def wrap(self, func): #{{{ if not iscallable(func): raise TypeError('Argument must be a valid callable object') newfunc = func(self._newcall) if not iscallable(newfunc): raise TypeError('Return value of wrapping callable must be a valid callable object') if not _ism(newfunc): newfunc = method(newfunc, self, self.__class__) self._newcall = newfunc
def __init__(self, obj, callback=None, **kwargs): #{{{ self.__name__ = getattr(obj, '__name__', 'UnnamedCallable') isw = needs_wrapping(obj) obj = callableobj(obj) if not obj: raise TypeError('Argument must be a valid callable object') elif callback is not None and not iscallable(callback): raise TypeError('callback argument must be a callable object') self._object = None self._function = None self._newcall = self.call self._numargs, self._maxargs = num_static_args(obj) isweak = bool(kwargs.get('weak', True)) if isw: isweak = False mtype = methodtype(obj) self._methodtype = mtype if mtype not in (METHODTYPE_NOTMETHOD, METHODTYPE_UNBOUND): o = obj.im_class if mtype == METHODTYPE_INSTANCE: o = obj.im_self self._object = cref(o, callback, weak=isweak) self._function = obj.im_func else: self._function = cref(obj, callback, weak=isweak) self._funcid = cid(obj)
def connect_choosefunc(self, listname, slots): #{{{ cleanlist, vals = self._cleanlist, slots.get(listname, ()) clist, cleanfunc, test_store = self._funclist[listname], mkcallback(listname, cleanlist), [] weak = bool(slots.get('weak', self.func.isweak)) wcf = bool(slots.get('weakcondf', weak)) uniq = bool(slots.get('unique', True)) for tup in vals: cond, f = tup if not iscallable(cond) or not iscallable(f): raise TypeError('Detected non-callable element of \'%s\' slots' %listname) found = self._find(f, listname, chooser=cond) if found and uniq: continue else: cfunc = CallableWrapper(cond, cleanfunc, weak=wcf) func = CallableWrapper(f, cleanfunc, weak=weak) test_store.append((ChoiceObject(cfunc, func))) if test_store: clist.extend(test_store)
def _find_cond(self, **kw): #{{{ chooser = kw.get('chooser', None) choosercid = None if iscallable(chooser): choosercid = cid(chooser) def fcond(self, listname, siglist, f, index): #{{{ if choosercid and listname in ('choose', 'choosereturn'): if choosercid != f.choosefunc.cid: return False return True # End def #}}} return fcond
def disconnect_choosefunc(self, listname, slots): #{{{ l, vals = self._funclist[listname], slots.get(listname, ()) delall = bool(slots.get('deleteall', False)) if delall and (not (len(slots)-1) or listname in slots): while l: l.pop() return for tup in slots.get(listname, ()): f, cond = tup, None if not iscallable(f): cond, f = tup found = self._find(f, listname, chooser=None) if found: del l[found[0]]
def _find_cond(self, **kw): #{{{ chooser = kw.pop('chooser', None) choosercid = None if iscallable(chooser): choosercid = cid(chooser) super_fcond = super(ChooseExtension, self)._find_cond(**kw) def fcond(self, listname, siglist, f, index): #{{{ if not super_fcond(self, listname, siglist, f, index): return False if choosercid and listname in ('choose', 'choosereturn', 'chooseyield'): if choosercid != f.choosefunc.cid: return False return True # End def #}}} return fcond
def connect_func(self, listname, slots): #{{{ weak = bool(slots.get('weak', self.func.isweak)) uniq = bool(slots.get('unique', True)) l, vals = self._funclist[listname], slots.get(listname, ()) cleanlist, test_store = self._cleanlist, [] cleanfunc = mkcallback(listname, cleanlist) for f in vals: if not iscallable(f): raise TypeError('Detected non-callable element of \'%s\' slots' %listname) c = CallableWrapper(f, cleanfunc, weak=weak) found = self._find(f, listname) or c.cid in (cid(o) for o in test_store) if found and uniq: continue test_store.append(c) if test_store: l.extend(test_store)
def __init__(self, signal, **kwargs): #{{{ if not iscallable(signal): raise TypeError("Argument must be callable.") expected = ('weak', 'active', 'activate_on_call') if any(kw for kw in kwargs if kw not in expected): raise ValueError("Detected unexpected arguments: %s" %', '.join([found])) weak = kwargs.get('weak', True) self._func = CallableWrapper(signal, weak=weak) self.__name__ = self._func.__name__ funclist = self._funclist = dict() conn = self._connections = dict() call_funclist = self._call_funclist = dict((n, odict()) for n in ('after', 'replace', 'around', 'before')) self._vars = getattr(self, '_vars', dict()) self._vars.update(active=kwargs.get('active', True), callactivate=kwargs.get('activate_on_call', False), caller=callfunc) # Initialize values of function lists self._init_funclist(funclist) self._init_calls(call_funclist) self._init_connections(conn)
def num_static_args(obj): #{{{ if not iscallable(obj): return -1, None if _ism(obj): obj = obj.im_func if isinstance(obj, _CallableWrapper): return obj._numargs, obj._maxargs isc = isclass(obj) if not _isf(obj) and not isc: obj = obj.__call__ if not _ism(obj): return -1, None argspec = cgetargspec(obj) l, d = len(argspec[0]), argspec[3] max = l if argspec[1]: max = None if d: l -= len(d) if isc: l -= 1 return l, max
def _setcaller(self, c): #{{{ if c is None: return elif not iscallable(c): raise TypeError('caller property must be a valid callable object') self._vars['caller'] = CallableWrapper(c, weak=False)