blob: 934b57c1e8d238fcb688535db7315b7db153550a [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 (
Raymond Hettinger2c31a052004-09-22 18:44:21 +000067 ('a, = a,', 'LOAD_CONST',),
68 ('a, b = a, b', 'ROT_TWO',),
69 ('a, b, c = a, b, c', 'ROT_THREE',),
Raymond Hettingerfd2d1f72004-08-23 23:37:48 +000070 ):
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
Raymond Hettinger2c31a052004-09-22 18:44:21 +000076 def test_folding_of_tuples_of_constants(self):
77 for line, elem in (
78 ('a = 1,2,3', '((1, 2, 3))',),
79 ('("a","b","c")', "(('a', 'b', 'c'))",),
80 ('a,b,c = 1,2,3', '((1, 2, 3))',),
81 ):
82 asm = dis_single(line)
83 self.assert_(elem in asm)
84 self.assert_('BUILD_TUPLE' not in asm)
85
Raymond Hettinger23109ef2004-10-26 08:59:14 +000086 # Bug 1053819: Tuple of constants misidentified when presented with:
87 # . . . opcode_with_arg 100 unary_opcode BUILD_TUPLE 1 . . .
88 # The following would segfault upon compilation
89 def crater():
90 (~[
91 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
92 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
93 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
94 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
95 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
96 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
97 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
98 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
99 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
100 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
101 ],)
102
Raymond Hettingerfd2d1f72004-08-23 23:37:48 +0000103 def test_elim_extra_return(self):
104 # RETURN LOAD_CONST None RETURN --> RETURN
105 def f(x):
106 return x
107 asm = disassemble(f)
108 self.assert_('LOAD_CONST' not in asm)
109 self.assert_('(None)' not in asm)
110 self.assertEqual(asm.split().count('RETURN_VALUE'), 1)
111
112
113
114def test_main(verbose=None):
115 import sys
116 from test import test_support
117 test_classes = (TestTranforms,)
118 test_support.run_unittest(*test_classes)
119
120 # verify reference counting
121 if verbose and hasattr(sys, "gettotalrefcount"):
122 import gc
123 counts = [None] * 5
124 for i in xrange(len(counts)):
125 test_support.run_unittest(*test_classes)
126 gc.collect()
127 counts[i] = sys.gettotalrefcount()
128 print counts
129
130if __name__ == "__main__":
131 test_main(verbose=True)