optimize-later/optimize_later/config.py

72 lines
1.8 KiB
Python
Raw Normal View History

2017-08-13 18:12:00 -04:00
import logging
from functools import wraps
2017-08-13 19:11:40 -04:00
from optimize_later.utils import NoArgDecoratorMeta, with_metaclass
2017-08-13 18:12:00 -04:00
try:
import threading
except ImportError:
import dummy_threading as threading
log = logging.getLogger(__name__.rpartition('.')[0] or __name__)
_global_callbacks = []
_local = threading.local()
def get_callbacks():
try:
return _local.callbacks
except AttributeError:
return _global_callbacks
2017-08-11 16:08:59 -04:00
def register_callback(callback):
2017-08-13 18:12:00 -04:00
get_callbacks().append(callback)
2017-08-11 16:08:59 -04:00
return callback
def deregister_callback(callback):
2017-08-13 18:12:00 -04:00
get_callbacks().remove(callback)
def global_callback(report):
for callback in get_callbacks():
try:
callback(report)
except Exception:
log.exception('Failed to invoke global callback: %r', callback)
2017-08-13 19:11:40 -04:00
class optimize_context(with_metaclass(NoArgDecoratorMeta)):
2017-08-13 20:21:17 -04:00
def __init__(self, callbacks=None, reset=False):
self.callbacks = callbacks or []
self.reset = reset
2017-08-13 18:12:00 -04:00
def __enter__(self):
try:
self.old_context = _local.callbacks
except AttributeError:
self.old_context = None
2017-08-13 20:21:17 -04:00
if self.reset:
base_context = []
elif self.old_context is None:
base_context = _global_callbacks
2017-08-13 18:12:00 -04:00
else:
2017-08-13 20:21:17 -04:00
base_context = self.old_context
_local.callbacks = base_context + self.callbacks
2017-08-13 18:12:00 -04:00
def __exit__(self, exc_type, exc_val, exc_tb):
if self.old_context is None:
del _local.callbacks
else:
_local.callbacks = self.old_context
def __call__(self, function):
@wraps(function)
def wrapper(*args, **kwargs):
with optimize_context(self.callbacks, reset=self.reset):
2017-08-13 18:12:00 -04:00
return function(*args, **kwargs)
return wrapper