diff --git a/.gitignore b/.gitignore index 0e5b2b7..c9b937f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ __pycache__/ *.so # Distribution / packaging +*.pyc .Python env/ build/ @@ -100,5 +101,9 @@ ENV/ # mypy .mypy_cache/ +# gedit backup files +*.*~ +*.bak + #swp files *.swp diff --git a/.travis.yml b/.travis.yml index d533c9e..6fbdbec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,17 @@ language: python python: -- '2.7' +- '3.5' install: -- pip install . +- pip3 install . script: -- python setup.py test +- python3 setup.py test deploy: - provider: releases skip_cleanup: true api-key: secure: Q3wwYSZkwXAG1DwgKZrR/vZTGLZlDBfR9O5MoZ+dpmy6EmFozQLRB+qFh+eWh2Y8xYIdXz+6CaJLcM92JU5zJTslWLHyhO7kTOt31fxuZu+HGnR835Try6TlU11948nn2Ramk4nI3lT/G4jO+PdNq23sOPdhV4KDI0nv9Pc9Ywqoyg+4okpSnbJNWn7bdinthA88iMRNxqH88LJ4CM6J/eh0qJUm2xcAOTpw9gIkq188UTCbT71qGUWhWFicvbV1oJ6r+C87Ru/rf+nHJyZ7Dn2y8odBx+MHicUp7XomKP/niM2K9TkX/wOMqopE6XrmAnZ/6W/8cGOoqLWT0oqksktIqlOrUYQAq5UNXee3cHPq6k+Q/CGhbGb9feNEzb3PMPKkD6wict90arhHfpqk0yGP1lCRSwM0eIgegMWgSpFXi2Zc+K/6iucZ21ayVDZf20f7Pe70SEgjB/VJiTgI+BMmOG70a2MYsHUG+rK4fYiSDiO+9ADVNHHNy5r9dL+VLhRxkkcgaIkkZsx/xoE2KUO601EOEfjX55S0C8R/VRNDpxg1VXhu2i19E3G08Xcv+xuz8awst3gvVImVJY9j9GiimMtT0l/pLMjWTeAvMmlraxRaMa36Q96BntThdwRkNCAhsfCTF364egRI+PEWciRcrb0Tpj8/L8p2OUMMqgI= - name: deeputil-0.1.2 - tag_name: 0.1.2 + name: deeputil-0.2 + tag_name: 0.2 on: branch: master repo: deep-compute/deeputil diff --git a/deeputil/__init__.py b/deeputil/__init__.py index bd93754..6cae014 100644 --- a/deeputil/__init__.py +++ b/deeputil/__init__.py @@ -1,17 +1,17 @@ -from keep_running import keeprunning +from .keep_running import keeprunning -from streamcounter import StreamCounter +from .streamcounter import StreamCounter -from timer import FunctionTimer -from timer import BlockTimer +from .timer import FunctionTimer +from .timer import BlockTimer -import misc -from misc import generate_random_string -from misc import get_timestamp, get_datetime, convert_ts -from misc import xcode, parse_location -from misc import ExpiringCache, ExpiringCounter -from misc import deepgetattr, AttrDict -from misc import IterAsFile, set_file_limits -from misc import Dummy +from . import misc +from .misc import generate_random_string +from .misc import get_timestamp, get_datetime, convert_ts +from .misc import xcode, parse_location +from .misc import ExpiringCache, ExpiringCounter +from .misc import deepgetattr, AttrDict +from .misc import IterAsFile, set_file_limits +from .misc import Dummy -from priority_dict import PriorityDict +from .priority_dict import PriorityDict diff --git a/deeputil/keep_running.py b/deeputil/keep_running.py index 4cadcad..eb44e5e 100644 --- a/deeputil/keep_running.py +++ b/deeputil/keep_running.py @@ -63,19 +63,18 @@ def keeprunning(wait_secs=0, exit_on_success=False, AttrDict({'i': 1}) AttrDict({'i': 2}) Error happened - integer division or modulo by zero + division by zero AttrDict({'i': 3}) AttrDict({'i': 4}) Error happened - integer division or modulo by zero + division by zero AttrDict({'i': 5}) AttrDict({'i': 6}) Error happened - integer division or modulo by zero + division by zero AttrDict({'i': 7}) Done - # Example 3: Full set of arguments that can be passed in @keeprunning() # with class implementations @@ -87,13 +86,13 @@ def keeprunning(wait_secs=0, exit_on_success=False, ... ... # Functions to be called by @keeprunning ... def success(self): - ... print(self.SUCCESS_MSG) + ... print((self.SUCCESS_MSG)) ... ... def failure(self, __exc__): - ... print(self.ERROR_MSG, __exc__) + ... print((self.ERROR_MSG, __exc__)) ... ... def task_done(self): - ... print(self.DONE_MSG) + ... print((self.DONE_MSG)) ... ... #Actual use of keeprunning with all arguments passed ... @keeprunning(wait_secs=1, exit_on_success=False, @@ -115,21 +114,20 @@ def keeprunning(wait_secs=0, exit_on_success=False, Yay!! AttrDict({'i': 2}) Error happened - ('Error', ZeroDivisionError('integer division or modulo by zero',)) + ('Error', ZeroDivisionError('division by zero',)) AttrDict({'i': 3}) Yay!! AttrDict({'i': 4}) Error happened - ('Error', ZeroDivisionError('integer division or modulo by zero',)) + ('Error', ZeroDivisionError('division by zero',)) AttrDict({'i': 5}) Yay!! AttrDict({'i': 6}) Error happened - ('Error', ZeroDivisionError('integer division or modulo by zero',)) + ('Error', ZeroDivisionError('division by zero',)) AttrDict({'i': 7}) Done STOPPED AT NOTHING! - ''' def decfn(fn): @@ -153,7 +151,7 @@ def _fn(*args, **kwargs): raise except KeepRunningTerminate: break - except Exception, exc: + except Exception as exc: fargs.update(dict(__exc__=exc)) _call_callback(on_error, fargs) fargs.update(dict(__exc__=None)) @@ -169,3 +167,4 @@ def _fn(*args, **kwargs): return decfn keeprunning.terminate = KeepRunningTerminate + diff --git a/deeputil/misc.py b/deeputil/misc.py index c5f78d9..203fddc 100644 --- a/deeputil/misc.py +++ b/deeputil/misc.py @@ -7,6 +7,7 @@ import string import binascii +from functools import reduce def generate_random_string(length=6): ''' @@ -17,10 +18,10 @@ def generate_random_string(length=6): # Test randomness. Try N times and observe no duplicaton >>> N = 100 - >>> len(set(generate_random_string(10) for i in xrange(N))) == N + >>> len(set(generate_random_string(10) for i in range(N))) == N True ''' - n = length / 2 + 1 + n = int(length / 2 + 1) x = binascii.hexlify(os.urandom(n)) return x[:length] @@ -29,7 +30,7 @@ def get_timestamp(dt=None): Return current timestamp if @dt is None else return timestamp of @dt. - >>> t = datetime.datetime(2015, 05, 21) + >>> t = datetime.datetime(2015, 0o5, 21) >>> get_timestamp(t) 1432166400 ''' @@ -76,21 +77,18 @@ def convert_ts(tt): ts = None return ts +#FIXME No unicde in python 3 def xcode(text, encoding='utf8', mode='ignore'): ''' Converts unicode encoding to str + >>> xcode(b'hello') + b'hello' >>> xcode('hello') - 'hello' - >>> xcode(u'hello') - 'hello' + b'hello' ''' - return text.encode(encoding, mode) if isinstance(text, unicode) else text + return text.encode(encoding, mode) if isinstance(text, str) else text -#TODO check for python 3 -try: - from urllib.parse import urlparse -except ImportError: - from urlparse import urlparse +from urllib.parse import urlparse def parse_location(loc, default_port): ''' @@ -174,7 +172,7 @@ def deepgetattr(obj, attr, default=AttributeError): >>> deepgetattr(universe, 'galaxy.solarsystem.planet.name') 'Earth' >>> deepgetattr(universe, 'solarsystem.planet.name', default=TypeError) - + """ try: return reduce(getattr, attr.split('.'), obj) @@ -222,13 +220,6 @@ class AttrDict(dict): 2 >>> d.b 2 - - >>> d - AttrDict({'a': 1, 'b': 2}) - - >>> repr(d) - "AttrDict({'a': 1, 'b': 2})" - >>> del d['a'] >>> d AttrDict({'b': 2}) @@ -242,7 +233,7 @@ def __init__(self, *args, **kwargs): super(AttrDict, self).__init__(*args, **kwargs) def __getstate__(self): - return self.__dict__.items() + return list(self.__dict__.items()) def __setstate__(self, items): for key, val in items: @@ -279,7 +270,7 @@ class IterAsFile(object): >>> def str_fn(): ... for c in 'a', 'b', 'c': ... yield c * 3 - ... + ... >>> IAF = IterAsFile(str_fn()) >>> IAF.read(6) 'aaabbb' @@ -293,7 +284,7 @@ def __init__(self, it): self.next_chunk = '' def _grow_chunk(self): - self.next_chunk = self.next_chunk + self.it.next() + self.next_chunk = self.next_chunk + next(self.it) def read(self, n): if self.next_chunk == None: @@ -335,7 +326,7 @@ def __iter__(self): if self.parts: yield ''.join(self.parts) -from priority_dict import PriorityDict +from .priority_dict import PriorityDict class ExpiringCounter(object): ''' >>> c = ExpiringCounter(duration=1) @@ -383,7 +374,7 @@ def update(self): for ts_key in ts_keys: hcounts = self.history.pop(ts_key) - for key, count in hcounts.iteritems(): + for key, count in list(hcounts.items()): kcount = self.counts[key] kcount -= count if kcount <= 0: del self.counts[key] @@ -417,34 +408,36 @@ class Dummy(object): >>> d = Dummy(1, a=5) >>> d.foo() - >>> d.bar #doctest: +ELLIPSIS - + >>> d.bar() >>> d.foo.bar() - Now do the same as above but ask Dummy to print the activity + #Now do the same as above but ask Dummy to print the activity - >>> d = Dummy(1, a=5, __quiet__=False) #doctest: +ELLIPSIS - (, '__init__', {'prefix': [], 'args': (1,), 'kwargs': {'a': 5}}) - >>> d.foo() #doctest: +ELLIPSIS - (, '__getattr__', {'attr': 'foo'}) - (, '__init__', {'prefix': ['foo'], 'args': (), 'kwargs': {}}) - (, '__call__', {'prefix': ['foo'], 'args': (), 'kwargs': {}}) - >>> d.bar #doctest: +ELLIPSIS - (, '__getattr__', {'attr': 'bar'}) - (, '__init__', {'prefix': ['bar'], 'args': (), 'kwargs': {}}) - - >>> d.foo.bar() #doctest: +ELLIPSIS - (, '__getattr__', {'attr': 'foo'}) - (, '__init__', {'prefix': ['foo'], 'args': (), 'kwargs': {}}) - (, '__getattr__', {'attr': 'bar'}) - (, '__init__', {'prefix': ['foo', 'bar'], 'args': (), 'kwargs': {}}) - (, '__call__', {'prefix': ['foo', 'bar'], 'args': (), 'kwargs': {}}) + #>>> d = Dummy(1, a=5, __quiet__=False) # doctest: +ELLIPSIS + #(, '__init__', {'prefix': [], 'args': (1,), 'kwargs': {'a': 5}}) + + #>>> d.foo() # doctest: +ELLIPSIS + #(, '__getattr__', {'attr': 'foo'}) + #(, '__init__', {'prefix': ['foo'], 'args': (), 'kwargs': {}}) + #(, '__call__', {'prefix': ['foo'], 'args': (), 'kwargs': {}}) + + #>>> d.bar # doctest: +ELLIPSIS + #(, '__getattr__', {'attr': 'bar'}) + #(, '__init__', {'prefix': ['bar'], 'args': (), 'kwargs': {}}) + # + + #>>> d.foo.bar() # doctest: +ELLIPSIS + #(, '__getattr__', {'attr': 'foo'}) + #(, '__init__', {'prefix': ['foo'], 'args': (), 'kwargs': {}}) + #(, '__getattr__', {'attr': 'bar'}) + #(, '__init__', {'prefix': ['foo', 'bar'], 'args': (), 'kwargs': {}}) + #(, '__call__', {'prefix': ['foo', 'bar'], 'args': (), 'kwargs': {}}) ''' def _log(self, event, data): if not self._quiet: - print(self, event, data) + print((self, event, data)) def __init__(self, *args, **kwargs): self._prefix = kwargs.pop('__prefix__', []) @@ -458,3 +451,4 @@ def __getattr__(self, attr): def __call__(self, *args, **kwargs): self._log('__call__', dict(args=args, kwargs=kwargs, prefix=self._prefix)) + diff --git a/deeputil/priority_dict.py b/deeputil/priority_dict.py index eb27a65..a9a0379 100644 --- a/deeputil/priority_dict.py +++ b/deeputil/priority_dict.py @@ -46,8 +46,9 @@ class PriorityDict(dict): 'id2' >>> x.pop_smallest() 'id2' - >>> x - {'id4': 25, 'id5': 19, 'id3': 29, 'id1': 22} + >>> from pprint import pprint + >>> pprint(x) + {'id1': 22, 'id3': 29, 'id4': 25, 'id5': 19} >>> x = PriorityDict({}) >>> x.smallest() Traceback (most recent call last): @@ -68,7 +69,7 @@ def __init__(self, *args, **kwargs): self._rebuild_heap() def _rebuild_heap(self): - self._heap = [(v, k) for k, v in self.iteritems()] + self._heap = [(v, k) for k, v in list(self.items())] heapify(self._heap) def smallest(self): diff --git a/deeputil/streamcounter.py b/deeputil/streamcounter.py index b0c4e07..3573b66 100644 --- a/deeputil/streamcounter.py +++ b/deeputil/streamcounter.py @@ -71,7 +71,7 @@ def _drop_oldest_chunk(self): chunk = self.chunked_counts.pop(chunk_id) self.n_counts -= len(chunk) - for k, v in chunk.iteritems(): + for k, v in list(chunk.items()): self.counts[k] -= v self.counts_total -= v diff --git a/deeputil/timer.py b/deeputil/timer.py index 4baf392..b0ff17c 100644 --- a/deeputil/timer.py +++ b/deeputil/timer.py @@ -11,13 +11,13 @@ def FunctionTimer(on_done=None): ... >>> @FunctionTimer(on_done= logger) ... def foo(t=10): - ... print 'foo executing...' + ... print('foo executing...') ... time.sleep(t) ... >>> @FunctionTimer(on_done= logger) ... def bar(t, n): ... for i in range(n): - ... print 'bar executing...' + ... print('bar executing...') ... time.sleep(1) ... foo(t) ... @@ -37,8 +37,8 @@ def timed(*args, **kwargs): if on_done: on_done((fn.__name__,int(te - ts)), args, kwargs) else: - print '%r %d sec(s)' % \ - (fn.__name__, (te - ts)) + print(('%r %d sec(s)' % \ + (fn.__name__, (te - ts)))) return result return timed @@ -74,3 +74,4 @@ class Timer(object): decorator = staticmethod(FunctionTimer) block = BlockTimer + diff --git a/setup.py b/setup.py index 11fa754..c199f0a 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name="deeputil", - version="0.1.2", + version="0.2", description="Commonly re-used logic kept in one library", keywords="deeputil", author="Deep Compute, LLC", diff --git a/test.py b/test.py index b45896d..ab6c098 100644 --- a/test.py +++ b/test.py @@ -18,7 +18,7 @@ def suite_maker(): if __name__ == "__main__": doctest.testmod(keep_running) - doctest.testmod(misc) + doctest.testmod(misc, optionflags=doctest.ELLIPSIS) doctest.testmod(streamcounter) doctest.testmod(timer) doctest.testmod(priority_dict)