home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 June / maximum-cd-2009-06.iso / DiscContents / digsby_setup.exe / lib / util / callbacks.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-02-26  |  9.3 KB  |  291 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. from introspect import funcinfo
  6. from primitives import Delegate
  7. from functools import wraps
  8. from logging import getLogger
  9. from traceback import print_exc
  10. import sys
  11. import threading
  12. log = getLogger('callbacks')
  13. CALLBACKS = ('success', 'error', 'timeout')
  14. call_later_lock = threading.Lock()
  15. call_laters = dict()
  16.  
  17. def register_call_later(threadname, call_later):
  18.     call_later_lock.__enter__()
  19.     
  20.     try:
  21.         call_laters[threadname] = call_later
  22.     finally:
  23.         pass
  24.  
  25.  
  26.  
  27. def unregister_call_later(threadname):
  28.     call_later_lock.__enter__()
  29.     
  30.     try:
  31.         call_laters.pop(threadname)
  32.     finally:
  33.         pass
  34.  
  35.  
  36.  
  37. DO_NOTHING = lambda *a, **k: pass
  38.  
  39. class CallLater(object):
  40.     
  41.     def __init__(self, cb, threadname = None):
  42.         if not threadname:
  43.             pass
  44.         self.threadname = threading.currentThread().getName()
  45.         if self.threadname not in call_laters:
  46.             
  47.             try:
  48.                 cb_dbg_str = ', '.join((lambda .0: for s in .0:
  49. str(s))([
  50.                     funcinfo(cb),
  51.                     cb.func_code.co_filename,
  52.                     cb.func_code.co_firstlineno]))
  53.             except Exception:
  54.                 cb_dbg_str = 'Error making debug string. Repr is: {%s}' % funcinfo(cb)
  55.  
  56.             if cb is not DO_NOTHING:
  57.                 pass
  58.             
  59.         
  60.         self.cb = cb
  61.  
  62.     
  63.     def __repr__(self):
  64.         return '<%s %s>' % (type(self).__name__, funcinfo(self.cb))
  65.  
  66.     
  67.     def __call__(self, *a, **k):
  68.         if threading.currentThread().getName() != self.threadname and self.threadname in call_laters:
  69.             
  70.             try:
  71.                 return (None, None, call_laters[self.threadname])((lambda : self.cb(*a, **k)))
  72.             except Exception:
  73.                 print >>sys.stderr, 'callback is %s' % funcinfo(self.cb)
  74.                 raise 
  75.             except:
  76.                 None<EXCEPTION MATCH>Exception
  77.             
  78.  
  79.         None<EXCEPTION MATCH>Exception
  80.         
  81.         try:
  82.             return self.cb(*a, **k)
  83.         except Exception:
  84.             print >>sys.stderr, '%s in %s (%s). args/kwargs are: %r,%r' % (getattr(self.cb, '__name__', funcinfo(self.cb)), self.cb.__module__, funcinfo(self.cb), a, k)
  85.             raise 
  86.  
  87.  
  88.  
  89.  
  90. class CallLaterDelegate(Delegate):
  91.     
  92.     def __init__(self, *a):
  93.         Delegate.__init__(self, (lambda .0: for x in .0:
  94. CallLater(x))(a))
  95.  
  96.     
  97.     def __iadd__(self, f):
  98.         if isinstance(f, list):
  99.             for thing in f:
  100.                 self += thing
  101.             
  102.         else:
  103.             self.append(CallLater(f))
  104.         return self
  105.  
  106.  
  107.  
  108. class Callback(object):
  109.     normal_callback_names = CALLBACKS
  110.     
  111.     def __init__(self, **cbs):
  112.         for name, callback in cbs.iteritems():
  113.             if not callable(callback):
  114.                 raise TypeError('keyword args to Callback must be callable: %s' % name)
  115.             
  116.             setattr(self, name, CallLaterDelegate(callback))
  117.             attr = getattr(self, name)
  118.         
  119.  
  120.     
  121.     def __getattr__(self, attr):
  122.         
  123.         try:
  124.             return object.__getattribute__(self, attr)
  125.         except AttributeError:
  126.             if attr in self.normal_callback_names:
  127.                 return CallLaterDelegate()
  128.             else:
  129.                 raise 
  130.         except:
  131.             attr in self.normal_callback_names
  132.  
  133.  
  134.     
  135.     def __setattr__(self, attr, val):
  136.         object.__setattr__(self, attr, val)
  137.  
  138.     
  139.     def __call__(self, *a, **k):
  140.         return self.success(*a, **k)
  141.  
  142.     
  143.     def __repr__(self):
  144.         return '<%s %s>' % (type(self).__name__, ' '.join((lambda .0: for item in .0:
  145. '%s=%s' % item)(self.__dict__.items())))
  146.  
  147.  
  148. EMPTY_CALLBACK = Callback()
  149. DefaultCallback = EMPTY_CALLBACK
  150. CALLBACK_ATTR = '_iscallback'
  151.  
  152. def callsback(func):
  153.     
  154.     def wrapper(*secret_a, **secret_kws):
  155.         cb = None
  156.         if 'callback' in secret_kws:
  157.             if (any,)((lambda .0: for cbname in .0:
  158. cbname in secret_kws)(CALLBACKS)):
  159.                 raise AssertionError('use callback or individual callbacks')
  160.             
  161.             cb = secret_kws['callback']
  162.         else:
  163.             for cbname in CALLBACKS:
  164.                 if cbname in secret_kws:
  165.                     if cb is None:
  166.                         cb = Callback()
  167.                     
  168.                     if not callable(secret_kws[cbname]):
  169.                         raise TypeError('%s must be callable' % cbname)
  170.                     
  171.                     mycb = CallLaterDelegate(secret_kws[cbname])
  172.                     setattr(cb, cbname, mycb)
  173.                     del secret_kws[cbname]
  174.                     continue
  175.             
  176.             secret_kws['callback'] = cb
  177.         if cb is None:
  178.             secret_kws['callback'] = cb = Callback()
  179.         
  180.         
  181.         try:
  182.             val = func(*secret_a, **secret_kws)
  183.         except Exception:
  184.             e = None
  185.             print_exc()
  186.             callany = callany
  187.             import util
  188.             if not callany(cb.error, e):
  189.                 raise 
  190.             
  191.             val = None
  192.  
  193.         if val is True:
  194.             cb.success()
  195.         
  196.         return val
  197.  
  198.     wrapper = (wraps(func),)(wrapper)
  199.     setattr(wrapper, CALLBACK_ATTR, True)
  200.     return wrapper
  201.  
  202.  
  203. def is_callsback(f):
  204.     return bool(getattr(f, CALLBACK_ATTR, False))
  205.  
  206.  
  207. def do_cb(seq, callback = None):
  208.     CallbackSequence(seq, callback = callback)()
  209.  
  210. do_cb = callsback(do_cb)
  211.  
  212. class CallbackSequence(object):
  213.     
  214.     def __init__(self, sequence, callback):
  215.         self.iter = iter(sequence)
  216.         self.callback = callback
  217.         self.n = 0
  218.  
  219.     
  220.     def __call__(self, *a):
  221.         self.n = self.n + 1
  222.         
  223.         try:
  224.             next = self.iter.next()
  225.         except StopIteration:
  226.             log.debug('stop iteration, calling success: %r', funcinfo(self.callback.success))
  227.             self.callback.success()
  228.  
  229.         log.debug('%s #%d: %r', funcinfo(self.callback), self.n, funcinfo(next))
  230.         next(*a, **dict(success = self, error = self.callback.error))
  231.  
  232.  
  233.  
  234. def do_cb_na(seq, callback = None):
  235.     CallbackSequenceNoArgs(seq, callback = callback)()
  236.  
  237. do_cb_na = callsback(do_cb_na)
  238.  
  239. class CallbackSequenceNoArgs(object):
  240.     
  241.     def __init__(self, sequence, callback):
  242.         self.iter = iter(sequence)
  243.         self.callback = callback
  244.         self.n = 0
  245.  
  246.     
  247.     def __call__(self, *a):
  248.         self.n = self.n + 1
  249.         
  250.         try:
  251.             next = self.iter.next()
  252.         except StopIteration:
  253.             log.debug('stop iteration, calling success: %r', funcinfo(self.callback.success))
  254.             self.callback.success()
  255.  
  256.         log.debug('%s #%d: %r', funcinfo(self.callback), self.n, funcinfo(next))
  257.         next(**dict(success = self, error = self.callback.error))
  258.  
  259.  
  260.  
  261. def wxcall(func):
  262.     
  263.     def wrapper(*a, **k):
  264.         CallLater(func, threadname = 'MainThread')(*a, **k)
  265.  
  266.     wrapper = (wraps(func),)(wrapper)
  267.     return wrapper
  268.  
  269. if __name__ == '__main__':
  270.     
  271.     class MyProtocol(object):
  272.         
  273.         def networkOperation(self, someArg, callback = None):
  274.             callback.success()
  275.  
  276.         networkOperation = callsback(networkOperation)
  277.  
  278.     
  279.     def good():
  280.         print 'success'
  281.  
  282.     
  283.     def bad():
  284.         print 'bad'
  285.  
  286.     c = Callback(success = good)
  287.     MyProtocol().networkOperation(5, callback = c)
  288.     MyProtocol().networkOperation(5, success = good)
  289.     MyProtocol().networkOperation(5)
  290.  
  291.