0001 import dis 0002 import sys 0003 from cStringIO import StringIO 0004 import unittest 0005 0006 def disassemble(func): 0007 f = StringIO() 0008 tmp = sys.stdout 0009 sys.stdout = f 0010 dis.dis(func) 0011 sys.stdout = tmp 0012 result = f.getvalue() 0013 f.close() 0014 return result 0015 0016 def dis_single(line): 0017 return disassemble(compile(line, '', 'single')) 0018 0019 class TestTranforms(unittest.TestCase): 0020 0021 def test_unot(self): 0022 # UNARY_NOT JUMP_IF_FALSE POP_TOP --> JUMP_IF_TRUE POP_TOP' 0023 def unot(x): 0024 if not x == 2: 0025 del x 0026 asm = disassemble(unot) 0027 for elem in ('UNARY_NOT', 'JUMP_IF_FALSE'): 0028 self.assert_(elem not in asm) 0029 for elem in ('JUMP_IF_TRUE', 'POP_TOP'): 0030 self.assert_(elem in asm) 0031 0032 def test_elim_inversion_of_is_or_in(self): 0033 for line, elem in ( 0034 ('not a is b', '(is not)',), 0035 ('not a in b', '(not in)',), 0036 ('not a is not b', '(is)',), 0037 ('not a not in b', '(in)',), 0038 ): 0039 asm = dis_single(line) 0040 self.assert_(elem in asm) 0041 0042 def test_none_as_constant(self): 0043 # LOAD_GLOBAL None --> LOAD_CONST None 0044 def f(x): 0045 None 0046 return x 0047 asm = disassemble(f) 0048 for elem in ('LOAD_GLOBAL',): 0049 self.assert_(elem not in asm) 0050 for elem in ('LOAD_CONST', '(None)'): 0051 self.assert_(elem in asm) 0052 0053 def test_while_one(self): 0054 # Skip over: LOAD_CONST trueconst JUMP_IF_FALSE xx POP_TOP 0055 def f(): 0056 while 1: 0057 pass 0058 return list 0059 asm = disassemble(f) 0060 for elem in ('LOAD_CONST', 'JUMP_IF_FALSE'): 0061 self.assert_(elem not in asm) 0062 for elem in ('JUMP_ABSOLUTE',): 0063 self.assert_(elem in asm) 0064 0065 def test_pack_unpack(self): 0066 for line, elem in ( 0067 ('a, = a,', 'LOAD_CONST',), 0068 ('a, b = a, b', 'ROT_TWO',), 0069 ('a, b, c = a, b, c', 'ROT_THREE',), 0070 ): 0071 asm = dis_single(line) 0072 self.assert_(elem in asm) 0073 self.assert_('BUILD_TUPLE' not in asm) 0074 self.assert_('UNPACK_TUPLE' not in asm) 0075 0076 def test_folding_of_tuples_of_constants(self): 0077 for line, elem in ( 0078 ('a = 1,2,3', '((1, 2, 3))'), 0079 ('("a","b","c")', "(('a', 'b', 'c'))"), 0080 ('a,b,c = 1,2,3', '((1, 2, 3))'), 0081 ('(None, 1, None)', '((None, 1, None))'), 0082 ('((1, 2), 3, 4)', '(((1, 2), 3, 4))'), 0083 ): 0084 asm = dis_single(line) 0085 self.assert_(elem in asm) 0086 self.assert_('BUILD_TUPLE' not in asm) 0087 0088 # Bug 1053819: Tuple of constants misidentified when presented with: 0089 # . . . opcode_with_arg 100 unary_opcode BUILD_TUPLE 1 . . . 0090 # The following would segfault upon compilation 0091 def crater(): 0092 (~[ 0093 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0094 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0095 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0096 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0097 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0098 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0099 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0100 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0101 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0102 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0103 ],) 0104 0105 def test_elim_extra_return(self): 0106 # RETURN LOAD_CONST None RETURN --> RETURN 0107 def f(x): 0108 return x 0109 asm = disassemble(f) 0110 self.assert_('LOAD_CONST' not in asm) 0111 self.assert_('(None)' not in asm) 0112 self.assertEqual(asm.split().count('RETURN_VALUE'), 1) 0113 0114 0115 0116 def test_main(verbose=None): 0117 import sys 0118 from test import test_support 0119 test_classes = (TestTranforms,) 0120 test_support.run_unittest(*test_classes) 0121 0122 # verify reference counting 0123 if verbose and hasattr(sys, "gettotalrefcount"): 0124 import gc 0125 counts = [None] * 5 0126 for i in xrange(len(counts)): 0127 test_support.run_unittest(*test_classes) 0128 gc.collect() 0129 counts[i] = sys.gettotalrefcount() 0130 print counts 0131 0132 if __name__ == "__main__": 0133 test_main(verbose=True) 0134
Generated by PyXR 0.9.4