Axel python 2.5 fix
This commit is contained in:
@@ -8,6 +8,6 @@
|
|||||||
import inspect
|
import inspect
|
||||||
from .axel import *
|
from .axel import *
|
||||||
__all__ = sorted(name for name, obj in locals().items()
|
__all__ = sorted(name for name, obj in locals().items()
|
||||||
if not (name.startswith('_') or inspect.ismodule(obj)))
|
if not (name.startswith('_') or inspect.ismodule(obj)))
|
||||||
__all__.append('axel')
|
__all__.append('axel')
|
||||||
del inspect
|
del inspec
|
||||||
@@ -52,8 +52,8 @@ class Event(object):
|
|||||||
>> None
|
>> None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, sender=None, asynch=False, exc_info=False,
|
def __init__(self, sender = None, asynch = False, exc_info = False,
|
||||||
lock=None, threads=3, traceback=False):
|
lock = None, threads = 3, traceback = False):
|
||||||
""" Creates an event
|
""" Creates an event
|
||||||
|
|
||||||
asynch
|
asynch
|
||||||
@@ -90,13 +90,13 @@ class Event(object):
|
|||||||
(False, error_info, handler), # on error
|
(False, error_info, handler), # on error
|
||||||
(None, None, handler), ... # asynchronous execution
|
(None, None, handler), ... # asynchronous execution
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
self.asynchronous = asynch
|
self.asynchronous = asynch
|
||||||
self.exc_info = exc_info
|
self.exc_info = exc_info
|
||||||
self.lock = lock
|
self.lock = lock
|
||||||
self.sender = sender
|
self.sender = sender
|
||||||
self.threads = threads
|
self.threads = threads
|
||||||
self.traceback = traceback
|
self.traceback = traceback
|
||||||
self.handlers = {}
|
self.handlers = {}
|
||||||
self.memoize = {}
|
self.memoize = {}
|
||||||
|
|
||||||
@@ -116,13 +116,13 @@ class Event(object):
|
|||||||
event += handler
|
event += handler
|
||||||
event += (handler, True, 1.5)
|
event += (handler, True, 1.5)
|
||||||
event += {'handler':handler, 'memoize':True, 'timeout':1.5}
|
event += {'handler':handler, 'memoize':True, 'timeout':1.5}
|
||||||
"""
|
"""
|
||||||
handler_, memoize, timeout = self._extract(handler)
|
handler_, memoize, timeout = self._extract(handler)
|
||||||
self.handlers[hash(handler_)] = (handler_, memoize, timeout)
|
self.handlers[hash(handler_)] = (handler_, memoize, timeout)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def unhandle(self, handler):
|
def unhandle(self, handler):
|
||||||
""" Unregisters a handler """
|
""" Unregisters a handler """
|
||||||
handler_, memoize, timeout = self._extract(handler)
|
handler_, memoize, timeout = self._extract(handler)
|
||||||
key = hash(handler_)
|
key = hash(handler_)
|
||||||
if not key in self.handlers:
|
if not key in self.handlers:
|
||||||
@@ -131,26 +131,26 @@ class Event(object):
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
def fire(self, *args, **kwargs):
|
def fire(self, *args, **kwargs):
|
||||||
""" Stores all registered handlers in a queue for processing """
|
""" Stores all registered handlers in a queue for processing """
|
||||||
self.queue = Queue.Queue()
|
self.queue = Queue.Queue()
|
||||||
self.result = []
|
self.result = []
|
||||||
|
|
||||||
if self.handlers:
|
if self.handlers:
|
||||||
max_threads = self._threads()
|
max_threads = self._threads()
|
||||||
|
|
||||||
for i in range(max_threads):
|
for i in range(max_threads):
|
||||||
t = threading.Thread(target=self._execute,
|
t = threading.Thread(target = self._execute,
|
||||||
args=args, kwargs=kwargs)
|
args = args, kwargs = kwargs)
|
||||||
t.daemon = True
|
t.daemon = True
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
for handler in self.handlers:
|
for handler in self.handlers:
|
||||||
self.queue.put(handler)
|
self.queue.put(handler)
|
||||||
|
|
||||||
if self.asynchronous:
|
if self.asynchronous:
|
||||||
handler_, memoize, timeout = self.handlers[handler]
|
handler_, memoize, timeout = self.handlers[handler]
|
||||||
self.result.append((None, None, handler_))
|
self.result.append((None, None, handler_))
|
||||||
|
|
||||||
if not self.asynchronous:
|
if not self.asynchronous:
|
||||||
self.queue.join()
|
self.queue.join()
|
||||||
|
|
||||||
@@ -159,40 +159,43 @@ class Event(object):
|
|||||||
def count(self):
|
def count(self):
|
||||||
""" Returns the count of registered handlers """
|
""" Returns the count of registered handlers """
|
||||||
return len(self.handlers)
|
return len(self.handlers)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
""" Discards all registered handlers and cached results """
|
""" Discards all registered handlers and cached results """
|
||||||
self.handlers.clear()
|
self.handlers.clear()
|
||||||
self.memoize.clear()
|
self.memoize.clear()
|
||||||
|
|
||||||
def _execute(self, *args, **kwargs):
|
def _execute(self, *args, **kwargs):
|
||||||
""" Executes all handlers stored in the queue """
|
""" Executes all handlers stored in the queue """
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
handler, memoize, timeout = self.handlers[self.queue.get()]
|
handler, memoize, timeout = self.handlers[self.queue.get()]
|
||||||
|
|
||||||
if isinstance(self.lock, threading._RLock):
|
if isinstance(self.lock, threading._RLock):
|
||||||
self.lock.acquire() #synchronization
|
self.lock.acquire() #synchronization
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = self._memoize(memoize, timeout, handler, *args, **kwargs)
|
r = self._memoize(memoize, timeout, handler, *args, **kwargs)
|
||||||
if not self.asynchronous:
|
if not self.asynchronous:
|
||||||
self.result.append(tuple(r))
|
self.result.append(tuple(r))
|
||||||
|
|
||||||
except Exception as err:
|
except Exception:
|
||||||
if not self.asynchronous:
|
if not self.asynchronous:
|
||||||
self.result.append((False, self._error(sys.exc_info()),
|
self.result.append((False, self._error(sys.exc_info()),
|
||||||
handler))
|
handler))
|
||||||
finally:
|
finally:
|
||||||
if isinstance(self.lock, threading._RLock):
|
if isinstance(self.lock, threading._RLock):
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
|
||||||
if not self.asynchronous:
|
if not self.asynchronous:
|
||||||
self.queue.task_done()
|
self.queue.task_done()
|
||||||
|
|
||||||
|
if self.queue.empty():
|
||||||
|
raise Queue.Empty
|
||||||
|
|
||||||
except Queue.Empty:
|
except Queue.Empty:
|
||||||
break
|
break
|
||||||
|
|
||||||
def _extract(self, queue_item):
|
def _extract(self, queue_item):
|
||||||
""" Extracts a handler and handler's arguments that can be provided
|
""" Extracts a handler and handler's arguments that can be provided
|
||||||
as list or dictionary. If arguments are provided as list, they are
|
as list or dictionary. If arguments are provided as list, they are
|
||||||
@@ -201,27 +204,27 @@ class Event(object):
|
|||||||
event += handler
|
event += handler
|
||||||
event += (handler, True, 1.5)
|
event += (handler, True, 1.5)
|
||||||
event += {'handler':handler, 'memoize':True, 'timeout':1.5}
|
event += {'handler':handler, 'memoize':True, 'timeout':1.5}
|
||||||
"""
|
"""
|
||||||
assert queue_item, 'Invalid list of arguments'
|
assert queue_item, 'Invalid list of arguments'
|
||||||
handler = None
|
handler = None
|
||||||
memoize = False
|
memoize = False
|
||||||
timeout = 0
|
timeout = 0
|
||||||
|
|
||||||
if not isinstance(queue_item, (list, tuple, dict)):
|
if not isinstance(queue_item, (list, tuple, dict)):
|
||||||
handler = queue_item
|
handler = queue_item
|
||||||
elif isinstance(queue_item, (list, tuple)):
|
elif isinstance(queue_item, (list, tuple)):
|
||||||
if len(queue_item) == 3:
|
if len(queue_item) == 3:
|
||||||
handler, memoize, timeout = queue_item
|
handler, memoize, timeout = queue_item
|
||||||
elif len(queue_item) == 2:
|
elif len(queue_item) == 2:
|
||||||
handler, memoize, = queue_item
|
handler, memoize, = queue_item
|
||||||
elif len(queue_item) == 1:
|
elif len(queue_item) == 1:
|
||||||
handler = queue_item
|
handler = queue_item
|
||||||
elif isinstance(queue_item, dict):
|
elif isinstance(queue_item, dict):
|
||||||
handler = queue_item.get('handler')
|
handler = queue_item.get('handler')
|
||||||
memoize = queue_item.get('memoize', False)
|
memoize = queue_item.get('memoize', False)
|
||||||
timeout = queue_item.get('timeout', 0)
|
timeout = queue_item.get('timeout', 0)
|
||||||
return (handler, bool(memoize), float(timeout))
|
return (handler, bool(memoize), float(timeout))
|
||||||
|
|
||||||
def _memoize(self, memoize, timeout, handler, *args, **kwargs):
|
def _memoize(self, memoize, timeout, handler, *args, **kwargs):
|
||||||
""" Caches the execution result of successful executions
|
""" Caches the execution result of successful executions
|
||||||
hash = hash(handler)
|
hash = hash(handler)
|
||||||
@@ -229,35 +232,35 @@ class Event(object):
|
|||||||
hash : ((args, kwargs, result), (args, kwargs, result), ...),
|
hash : ((args, kwargs, result), (args, kwargs, result), ...),
|
||||||
hash : ((args, kwargs, result), ...), ...
|
hash : ((args, kwargs, result), ...), ...
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
if not isinstance(handler, Event) and self.sender is not None:
|
if not isinstance(handler, Event) and self.sender is not None:
|
||||||
args = list(args)[:]
|
args = list(args)[:]
|
||||||
args.insert(0, self.sender)
|
args.insert(0, self.sender)
|
||||||
|
|
||||||
if not memoize:
|
if not memoize:
|
||||||
if timeout <= 0: #no time restriction
|
if timeout <= 0: #no time restriction
|
||||||
return [True, handler(*args, **kwargs), handler]
|
return [True, handler(*args, **kwargs), handler]
|
||||||
|
|
||||||
result = self._timeout(timeout, handler, *args, **kwargs)
|
result = self._timeout(timeout, handler, *args, **kwargs)
|
||||||
if isinstance(result, tuple) and len(result) == 3:
|
if isinstance(result, tuple) and len(result) == 3:
|
||||||
if isinstance(result[1], Exception): #error occurred
|
if isinstance(result[1], Exception): #error occurred
|
||||||
return [False, self._error(result), handler]
|
return [False, self._error(result), handler]
|
||||||
return [True, result, handler]
|
return [True, result, handler]
|
||||||
else:
|
else:
|
||||||
hash_ = hash(handler)
|
hash_ = hash(handler)
|
||||||
if hash_ in self.memoize:
|
if hash_ in self.memoize:
|
||||||
for args_, kwargs_, result in self.memoize[hash_]:
|
for args_, kwargs_, result in self.memoize[hash_]:
|
||||||
if args_ == args and kwargs_ == kwargs:
|
if args_ == args and kwargs_ == kwargs:
|
||||||
return [True, result, handler]
|
return [True, result, handler]
|
||||||
|
|
||||||
if timeout <= 0: #no time restriction
|
if timeout <= 0: #no time restriction
|
||||||
result = handler(*args, **kwargs)
|
result = handler(*args, **kwargs)
|
||||||
else:
|
else:
|
||||||
result = self._timeout(timeout, handler, *args, **kwargs)
|
result = self._timeout(timeout, handler, *args, **kwargs)
|
||||||
if isinstance(result, tuple) and len(result) == 3:
|
if isinstance(result, tuple) and len(result) == 3:
|
||||||
if isinstance(result[1], Exception): #error occurred
|
if isinstance(result[1], Exception): #error occurred
|
||||||
return [False, self._error(result), handler]
|
return [False, self._error(result), handler]
|
||||||
|
|
||||||
lock = threading.RLock()
|
lock = threading.RLock()
|
||||||
lock.acquire()
|
lock.acquire()
|
||||||
try:
|
try:
|
||||||
@@ -268,32 +271,33 @@ class Event(object):
|
|||||||
finally:
|
finally:
|
||||||
lock.release()
|
lock.release()
|
||||||
|
|
||||||
|
|
||||||
def _timeout(self, timeout, handler, *args, **kwargs):
|
def _timeout(self, timeout, handler, *args, **kwargs):
|
||||||
""" Controls the time allocated for the execution of a method """
|
""" Controls the time allocated for the execution of a method """
|
||||||
t = spawn_thread(target=handler, args=args, kwargs=kwargs)
|
t = spawn_thread(target = handler, args = args, kwargs = kwargs)
|
||||||
t.daemon = True
|
t.daemon = True
|
||||||
t.start()
|
t.start()
|
||||||
t.join(timeout)
|
t.join(timeout)
|
||||||
|
|
||||||
if not t.is_alive():
|
if not t.is_alive():
|
||||||
if t.exc_info:
|
if t.exc_info:
|
||||||
return t.exc_info
|
return t.exc_info
|
||||||
return t.result
|
return t.result
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
msg = '[%s] Execution was forcefully terminated'
|
msg = '[%s] Execution was forcefully terminated'
|
||||||
raise RuntimeError(msg % t.name)
|
raise RuntimeError(msg % t.name)
|
||||||
except:
|
except:
|
||||||
return sys.exc_info()
|
return sys.exc_info()
|
||||||
|
|
||||||
def _threads(self):
|
def _threads(self):
|
||||||
""" Calculates maximum number of threads that will be started """
|
""" Calculates maximum number of threads that will be started """
|
||||||
if self.threads < len(self.handlers):
|
if self.threads < len(self.handlers):
|
||||||
return self.threads
|
return self.threads
|
||||||
return len(self.handlers)
|
return len(self.handlers)
|
||||||
|
|
||||||
def _error(self, exc_info):
|
def _error(self, exc_info):
|
||||||
""" Retrieves the error info """
|
""" Retrieves the error info """
|
||||||
if self.exc_info:
|
if self.exc_info:
|
||||||
if self.traceback:
|
if self.traceback:
|
||||||
return exc_info
|
return exc_info
|
||||||
@@ -303,23 +307,23 @@ class Event(object):
|
|||||||
__iadd__ = handle
|
__iadd__ = handle
|
||||||
__isub__ = unhandle
|
__isub__ = unhandle
|
||||||
__call__ = fire
|
__call__ = fire
|
||||||
__len__ = count
|
__len__ = count
|
||||||
|
|
||||||
class spawn_thread(threading.Thread):
|
class spawn_thread(threading.Thread):
|
||||||
""" Spawns a new thread and returns the execution result """
|
""" Spawns a new thread and returns the execution result """
|
||||||
|
|
||||||
def __init__(self, target, args=(), kwargs={}, default=None):
|
def __init__(self, target, args = (), kwargs = {}, default = None):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self._target = target
|
self._target = target
|
||||||
self._args = args
|
self._args = args
|
||||||
self._kwargs = kwargs
|
self._kwargs = kwargs
|
||||||
self.result = default
|
self.result = default
|
||||||
self.exc_info = None
|
self.exc_info = None
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
try:
|
try:
|
||||||
self.result = self._target(*self._args, **self._kwargs)
|
self.result = self._target(*self._args, **self._kwargs)
|
||||||
except:
|
except:
|
||||||
self.exc_info = sys.exc_info()
|
self.exc_info = sys.exc_info()
|
||||||
finally:
|
finally:
|
||||||
del self._target, self._args, self._kwargs
|
del self._target, self._args, self._kwargs
|
||||||
Reference in New Issue
Block a user