blob: 33eb0f57574504685bb7335dd3161a2f137eceb5 [file] [log] [blame]
Raymond Hettingerfd2d1f72004-08-23 23:37:48 +00001import dis
2import sys
3from cStringIO import StringIO
4import unittest
5
6def disassemble(func):
7 f = StringIO()
8 tmp = sys.stdout
9 sys.stdout = f
10 dis.dis(func)
11 sys.stdout = tmp
12 result = f.getvalue()
13 f.close()
14 return result
15
16def dis_single(line):
17 return disassemble(compile(line, '', 'single'))
18
19class TestTranforms(unittest.TestCase):
20
21 def test_unot(self):
22 # UNARY_NOT JUMP_IF_FALSE POP_TOP --> JUMP_IF_TRUE POP_TOP'
23 def unot(x):
24 if not x == 2:
25 del x
26 asm = disassemble(unot)
27 for elem in ('UNARY_NOT', 'JUMP_IF_FALSE'):
28 self.assert_(elem not in asm)
29 for elem in ('JUMP_IF_TRUE', 'POP_TOP'):
30 self.assert_(elem in asm)
31
32 def test_elim_inversion_of_is_or_in(self):
33 for line, elem in (
34 ('not a is b', '(is not)',),
35 ('not a in b', '(not in)',),
36 ('not a is not b', '(is)',),
37 ('not a not in b', '(in)',),
38 ):
39 asm = dis_single(line)
40 self.assert_(elem in asm)
41
42 def test_none_as_constant(self):
43 # LOAD_GLOBAL None --> LOAD_CONST None
44 def f(x):
Tim Peters66cb0182004-08-26 05:23:19 +000045 None
46 return x
Raymond Hettingerfd2d1f72004-08-23 23:37:48 +000047 asm = disassemble(f)
48 for elem in ('LOAD_GLOBAL',):
49 self.assert_(elem not in asm)
50 for elem in ('LOAD_CONST', '(None)'):
51 self.assert_(elem in asm)
52
53 def test_while_one(self):
54 # Skip over: LOAD_CONST trueconst JUMP_IF_FALSE xx POP_TOP
55 def f():
Tim Peters66cb0182004-08-26 05:23:19 +000056 while 1:
57 pass
58 return list
Raymond Hettingerfd2d1f72004-08-23 23:37:48 +000059 asm = disassemble(f)
60 for elem in ('LOAD_CONST', 'JUMP_IF_FALSE'):
61 self.assert_(elem not in asm)
62 for elem in ('JUMP_ABSOLUTE',):
63 self.assert_(elem in asm)
64
65 def test_pack_unpack(self):
66 for line, elem in (
67 ('a, = 1,', 'LOAD_CONST',),
68 ('a, b = 1, 2', 'ROT_TWO',),
69 ('a, b, c = 1, 2, 3', 'ROT_THREE',),
70 ):
71 asm = dis_single(line)
72 self.assert_(elem in asm)
73 self.assert_('BUILD_TUPLE' not in asm)
74 self.assert_('UNPACK_TUPLE' not in asm)
75
76 def test_elim_extra_return(self):
77 # RETURN LOAD_CONST None RETURN --> RETURN
78 def f(x):
79 return x
80 asm = disassemble(f)
81 self.assert_('LOAD_CONST' not in asm)
82 self.assert_('(None)' not in asm)
83 self.assertEqual(asm.split().count('RETURN_VALUE'), 1)
84
85
86
87def test_main(verbose=None):
88 import sys
89 from test import test_support
90 test_classes = (TestTranforms,)
91 test_support.run_unittest(*test_classes)
92
93 # verify reference counting
94 if verbose and hasattr(sys, "gettotalrefcount"):
95 import gc
96 counts = [None] * 5
97 for i in xrange(len(counts)):
98 test_support.run_unittest(*test_classes)
99 gc.collect()
100 counts[i] = sys.gettotalrefcount()
101 print counts
102
103if __name__ == "__main__":
104 test_main(verbose=True)