def settings(func): #{{{ signal = getattr(func, 'signal', None) if isinstance(signal, DecoSignalExtension) and isinstance(signal, BaseSignal): DecoSignalFunction = func elif not _isf(func) and not isclass(func): raise TypeError('argument must be a python function or a python class') else: signal = mkdeco(func, opt) args, vargs, vkeys, defaults = spec = cgetargspec(func) code_args = args + [v for v in (vargs, vkeys) if v != None] fcode = Code(CodeList(), (), code_args, bool(vargs), bool(vkeys), True, 'f', '<dynamic decorator signal function>', 1, None) fcode.code[:] = ([(SetLineno, 2), (LOAD_GLOBAL, 'signal')] + bp_call_args(*spec) + [(RETURN_VALUE, None)]) DecoSignalFunction = newfunction(fcode.to_code(), locals(), 'DecoSignalFunction', default_argvals(args, defaults)) d = DecoSignalFunction d = wraps(func)(d) d.signal = signal signal.signalfunc = d for n in signal.decorators: setattr(d, n, getattr(signal, n)) opt['MAKE_SIGNAL'] = 1 return global_settings(d, **opt)(d)
def _func_settings(self, func): #{{{ global_settings = self._vars['global_settings'] mk_sig = global_settings.pop('MAKE_SIGNAL', 0) s = self._csettings() options = self._func_settings_options(s, global_settings) block = self._blocked_func_settings() custom_block = self._custom_blocked_func_settings news = dict((k, v) for k, v in s.iteritems() if k not in block and not custom_block(k)) ism = bool(s.get('ismethod', False)) istup = isinstance(func, tuple) meth_app = self._vars['methods'].append # Add to methods var so callfunc can process both # conditional callables and target callables if ism: callmeth = bool(s.get('callmethod', False)) if callmeth and not mk_sig: if options['overload']: raise ValueError("Keywords 'overload' and 'callmethod' cannot be True at the same time") func_obj = func[1] if istup else func name, vardict = func_obj.__name__, dict() # Low-level function creation to avoid use of exec # which allows turning this class into a builtin type args, vargs, vkeys, defaults = spec = cgetargspec(func_obj) code_args = args + [v for v in (vargs, vkeys) if v != None] fcode = Code(CodeList(), (), code_args, bool(vargs), bool(vkeys), True, 'f', '<dyn>', 1, None) fcode.code[:] = ([(SetLineno, 2), (LOAD_GLOBAL, 'getattr'), (LOAD_FAST, 'self'), (LOAD_CONST, name), (CALL_FUNCTION, 2), ] + bp_call_args(callmethod=True, *spec) + [(RETURN_VALUE, None)]) f = newfunction(fcode.to_code(), dict(getattr=getattr), 'f', default_argvals(args, defaults)) func = (func[0], f) if istup else f if istup: for f in func: meth_app(f) else: meth_app(func) return func, news, options
def factory(func): args, vargs, vkeys, defaults = spec = cgetargspec(func) names = set(list(args) + [vargs, vkeys]) n, _join, csg = 'cs_str', ''.join, dict(__builtin__.__dict__) csg.update(self.connect_settings.get('globals', {})) # Find name that is unbound while n in names or n in csg: n = _join(n, '_') # Pre-compile expression into a code object csg[n] = compile_str(s.strip(), __file__, 'eval') # Build a new function code_args = args + [v for v in (vargs, vkeys) if v != None] fcode = Code(CodeList(), (), code_args, bool(vargs), bool(vkeys), True, 'whenfunc', '<dyn>', 1, None) fcode.code[:] = ([(SetLineno, 2), (LOAD_GLOBAL, 'bool'), (LOAD_GLOBAL, 'eval'), (LOAD_GLOBAL, n), (CALL_FUNCTION, 1), (CALL_FUNCTION, 1), (RETURN_VALUE, None)]) whenfunc = newfunction(fcode.to_code(), csg, 'whenfunc', default_argvals(args, defaults)) self._vars['settings']['weakcondf'] = False return condfunc(whenfunc)(func)
def factory(func): args, vargs, vkeys, defaults = cgetargspec(func) names = set(list(args) + [vargs, vkeys]) n, sn, _join, csg = 'cs_str', 'cs_stop_str', ''.join, dict(__builtin__.__dict__) csg['StopCascade'] = StopCascade csg.update(self.connect_settings.get('globals', {})) # Find names that are unbound while n in names or n in csg: n = _join(n, '_') while sn in names or sn in csg: sn = _join(sn, '_') # Pre-compile expression into a code object csg[n] = compile_str(s.strip(), '<dynamic cascade expression>', 'eval') csg[sn] = (stop if not isinstance(stop, basestring) else compile_str(str(stop).strip(), '<dynamic cascade stop condition>', 'eval')) # Build a new function: # def cascadefunc(*args, **kwargs): # Not really, dynamically generate args # ret = bool(eval(s)) # if isinstance(stop, basestring): # stop = eval(stop) # if bool(stop): # raise StopCascade(ret) # return ret code_args = args + [v for v in (vargs, vkeys) if v != None] fcode = Code(CodeList(), (), code_args, bool(vargs), bool(vkeys), True, 'cascadefunc', '<dynamic cascade function>', 1, None) labels = map(lambda i: Label(), xrange(4)) fcode.code[:] = ([(SetLineno, 2), (LOAD_GLOBAL, 'bool'), (LOAD_GLOBAL, 'eval'), (LOAD_GLOBAL, n), (CALL_FUNCTION, 1), (CALL_FUNCTION, 1), (STORE_FAST, 'ret'), (SetLineno, 3), (LOAD_GLOBAL, sn), (STORE_FAST, 'stop'), (SetLineno, 4), (LOAD_GLOBAL, 'isinstance'), (LOAD_FAST, 'stop'), (LOAD_GLOBAL, 'basestring'), (CALL_FUNCTION, 2), (JUMP_IF_FALSE, labels[0]), (POP_TOP, None), (SetLineno, 5), (LOAD_GLOBAL, 'eval'), (LOAD_FAST, 'stop'), (CALL_FUNCTION, 1), (STORE_FAST, 'stop'), (JUMP_FORWARD, labels[1]), (labels[0], None), (POP_TOP, None), (labels[1], None), (SetLineno, 6), (LOAD_FAST, 'stop'), (JUMP_IF_FALSE, labels[2]), (POP_TOP, None), (SetLineno, 7), (LOAD_GLOBAL, 'StopCascade'), (LOAD_FAST, 'ret'), (CALL_FUNCTION, 1), (RAISE_VARARGS, 1), (JUMP_FORWARD, labels[3]), (labels[2], None), (POP_TOP, None), (SetLineno, 8), (labels[3], None), (LOAD_FAST, 'ret'), (RETURN_VALUE, None)]) cascadefunc = newfunction(fcode.to_code(), csg, 'cascadefunc', default_argvals(args, defaults)) self._vars['settings']['weakcondf'] = False return condfunc(cascadefunc)(func)