def _generate_code(self): self.cache = cache = self.static_cache.copy() def callback(*args, **kw): types = tuple( [getattr(arg, '__class__', type(arg)) for arg in args]) key = tuple(map(istype, types)) self.__lock__.acquire() try: action = self.rules.default_action for sig in self.registry: if implies(key, sig): action = combine_actions(action, self.registry[sig]) f = cache[types] = compile_method(action, self) finally: self.__lock__.release() return f(*args, **kw) c = Code.from_function(self.function, copy_lineno=True) types = [ class_or_type_of(Local(name)) for name in flatten(inspect.getargspec(self.function)[0]) ] target = Call(Const(cache.get), (tuple(types), Const(callback))) c.return_(call_thru(self.function, target)) return c.code()
def testClassBodyRules(self): from peak.rules.core import Local, Rule from peak.rules.criteria import Signature, Test, Class, Value from peak.rules.predicates import IsInstance, Truth from peak.util.decorators import enclosing_frame im_func = lambda x: getattr(x, 'im_func', x) abstract() def f1(a): pass abstract() def f2(b): pass # This is to verify that the rules have sequence numbers by definition # order, not reverse definition order, inside a class. num = Rule(None).sequence class T: f1 = enclosing_frame(level=2).f_locals['f1'] # ugh when(f1) def f1_(a): pass f2 = enclosing_frame(level=2).f_locals['f2'] when(f2, 'b') def f2_(b): pass self.assertEqual(list(rules_for(f1)), [Rule(im_func(T.f1_), (T, ), Method, num + 1)]) self.assertEqual(list(rules_for(f2)), [ Rule( im_func(T.f2_), Signature([ Test(IsInstance(Local('b')), Class(T)), Test(Truth(Local('b')), Value(True)) ]), Method, num + 2) ])
def test_basics(self): from peak.util.assembler import Pass, Getattr, Local self.check(Pass, '') self.check(Getattr(Local('a'), 'b'), 'a.b') self.roundtrip('not -+~`a`') self.roundtrip('a+b-c*d/e%f**g//h') self.roundtrip('a and b or not c') self.roundtrip('~a|b^c&d<<e>>f') self.roundtrip('(a, b)') self.roundtrip('[a, b]') self.roundtrip('[a]') self.roundtrip('[]') self.roundtrip('()') self.roundtrip('1') self.roundtrip('a.b.c')
def setUp(self): from peak.rules.ast_builder import parse_expr from peak.rules.codegen import ExprBuilder from peak.util.assembler import Local, Const from peak.rules.debug.decompile import decompile class Const(Const): pass # non-folding class ExprBuilder(ExprBuilder): def Const(self, value): return Const(value) argmap = dict([(name, Local(name)) for name in 'abcdefgh']) builder = ExprBuilder(argmap, locals(), globals(), __builtins__) self.parse = builder.parse self.decompile = decompile
def testParseInequalities(self): from peak.rules.predicates import CriteriaBuilder, Comparison, Truth from peak.util.assembler import Compare, Local from peak.rules.criteria import Inequality, Test, Value from peak.rules.ast_builder import parse_expr builder = CriteriaBuilder(dict(x=Local('x'), y=Local('y')), locals(), globals(), __builtins__) pe = builder.parse x_cmp_y = lambda op, t=True: Test( Truth(Compare(Local('x'), ((op, Local('y')), ))), Value(True, t)) x, y = Comparison(Local('x')), Comparison(Local('y')) for op, mirror_op, not_op, stdop, not_stdop in [ ('>', '<', '<=', '>', '<='), ('<', '>', '>=', '<', '>='), ('==', '==', '!=', '==', '!='), ('<>', '<>', '==', '!=', '=='), ]: if op == '<>' and sys.version >= "3": continue fwd_sig = Test(x, Inequality(op, 1)) self.assertEqual(pe('x %s 1' % op), fwd_sig) self.assertEqual(pe('1 %s x' % mirror_op), fwd_sig) rev_sig = Test(x, Inequality(mirror_op, 1)) self.assertEqual(pe('x %s 1' % mirror_op), rev_sig) self.assertEqual(pe('1 %s x' % op), rev_sig) not_sig = Test(x, Inequality(not_op, 1)) self.assertEqual(pe('not x %s 1' % op), not_sig) self.assertEqual(pe('not x %s 1' % not_op), fwd_sig) self.assertEqual(pe('x %s y' % op), x_cmp_y(stdop)) self.assertEqual(pe('x %s y' % not_op), x_cmp_y(not_stdop)) self.assertEqual(pe('not x %s y' % op), x_cmp_y(stdop, False)) self.assertEqual(pe('not x %s y' % not_op), x_cmp_y(not_stdop, False))
def setup(r, f): when(classify, Signature([Test(Comparison(Local('age')), r)]))(f)
def gen_arg(v): if isinstance(v,basestring): return Local(v) if isinstance(v,list): return tuple(map(gen_arg,v))