3 from cStringIO
import StringIO
17 return disassemble(compile(line
, '', 'single'))
19 class TestTranforms(unittest
.TestCase
):
22 # UNARY_NOT JUMP_IF_FALSE POP_TOP --> JUMP_IF_TRUE POP_TOP'
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
)
32 def test_elim_inversion_of_is_or_in(self
):
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)',),
39 asm
= dis_single(line
)
40 self
.assert_(elem
in asm
)
42 def test_none_as_constant(self
):
43 # LOAD_GLOBAL None --> LOAD_CONST None
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
)
53 def test_while_one(self
):
54 # Skip over: LOAD_CONST trueconst JUMP_IF_FALSE xx POP_TOP
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
)
65 def test_pack_unpack(self
):
67 ('a, = a,', 'LOAD_CONST',),
68 ('a, b = a, b', 'ROT_TWO',),
69 ('a, b, c = a, b, c', 'ROT_THREE',),
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
)
76 def test_folding_of_tuples_of_constants(self
):
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 ('(None, 1, None)', '((None, 1, None))'),
82 ('((1, 2), 3, 4)', '(((1, 2), 3, 4))'),
84 asm
= dis_single(line
)
85 self
.assert_(elem
in asm
)
86 self
.assert_('BUILD_TUPLE' not in asm
)
88 # Bug 1053819: Tuple of constants misidentified when presented with:
89 # . . . opcode_with_arg 100 unary_opcode BUILD_TUPLE 1 . . .
90 # The following would segfault upon compilation
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 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
102 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
105 def test_folding_of_binops_on_constants(self
):
107 ('a = 2+3+4', '(9)'), # chained fold
108 ('"@"*4', "('@@@@')"), # check string ops
109 ('a="abc" + "def"', "('abcdef')"), # check string ops
110 ('a = 3**4', '(81)'), # binary power
111 ('a = 3*4', '(12)'), # binary multiply
112 ('a = 13//4', '(3)'), # binary floor divide
113 ('a = 14%4', '(2)'), # binary modulo
114 ('a = 2+3', '(5)'), # binary add
115 ('a = 13-4', '(9)'), # binary subtract
116 ('a = (12,13)[1]', '(13)'), # binary subscr
117 ('a = 13 << 2', '(52)'), # binary lshift
118 ('a = 13 >> 2', '(3)'), # binary rshift
119 ('a = 13 & 7', '(5)'), # binary and
120 ('a = 13 ^ 7', '(10)'), # binary xor
121 ('a = 13 | 7', '(15)'), # binary or
123 asm
= dis_single(line
)
124 self
.assert_(elem
in asm
, asm
)
125 self
.assert_('BINARY_' not in asm
)
127 # Verify that unfoldables are skipped
128 asm
= dis_single('a=2+"b"')
129 self
.assert_('(2)' in asm
)
130 self
.assert_("('b')" in asm
)
132 # Verify that large sequences do not result from folding
133 asm
= dis_single('a="x"*1000')
134 self
.assert_('(1000)' in asm
)
136 def test_folding_of_unaryops_on_constants(self
):
138 ('`1`', "('1')"), # unary convert
139 ('-0.5', '(-0.5)'), # unary negative
140 ('~-2', '(1)'), # unary invert
142 asm
= dis_single(line
)
143 self
.assert_(elem
in asm
, asm
)
144 self
.assert_('UNARY_' not in asm
)
146 # Verify that unfoldables are skipped
148 ('-"abc"', "('abc')"), # unary negative
149 ('~"abc"', "('abc')"), # unary invert
151 asm
= dis_single(line
)
152 self
.assert_(elem
in asm
, asm
)
153 self
.assert_('UNARY_' in asm
)
155 def test_elim_extra_return(self
):
156 # RETURN LOAD_CONST None RETURN --> RETURN
160 self
.assert_('LOAD_CONST' not in asm
)
161 self
.assert_('(None)' not in asm
)
162 self
.assertEqual(asm
.split().count('RETURN_VALUE'), 1)
166 def test_main(verbose
=None):
168 from test
import test_support
169 test_classes
= (TestTranforms
,)
170 test_support
.run_unittest(*test_classes
)
172 # verify reference counting
173 if verbose
and hasattr(sys
, "gettotalrefcount"):
176 for i
in xrange(len(counts
)):
177 test_support
.run_unittest(*test_classes
)
179 counts
[i
] = sys
.gettotalrefcount()
182 if __name__
== "__main__":
183 test_main(verbose
=True)