Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

I think I've seen this ORM somewhere before...

root/trunk/test_codewalk.py

Revision 41 (checked in by fumanchu, 8 years ago)

1. codewalk.EarlyBinder? now late-binds any object with a bind_late attribute which evaluates to True. Notice that functions are first-class objects and so may be assigned such an attribute.
2. Changed postgres timedelta from pg interval to float8.

Line 
1 import unittest
2 from dejavu import codewalk
3 nums = codewalk.numeric_opcodes
4
5 import datetime
6 import fixedpoint
7
8 amount = 5
9 a = [1,2,3,4,5]
10 f = [lambda x: x in a,
11      lambda x: x + datetime.date(2004, 1, 1),
12      lambda x, **kw: (x.Date == datetime.date(2004, 1, 1)
13                       and x.Qty < kw['Size']),
14      # Mix names from globals, locals, attrs
15      lambda x, amount: (4 != x.amount) or (amount * 3 > 20),
16      lambda x: 3 * 4 * 5 * x,
17      lambda x: a[2:4] == -x['offset'],
18      lambda x: amount == 5 or amount == x.Qty,
19      lambda x: not (x.a == 3 and (x.b > 1 or x.b < -10)),
20      # Unicode const
21      lambda x: x.Name == u'Dimsdale',
22      # getattr
23      lambda x: getattr(x, 'Name') == u'Dimsdale',
24      # fixedpoint
25      lambda x: x.Amount > fixedpoint.FixedPoint(3, 2),
26      # multiple args
27      lambda x, y, z, **kw: x.Qty > 1 and y.Qty > 20 and z.Type == 'A',
28      ]
29
30 # Closure example
31 def foo():
32     a = 5
33     def bar():
34         return a + 5
35     return bar
36 f.append(foo())
37
38 fcode = [func.func_code.co_code for func in f]
39
40
41 class VisitorTests(unittest.TestCase):
42    
43     def test_safe_tuple(self):
44         l = ['logic', 'icontains', 'getattr', 'x', 'field', 'criteria', u'GroupName']
45         self.assertEqual(codewalk.safe_tuple(l), ('logic', 'icontains', 'getattr',
46                                                   'x', 'field', 'criteria', 'GroupName'))
47    
48     def test_Localizer(self):
49         r = codewalk.Localizer(f[0]).bytecode()
50         self.assertEqual(r, nums(['LOAD_FAST', 0, 0,
51                                   'LOAD_CONST', 1, 0,
52                                   'COMPARE_OP', 6, 0,
53                                   'RETURN_VALUE']))
54         r = codewalk.Localizer(f[1]).bytecode()
55         self.assertEqual(r, nums(['LOAD_FAST', 0, 0,
56                                   'LOAD_CONST', 3, 0,
57                                   'LOAD_ATTR', 2, 0,
58                                   'LOAD_CONST', 1, 0,
59                                   'LOAD_CONST', 2, 0,
60                                   'LOAD_CONST', 2, 0,
61                                   'CALL_FUNCTION', 3, 0,
62                                   'BINARY_ADD',
63                                   'RETURN_VALUE']))
64         r = codewalk.Localizer(f[2]).bytecode()
65         self.assertEqual(r, nums(['LOAD_FAST', 0, 0,
66                                   'LOAD_ATTR', 1, 0,
67                                   'LOAD_CONST', 4, 0,
68                                   'LOAD_ATTR', 3, 0,
69                                   'LOAD_CONST', 1, 0,
70                                   'LOAD_CONST', 2, 0,
71                                   'LOAD_CONST', 2, 0,
72                                   'CALL_FUNCTION', 3, 0,
73                                   'COMPARE_OP', 2, 0,
74                                   'JUMP_IF_FALSE', 17, 0,
75                                   'POP_TOP',
76                                   'LOAD_FAST', 0, 0,
77                                   'LOAD_ATTR', 4, 0,
78                                   'LOAD_FAST', 1, 0,
79                                   'LOAD_CONST', 3, 0,
80                                   'BINARY_SUBSCR',
81                                   'COMPARE_OP', 0, 0,
82                                   'RETURN_VALUE']))
83        
84         r = codewalk.Localizer(f[3]).bytecode()
85         self.assertEqual(r, nums(['LOAD_CONST', 1, 0,
86                                   'LOAD_FAST', 0, 0,
87                                   'LOAD_ATTR', 1, 0,
88                                   'COMPARE_OP', 3, 0,
89                                   'JUMP_IF_TRUE', 14, 0,
90                                   'POP_TOP',
91                                   'LOAD_FAST', 1, 0,
92                                   'LOAD_CONST', 2, 0,
93                                   'BINARY_MULTIPLY',
94                                   'LOAD_CONST', 3, 0,
95                                   'COMPARE_OP', 4, 0,
96                                   'RETURN_VALUE']))
97    
98     def test_EarlyBinder(self):
99         r = codewalk.EarlyBinder(f[1]).bytecode()
100         self.assertEqual(r, nums(['LOAD_FAST', 0, 0,
101                                   'LOAD_CONST', 5, 0,
102                                   'BINARY_ADD',
103                                   'RETURN_VALUE']))
104         r = codewalk.EarlyBinder(f[2]).bytecode()
105         self.assertEqual(r, nums(['LOAD_FAST', 0, 0,
106                                   'LOAD_ATTR', 1, 0,
107                                   'LOAD_CONST', 6, 0,
108                                   'COMPARE_OP', 2, 0,
109                                   'JUMP_IF_FALSE', 17, 0,
110                                   'POP_TOP',
111                                   'LOAD_FAST', 0, 0,
112                                   'LOAD_ATTR', 4, 0,
113                                   'LOAD_FAST', 1, 0,
114                                   'LOAD_CONST', 3, 0,
115                                   'BINARY_SUBSCR',
116                                   'COMPARE_OP', 0, 0,
117                                   'RETURN_VALUE']))
118         r = codewalk.EarlyBinder(f[4]).bytecode()
119         self.assertEqual(r, nums(['LOAD_CONST', 5, 0,
120                                   'LOAD_FAST', 0, 0,
121                                   'BINARY_MULTIPLY',
122                                   'RETURN_VALUE']))
123         r = codewalk.EarlyBinder(f[5]).bytecode()
124         self.assertEqual(r, nums(['LOAD_CONST', 5, 0,
125                                   'LOAD_FAST', 0, 0,
126                                   'LOAD_CONST', 3, 0,
127                                   'BINARY_SUBSCR',
128                                   'UNARY_NEGATIVE',
129                                   'COMPARE_OP', 2, 0,
130                                   'RETURN_VALUE']))
131         r = codewalk.EarlyBinder(f[6]).bytecode()
132         self.assertEqual(r, nums(['LOAD_CONST', 2, 0,
133                                   'JUMP_IF_TRUE', 13, 0,
134                                   'POP_TOP',
135                                   'LOAD_CONST', 1, 0,
136                                   'LOAD_FAST', 0, 0,
137                                   'LOAD_ATTR', 2, 0,
138                                   'COMPARE_OP', 2, 0,
139                                   'RETURN_VALUE']))
140         r = codewalk.EarlyBinder(f[9]).bytecode()
141         self.assertEqual(r, nums(['LOAD_FAST', 0, 0,
142                                   # 2, since co_names was ('getattr', 'x').
143                                   'LOAD_ATTR', 2, 0,
144                                   'LOAD_CONST', 2, 0,
145                                   'COMPARE_OP', 2, 0,
146                                   'RETURN_VALUE']))
147         # Test a tainted (late-bound) function
148         e = lambda x: x.FirstDate >= datetime.date.today()
149         r = codewalk.EarlyBinder(e, bind_late=[datetime.date.today]).bytecode()
150         self.assertEqual(r, nums(['LOAD_FAST', 0, 0,
151                                   'LOAD_ATTR', 1, 0,
152                                   'LOAD_CONST', 3, 0,
153                                   'CALL_FUNCTION', 0, 0,
154                                   'COMPARE_OP', 5, 0,
155                                   'RETURN_VALUE']))
156        
157         # Closures (dereferencing of func_closure)
158         r = codewalk.EarlyBinder(f[12]).bytecode()
159         self.assertEqual(r, nums(['LOAD_CONST', 2, 0,
160                                   'RETURN_VALUE',
161                                   'LOAD_CONST', 0, 0,
162                                   'RETURN_VALUE']))
163    
164     def test_LambdaDecompiler(self):
165         s = ['lambda x: x in a',
166              'lambda x: x + datetime.date(2004, 1, 1)',
167              "lambda x, **kw: (x.Date == datetime.date(2004, 1, 1)) and (x.Qty < kw['Size'])",
168              "lambda x, amount: (4 != x.amount) or (amount * 3 > 20)",
169              "lambda x: 3 * 4 * 5 * x",
170              "lambda x: a[2:4] == -(x['offset'])",
171              "lambda x: (amount == 5) or (amount == x.Qty)",
172              "lambda x: not ((x.a == 3) and ((x.b > 1) or (x.b < -10)))",
173              "lambda x: x.Name == u'Dimsdale'",
174              "lambda x: getattr(x, 'Name') == u'Dimsdale'",
175              "lambda x: x.Amount > fixedpoint.FixedPoint(3, 2)",
176              "lambda x, y, z, **kw: (x.Qty > 1) and ((y.Qty > 20) and (z.Type == 'A'))",
177              ]
178         for funcitem, stritem in zip(f, s):
179             r = codewalk.LambdaDecompiler(funcitem).code()
180             self.assertEqual(r, stritem)
181    
182     def test_BranchTracker(self):
183         r = codewalk.BranchTracker(f[6]).branches()
184         self.assertEqual(r, [9, 22])
185    
186     def test_KeywordInspector(self):
187         e = lambda x, **kw: x.Size > kw['Size']
188         self.assertEqual(codewalk.KeywordInspector(e).kwargs(), ["Size"])
189         e = lambda x: x.Size > kw['Size']
190         self.assertRaises(ValueError, codewalk.KeywordInspector, e)
191         e = lambda x, **kw: x.Date > x.newdate(kw['Year'], 1, 1)
192         self.assertEqual(codewalk.KeywordInspector(e).kwargs(), ["Year"])
193
194
195
196
197 if __name__ == "__main__":
198     unittest.main()
199
Note: See TracBrowser for help on using the browser.