blob: 613d30a4ddefcd16e7e595731384dbc1c884c5a1 [file] [log] [blame]
Collin Winter9475db72007-04-04 18:14:17 +00001# Minimal tests for dis module
2
Christian Heimesc5f05e42008-02-23 17:40:11 +00003from test.test_support import run_unittest
Collin Winter9475db72007-04-04 18:14:17 +00004import unittest
Skip Montanaroadd0ccc2003-02-27 21:27:07 +00005import sys
6import dis
7import StringIO
8
Skip Montanaroadd0ccc2003-02-27 21:27:07 +00009
Skip Montanaroadd0ccc2003-02-27 21:27:07 +000010def _f(a):
Tim Peterseabafeb2003-03-07 15:55:36 +000011 print a
12 return 1
Skip Montanaroadd0ccc2003-02-27 21:27:07 +000013
14dis_f = """\
Michael W. Hudson26848a32003-04-29 17:07:36 +000015 %-4d 0 LOAD_FAST 0 (a)
Tim Peterseabafeb2003-03-07 15:55:36 +000016 3 PRINT_ITEM
17 4 PRINT_NEWLINE
Skip Montanaroadd0ccc2003-02-27 21:27:07 +000018
Michael W. Hudson26848a32003-04-29 17:07:36 +000019 %-4d 5 LOAD_CONST 1 (1)
Tim Peterseabafeb2003-03-07 15:55:36 +000020 8 RETURN_VALUE
Michael W. Hudson26848a32003-04-29 17:07:36 +000021"""%(_f.func_code.co_firstlineno + 1,
22 _f.func_code.co_firstlineno + 2)
23
24
25def bug708901():
26 for res in range(1,
27 10):
28 pass
29
30dis_bug708901 = """\
31 %-4d 0 SETUP_LOOP 23 (to 26)
32 3 LOAD_GLOBAL 0 (range)
33 6 LOAD_CONST 1 (1)
34
35 %-4d 9 LOAD_CONST 2 (10)
36 12 CALL_FUNCTION 2
37 15 GET_ITER
38 >> 16 FOR_ITER 6 (to 25)
39 19 STORE_FAST 0 (res)
40
41 %-4d 22 JUMP_ABSOLUTE 16
42 >> 25 POP_BLOCK
43 >> 26 LOAD_CONST 0 (None)
44 29 RETURN_VALUE
45"""%(bug708901.func_code.co_firstlineno + 1,
46 bug708901.func_code.co_firstlineno + 2,
47 bug708901.func_code.co_firstlineno + 3)
Skip Montanaroadd0ccc2003-02-27 21:27:07 +000048
Neal Norwitz51abbc72005-12-18 07:06:23 +000049
50def bug1333982(x=[]):
51 assert 0, ([s for s in x] +
52 1)
53 pass
54
55dis_bug1333982 = """\
56 %-4d 0 LOAD_CONST 1 (0)
Jeffrey Yasskin68d68522009-02-28 19:03:21 +000057 3 POP_JUMP_IF_TRUE 38
58 6 LOAD_GLOBAL 0 (AssertionError)
59 9 BUILD_LIST 0
60 12 LOAD_FAST 0 (x)
61 15 GET_ITER
62 >> 16 FOR_ITER 12 (to 31)
63 19 STORE_FAST 1 (s)
64 22 LOAD_FAST 1 (s)
65 25 LIST_APPEND 2
66 28 JUMP_ABSOLUTE 16
Neal Norwitz51abbc72005-12-18 07:06:23 +000067
Jeffrey Yasskin68d68522009-02-28 19:03:21 +000068 %-4d >> 31 LOAD_CONST 2 (1)
69 34 BINARY_ADD
70 35 RAISE_VARARGS 2
Neal Norwitz51abbc72005-12-18 07:06:23 +000071
Jeffrey Yasskin68d68522009-02-28 19:03:21 +000072 %-4d >> 38 LOAD_CONST 0 (None)
73 41 RETURN_VALUE
Neal Norwitz51abbc72005-12-18 07:06:23 +000074"""%(bug1333982.func_code.co_firstlineno + 1,
75 bug1333982.func_code.co_firstlineno + 2,
76 bug1333982.func_code.co_firstlineno + 3)
77
Neal Norwitz84be93b2006-07-16 01:50:38 +000078_BIG_LINENO_FORMAT = """\
79%3d 0 LOAD_GLOBAL 0 (spam)
80 3 POP_TOP
81 4 LOAD_CONST 0 (None)
82 7 RETURN_VALUE
83"""
84
Skip Montanaroadd0ccc2003-02-27 21:27:07 +000085class DisTests(unittest.TestCase):
Michael W. Hudson26848a32003-04-29 17:07:36 +000086 def do_disassembly_test(self, func, expected):
87 s = StringIO.StringIO()
88 save_stdout = sys.stdout
89 sys.stdout = s
90 dis.dis(func)
91 sys.stdout = save_stdout
92 got = s.getvalue()
93 # Trim trailing blanks (if any).
94 lines = got.split('\n')
95 lines = [line.rstrip() for line in lines]
96 expected = expected.split("\n")
97 import difflib
98 if expected != lines:
99 self.fail(
100 "events did not match expectation:\n" +
101 "\n".join(difflib.ndiff(expected,
102 lines)))
103
Skip Montanaroadd0ccc2003-02-27 21:27:07 +0000104 def test_opmap(self):
105 self.assertEqual(dis.opmap["STOP_CODE"], 0)
106 self.assertEqual(dis.opmap["LOAD_CONST"] in dis.hasconst, True)
107 self.assertEqual(dis.opmap["STORE_NAME"] in dis.hasname, True)
108
109 def test_opname(self):
110 self.assertEqual(dis.opname[dis.opmap["LOAD_FAST"]], "LOAD_FAST")
111
112 def test_boundaries(self):
113 self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG)
114 self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT)
115
116 def test_dis(self):
Michael W. Hudson26848a32003-04-29 17:07:36 +0000117 self.do_disassembly_test(_f, dis_f)
118
119 def test_bug_708901(self):
120 self.do_disassembly_test(bug708901, dis_bug708901)
Skip Montanaroadd0ccc2003-02-27 21:27:07 +0000121
Neal Norwitz51abbc72005-12-18 07:06:23 +0000122 def test_bug_1333982(self):
Tim Peters83a8c392005-12-25 22:52:32 +0000123 # This one is checking bytecodes generated for an `assert` statement,
124 # so fails if the tests are run with -O. Skip this test then.
125 if __debug__:
126 self.do_disassembly_test(bug1333982, dis_bug1333982)
Neal Norwitz51abbc72005-12-18 07:06:23 +0000127
Neal Norwitz84be93b2006-07-16 01:50:38 +0000128 def test_big_linenos(self):
129 def func(count):
Tim Peters73a9ead2006-07-18 21:55:15 +0000130 namespace = {}
131 func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
132 exec func in namespace
133 return namespace['foo']
Neal Norwitz84be93b2006-07-16 01:50:38 +0000134
135 # Test all small ranges
136 for i in xrange(1, 300):
137 expected = _BIG_LINENO_FORMAT % (i + 2)
138 self.do_disassembly_test(func(i), expected)
139
140 # Test some larger ranges too
141 for i in xrange(300, 5000, 10):
142 expected = _BIG_LINENO_FORMAT % (i + 2)
143 self.do_disassembly_test(func(i), expected)
144
Skip Montanaroadd0ccc2003-02-27 21:27:07 +0000145def test_main():
146 run_unittest(DisTests)
147
148
149if __name__ == "__main__":
150 test_main()