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