diff --git a/libs/wraptor/__init__.py b/libs/wraptor/__init__.py deleted file mode 100644 index a1f838168..000000000 --- a/libs/wraptor/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -""" Wraptor - -Provides a set of useful decorators and other wrap-like python utility functions - -""" - -__version__ = "0.6.0" diff --git a/libs/wraptor/context/__init__.py b/libs/wraptor/context/__init__.py deleted file mode 100644 index 1f7c627de..000000000 --- a/libs/wraptor/context/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from wraptor.context.maybe import maybe -from wraptor.context.throttle import throttle -from wraptor.context.timer import timer - -__all__ = ['maybe', 'throttle', 'timer'] diff --git a/libs/wraptor/context/maybe.py b/libs/wraptor/context/maybe.py deleted file mode 100644 index 599c65363..000000000 --- a/libs/wraptor/context/maybe.py +++ /dev/null @@ -1,27 +0,0 @@ -import sys -import inspect - -class _SkippedBlock(Exception): - pass - -class maybe(object): - def __init__(self, predicate): - self.predicate = predicate - - def __empty_fn(self, *args, **kwargs): - return None - - def __enter__(self): - if not self.predicate(): - sys.settrace(self.__empty_fn) - frame = inspect.currentframe(1) - frame.f_trace = self.__trace - - def __trace(self, *args, **kwargs): - raise _SkippedBlock() - - def __exit__(self, type, value, traceback): - if isinstance(value, _SkippedBlock): - sys.settrace(None) - return True - return False diff --git a/libs/wraptor/context/test/__init__.py b/libs/wraptor/context/test/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/wraptor/context/test/test_maybe.py b/libs/wraptor/context/test/test_maybe.py deleted file mode 100644 index cdbf356ed..000000000 --- a/libs/wraptor/context/test/test_maybe.py +++ /dev/null @@ -1,26 +0,0 @@ -from threading import Thread - -from wraptor.context import maybe - -def test_basic(): - with maybe(lambda: False): - assert False - - check = False - with maybe(lambda: True): - check = True - assert check - -def test_threads(): - def worker(arr, index): - for i in range(5): - with maybe(lambda: i == 3): - arr[index] = True - - workers = 100 - arr = [False for i in range(workers)] - threads = [Thread(target=worker, args=(arr, i)) for i in range(workers)] - [t.start() for t in threads] - [t.join() for t in threads] - - assert all(arr) diff --git a/libs/wraptor/context/test/test_throttle.py b/libs/wraptor/context/test/test_throttle.py deleted file mode 100644 index 3484e97b5..000000000 --- a/libs/wraptor/context/test/test_throttle.py +++ /dev/null @@ -1,17 +0,0 @@ -import time - -from wraptor.context import throttle - -def test_basic(): - arr = [] - t = throttle(.1) - - with t: - arr.append(1) - with t: - arr.append(1) - time.sleep(.2) - with t: - arr.append(1) - - assert arr == [1, 1] diff --git a/libs/wraptor/context/test/test_timer.py b/libs/wraptor/context/test/test_timer.py deleted file mode 100644 index 6f89cb455..000000000 --- a/libs/wraptor/context/test/test_timer.py +++ /dev/null @@ -1,15 +0,0 @@ -from wraptor.context import timer -import time - -def test_basic(): - with timer() as t: - time.sleep(0.1000000) # sleep 100 ms - - assert t.interval >= 100 - -def test_params(): - with timer('test') as t: - pass - - assert t.name == 'test' - assert str(t).startswith('test') diff --git a/libs/wraptor/context/throttle.py b/libs/wraptor/context/throttle.py deleted file mode 100644 index 0c444c8c5..000000000 --- a/libs/wraptor/context/throttle.py +++ /dev/null @@ -1,16 +0,0 @@ -import time -from wraptor.context import maybe - -class throttle(maybe): - def __init__(self, seconds=1): - self.seconds = seconds - self.last_run = 0 - - def predicate(): - now = time.time() - if now > self.last_run + self.seconds: - self.last_run = now - return True - return False - - maybe.__init__(self, predicate) diff --git a/libs/wraptor/context/timer.py b/libs/wraptor/context/timer.py deleted file mode 100644 index 13bd6b934..000000000 --- a/libs/wraptor/context/timer.py +++ /dev/null @@ -1,18 +0,0 @@ -import time - -class timer(object): - __slots__ = ('name', 'interval', 'start', 'end') - - def __init__(self, name=None): - self.name = name - - def __enter__(self): - self.start = time.time() * 1e3 - return self - - def __exit__(self, *args): - self.end = time.time() * 1e3 - self.interval = self.end - self.start - - def __str__(self): - return "%s took %.03f ms" % (self.name, self.interval) diff --git a/libs/wraptor/decorators/__init__.py b/libs/wraptor/decorators/__init__.py deleted file mode 100644 index 201245842..000000000 --- a/libs/wraptor/decorators/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from wraptor.decorators.memoize import memoize -from wraptor.decorators.throttle import throttle -from wraptor.decorators.timeout import timeout, TimeoutException -from wraptor.decorators.exception_catcher import exception_catcher - -__all__ = ['memoize', 'throttle', 'timeout', 'TimeoutException', 'exception_catcher'] diff --git a/libs/wraptor/decorators/exception_catcher.py b/libs/wraptor/decorators/exception_catcher.py deleted file mode 100644 index 71653e685..000000000 --- a/libs/wraptor/decorators/exception_catcher.py +++ /dev/null @@ -1,29 +0,0 @@ -from functools import wraps -import sys -import Queue - -def exception_catcher(fn): - """ Catch exceptions raised by the decorated function. - Call check() to raise any caught exceptions. - """ - exceptions = Queue.Queue() - - @wraps(fn) - def wrapped(*args, **kwargs): - try: - ret = fn(*args, **kwargs) - except Exception: - exceptions.put(sys.exc_info()) - raise - return ret - - def check(): - try: - item = exceptions.get(block=False) - klass, value, tb = item - raise klass, value, tb - except Queue.Empty: - pass - - setattr(wrapped, 'check', check) - return wrapped diff --git a/libs/wraptor/decorators/memoize.py b/libs/wraptor/decorators/memoize.py deleted file mode 100644 index ffd49916c..000000000 --- a/libs/wraptor/decorators/memoize.py +++ /dev/null @@ -1,70 +0,0 @@ -from functools import wraps -import time -from hashlib import md5 -import threading - -class memoize(object): - """ Memoize the results of a function. Supports an optional timeout - for automatic cache expiration. - - If the optional manual_flush argument is True, a function called - "flush_cache" will be added to the wrapped function. When - called, it will remove all the timed out values from the cache. - - If you use this decorator as a class method, you must specify - instance_method=True otherwise you will have a single shared - cache for every instance of your class. - - This decorator is thread safe. - """ - def __init__(self, timeout=None, manual_flush=False, instance_method=False): - self.timeout = timeout - self.manual_flush = manual_flush - self.instance_method = instance_method - self.cache = {} - self.cache_lock = threading.RLock() - - def __call__(self, fn): - if self.instance_method: - @wraps(fn) - def rewrite_instance_method(instance, *args, **kwargs): - # the first time we are called we overwrite the method - # on the class instance with a new memoize instance - if hasattr(instance, fn.__name__): - bound_fn = fn.__get__(instance, instance.__class__) - new_memoizer = memoize(self.timeout, self.manual_flush)(bound_fn) - setattr(instance, fn.__name__, new_memoizer) - return getattr(instance, fn.__name__)(*args, **kwargs) - - return rewrite_instance_method - - def flush_cache(): - with self.cache_lock: - for key in self.cache.keys(): - if (time.time() - self.cache[key][1]) > self.timeout: - del(self.cache[key]) - - @wraps(fn) - def wrapped(*args, **kwargs): - kw = kwargs.items() - kw.sort() - key_str = repr((args, kw)) - key = md5(key_str).hexdigest() - - with self.cache_lock: - try: - result, cache_time = self.cache[key] - if self.timeout is not None and (time.time() - cache_time) > self.timeout: - raise KeyError - except KeyError: - result, _ = self.cache[key] = (fn(*args, **kwargs), time.time()) - - if not self.manual_flush and self.timeout is not None: - flush_cache() - - return result - - if self.manual_flush: - wrapped.flush_cache = flush_cache - - return wrapped diff --git a/libs/wraptor/decorators/test/__init__.py b/libs/wraptor/decorators/test/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/wraptor/decorators/test/test_called_with_args.py b/libs/wraptor/decorators/test/test_called_with_args.py deleted file mode 100644 index 306901686..000000000 --- a/libs/wraptor/decorators/test/test_called_with_args.py +++ /dev/null @@ -1,18 +0,0 @@ -from wraptor.decorators import timeout, throttle, memoize -import pytest - -with_decorators = pytest.mark.parametrize("decorator", [ - timeout, throttle, memoize -]) - -@with_decorators -def test_called_with_args(decorator): - test_args = [1, 2, [1, 2, 3], { 'asdf': 5 }] - test_kwargs = { 'a': 1, 'b': [1, 2, 3] } - - @decorator() - def fn(*args, **kwargs): - assert tuple(test_args) == args - assert test_kwargs == kwargs - - fn(*test_args, **test_kwargs) diff --git a/libs/wraptor/decorators/test/test_exception_catcher.py b/libs/wraptor/decorators/test/test_exception_catcher.py deleted file mode 100644 index 2944fb7e7..000000000 --- a/libs/wraptor/decorators/test/test_exception_catcher.py +++ /dev/null @@ -1,16 +0,0 @@ -from wraptor.decorators import exception_catcher -import threading -import pytest - -def test_basic(): - - @exception_catcher - def work(): - raise Exception() - - t = threading.Thread(target=work) - t.start() - t.join() - - with pytest.raises(Exception): - work.check() diff --git a/libs/wraptor/decorators/test/test_memoize.py b/libs/wraptor/decorators/test/test_memoize.py deleted file mode 100644 index d7c7e5870..000000000 --- a/libs/wraptor/decorators/test/test_memoize.py +++ /dev/null @@ -1,147 +0,0 @@ -import time - -from wraptor.decorators import memoize - -def test_basic_noargs(): - arr = [] - - @memoize() - def fn(): - arr.append(1) - - fn() - fn() - - assert arr == [1] - -def test_basic_args(): - arr = [] - - @memoize() - def fn(*args, **kwargs): - arr.append(1) - - s_args = [1, 2, 3] - fn(*s_args) - fn(*s_args) - c_args = [[1], "asdjf", {'a': 5}] - fn(*c_args) - fn(*c_args) - kw_args = {'a': 234, 'b': [1, 2, "asdf"], 'c': [5, 6]} - kw_args_2 = {'a': 234, 'b': [1, 3, "asdf"], 'c': [5, 6]} - fn(*c_args, **kw_args) - fn(*c_args, **kw_args_2) - fn(*c_args, **kw_args) - - fn(fn) - fn(fn) - - assert arr == [1, 1, 1, 1, 1] - -def test_timeout(): - arr = [] - - @memoize(timeout=.1) - def fn(*args, **kwargs): - arr.append(1) - - fn(1, 2, 3) - time.sleep(.2) - fn(1, 2, 3) - - assert arr == [1, 1] - -def test_auto_flush(): - memoize_inst = memoize(timeout=.1) - - @memoize_inst - def fn(*args, **kwargs): - pass - - fn(1, 2, 3) - assert len(memoize_inst.cache.keys()) == 1 - time.sleep(.2) - fn(1, 2, 3) - assert len(memoize_inst.cache.keys()) == 1 - -def test_manual_flush(): - memoize_inst = memoize(timeout=.1, manual_flush=True) - - @memoize_inst - def fn(*args, **kwargs): - pass - - fn(1, 2, 3) - assert len(memoize_inst.cache.keys()) == 1 - time.sleep(.2) - fn(3, 4, 5) - assert len(memoize_inst.cache.keys()) == 2 - time.sleep(.2) - fn.flush_cache() - assert len(memoize_inst.cache.keys()) == 0 - -def test_class_method(): - import random - - memoizer = memoize(manual_flush=True, instance_method=True) - - class foo(object): - @memoizer - def bar(self, *args): - return random.random() - - x = foo() - x2 = foo() - - assert x.bar('a', 'b') != x2.bar('a', 'b') - assert x.bar('a', 'b') == x.bar('a', 'b') - assert x.bar('a', 'b') != x.bar('a', 'd') - assert x2.bar('a', 'b') == x2.bar('a', 'b') - - # the memoizer should have made private caches for each instance - assert len(memoizer.cache) == 0 - - # now make sure that they don't share caches - res1 = x.bar('a', 'b') - res2 = x2.bar('a', 'b') - x.bar.flush_cache() - assert res1 != x.bar('a', 'b') - assert res2 == x2.bar('a', 'b') - -def test_instance_method_extended(): - - class foo(object): - def __init__(self): - self.i = 0 - - @memoize(instance_method=True) - def bar(self, instance): - assert self == instance - self.i += 1 - return self.i - - f = foo() - assert f.bar(f) == 1 - assert f.bar(f) == 1 - -def test_fail_instance_method(): - """ Test that memoize without instance_method creates a globally - shared memoize instance (shared by all instances of the class) - """ - memoizer = memoize(manual_flush=True) - - class foo(object): - def __init__(self, x): - self._x = x - - @memoizer - def bar(self): - return self._x - - x = foo(1) - x2 = foo(2) - - assert x.bar() != x2.bar() - - # note that they share the same cache - assert len(memoizer.cache) == 2 diff --git a/libs/wraptor/decorators/test/test_throttle.py b/libs/wraptor/decorators/test/test_throttle.py deleted file mode 100644 index 9b04bc80c..000000000 --- a/libs/wraptor/decorators/test/test_throttle.py +++ /dev/null @@ -1,51 +0,0 @@ -import time - -from wraptor.decorators import throttle - -def test_basic(): - arr = [] - - @throttle(.1) - def test(): - arr.append(1) - - test() - test() - time.sleep(.2) - test() - - assert arr == [1, 1] - -def test_fail_instance_method(): - """ Test that throttle without instance_method creates a globally - shared throttle instance (shared by all instances of the class) - """ - arr = [] - - class foo(object): - @throttle(1) - def bar(self): - arr.append(1) - - x = foo() - x2 = foo() - - x.bar() - x2.bar() - # throttle - assert arr == [1] - -def test_class_method(): - arr = [] - - class foo(object): - @throttle(1, instance_method=True) - def bar(self): - arr.append(1) - - x = foo() - x2 = foo() - - x.bar() - x2.bar() - assert arr == [1, 1] diff --git a/libs/wraptor/decorators/test/test_timeout.py b/libs/wraptor/decorators/test/test_timeout.py deleted file mode 100644 index f7758c53f..000000000 --- a/libs/wraptor/decorators/test/test_timeout.py +++ /dev/null @@ -1,31 +0,0 @@ -import time - -from wraptor.decorators import timeout, TimeoutException - -def test_basic(): - @timeout(1) - def fn(): - try: - time.sleep(2) - assert False - except TimeoutException: - pass - fn() - -def test_catch_exception_outsize(): - @timeout(1) - def fn(): - time.sleep(2) - assert False - - try: - fn() - except TimeoutException: - pass - -def test_cancels_signal(): - @timeout(1) - def fn(): - pass - fn() - time.sleep(1) diff --git a/libs/wraptor/decorators/throttle.py b/libs/wraptor/decorators/throttle.py deleted file mode 100644 index 3a7c5eb07..000000000 --- a/libs/wraptor/decorators/throttle.py +++ /dev/null @@ -1,31 +0,0 @@ -from functools import wraps -from wraptor import context - -class throttle(object): - """ Throttle a function to execute at most 1 time per seconds - The function is executed on the forward edge. - """ - def __init__(self, seconds=1, instance_method=False): - self.throttler = context.throttle(seconds=seconds) - self.seconds = seconds - self.instance_method = instance_method - - def __call__(self, fn): - if self.instance_method: - @wraps(fn) - def rewrite_instance_method(instance, *args, **kwargs): - # the first time we are called we overwrite the method - # on the class instance with a new memoize instance - if hasattr(instance, fn.__name__): - bound_fn = fn.__get__(instance, instance.__class__) - new_throttler = throttle(self.seconds)(bound_fn) - setattr(instance, fn.__name__, new_throttler) - return getattr(instance, fn.__name__)(*args, **kwargs) - - return rewrite_instance_method - - @wraps(fn) - def wrapped(*args, **kwargs): - with self.throttler: - return fn(*args, **kwargs) - return wrapped diff --git a/libs/wraptor/decorators/timeout.py b/libs/wraptor/decorators/timeout.py deleted file mode 100644 index 7843823bf..000000000 --- a/libs/wraptor/decorators/timeout.py +++ /dev/null @@ -1,31 +0,0 @@ -from functools import wraps -import signal - -class TimeoutException(Exception): - pass - -class timeout(object): - """ Basic timeout decorator - * Uses signals, so this can only be used in the main thread of execution - * seconds must be a positive integer - Signal implementation based on http://code.activestate.com/recipes/307871-timing-out-function/ - """ - def __init__(self, seconds=1): - self.seconds = seconds - - def __call__(self, fn): - def sig_handler(signum, frame): - raise TimeoutException() - - @wraps(fn) - def wrapped(*args, **kwargs): - old = signal.signal(signal.SIGALRM, sig_handler) - signal.alarm(self.seconds) - try: - result = fn(*args, **kwargs) - finally: - signal.signal(signal.SIGALRM, old) - signal.alarm(0) - return result - - return wrapped diff --git a/libs/wraptor/test/__init__.py b/libs/wraptor/test/__init__.py deleted file mode 100644 index e69de29bb..000000000