blob: d82dc5a1e2fb0cdce77e40aaf61c09ef7ff8d480 [file] [log] [blame]
Guido van Rossumd8faa362007-04-27 19:54:29 +00001# Minimal tests for dis module
2
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003from test.support import run_unittest
Guido van Rossumd8faa362007-04-27 19:54:29 +00004import unittest
Skip Montanaroadd0ccc2003-02-27 21:27:07 +00005import sys
6import dis
Guido van Rossum34d19282007-08-09 01:03:29 +00007import io
Skip Montanaroadd0ccc2003-02-27 21:27:07 +00008
Skip Montanaroadd0ccc2003-02-27 21:27:07 +00009
Skip Montanaroadd0ccc2003-02-27 21:27:07 +000010def _f(a):
Guido van Rossumbe19ed72007-02-09 05:37:30 +000011 print(a)
Tim Peterseabafeb2003-03-07 15:55:36 +000012 return 1
Skip Montanaroadd0ccc2003-02-27 21:27:07 +000013
14dis_f = """\
Georg Brandl88fc6642007-02-09 21:28:07 +000015 %-4d 0 LOAD_GLOBAL 0 (print)
16 3 LOAD_FAST 0 (a)
17 6 CALL_FUNCTION 1
18 9 POP_TOP
Skip Montanaroadd0ccc2003-02-27 21:27:07 +000019
Georg Brandl88fc6642007-02-09 21:28:07 +000020 %-4d 10 LOAD_CONST 1 (1)
21 13 RETURN_VALUE
Neal Norwitz221085d2007-02-25 20:55:47 +000022"""%(_f.__code__.co_firstlineno + 1,
23 _f.__code__.co_firstlineno + 2)
Michael W. Hudson26848a32003-04-29 17:07:36 +000024
25
26def bug708901():
27 for res in range(1,
28 10):
29 pass
30
31dis_bug708901 = """\
32 %-4d 0 SETUP_LOOP 23 (to 26)
33 3 LOAD_GLOBAL 0 (range)
34 6 LOAD_CONST 1 (1)
35
36 %-4d 9 LOAD_CONST 2 (10)
37 12 CALL_FUNCTION 2
38 15 GET_ITER
39 >> 16 FOR_ITER 6 (to 25)
40 19 STORE_FAST 0 (res)
41
42 %-4d 22 JUMP_ABSOLUTE 16
43 >> 25 POP_BLOCK
44 >> 26 LOAD_CONST 0 (None)
45 29 RETURN_VALUE
Neal Norwitz221085d2007-02-25 20:55:47 +000046"""%(bug708901.__code__.co_firstlineno + 1,
47 bug708901.__code__.co_firstlineno + 2,
48 bug708901.__code__.co_firstlineno + 3)
Skip Montanaroadd0ccc2003-02-27 21:27:07 +000049
Neal Norwitz51abbc72005-12-18 07:06:23 +000050
51def bug1333982(x=[]):
52 assert 0, ([s for s in x] +
53 1)
54 pass
55
56dis_bug1333982 = """\
57 %-4d 0 LOAD_CONST 1 (0)
Antoine Pitrouf289ae62008-12-18 11:06:25 +000058 3 JUMP_IF_TRUE 33 (to 39)
Neal Norwitz51abbc72005-12-18 07:06:23 +000059 6 POP_TOP
60 7 LOAD_GLOBAL 0 (AssertionError)
61 10 BUILD_LIST 0
Antoine Pitrouf289ae62008-12-18 11:06:25 +000062 13 LOAD_FAST 0 (x)
63 16 GET_ITER
64 >> 17 FOR_ITER 12 (to 32)
65 20 STORE_FAST 1 (s)
66 23 LOAD_FAST 1 (s)
67 26 LIST_APPEND 2
68 29 JUMP_ABSOLUTE 17
Neal Norwitz51abbc72005-12-18 07:06:23 +000069
Antoine Pitrouf289ae62008-12-18 11:06:25 +000070 %-4d >> 32 LOAD_CONST 2 (1)
71 35 BINARY_ADD
72 36 RAISE_VARARGS 2
73 >> 39 POP_TOP
Neal Norwitz51abbc72005-12-18 07:06:23 +000074
Antoine Pitrouf289ae62008-12-18 11:06:25 +000075 %-4d 40 LOAD_CONST 0 (None)
76 43 RETURN_VALUE
Neal Norwitz221085d2007-02-25 20:55:47 +000077"""%(bug1333982.__code__.co_firstlineno + 1,
78 bug1333982.__code__.co_firstlineno + 2,
79 bug1333982.__code__.co_firstlineno + 3)
Neal Norwitz51abbc72005-12-18 07:06:23 +000080
Thomas Wouters0e3f5912006-08-11 14:57:12 +000081_BIG_LINENO_FORMAT = """\
82%3d 0 LOAD_GLOBAL 0 (spam)
83 3 POP_TOP
84 4 LOAD_CONST 0 (None)
85 7 RETURN_VALUE
86"""
87
Guido van Rossume7ba4952007-06-06 23:52:48 +000088dis_module_expected_results = """\
89Disassembly of f:
90 4 0 LOAD_CONST 0 (None)
91 3 RETURN_VALUE
92
93Disassembly of g:
94 5 0 LOAD_CONST 0 (None)
95 3 RETURN_VALUE
96
97"""
98
99
Skip Montanaroadd0ccc2003-02-27 21:27:07 +0000100class DisTests(unittest.TestCase):
Michael W. Hudson26848a32003-04-29 17:07:36 +0000101 def do_disassembly_test(self, func, expected):
Guido van Rossum34d19282007-08-09 01:03:29 +0000102 s = io.StringIO()
Michael W. Hudson26848a32003-04-29 17:07:36 +0000103 save_stdout = sys.stdout
104 sys.stdout = s
105 dis.dis(func)
106 sys.stdout = save_stdout
107 got = s.getvalue()
108 # Trim trailing blanks (if any).
109 lines = got.split('\n')
110 lines = [line.rstrip() for line in lines]
111 expected = expected.split("\n")
112 import difflib
113 if expected != lines:
114 self.fail(
115 "events did not match expectation:\n" +
116 "\n".join(difflib.ndiff(expected,
117 lines)))
118
Skip Montanaroadd0ccc2003-02-27 21:27:07 +0000119 def test_opmap(self):
120 self.assertEqual(dis.opmap["STOP_CODE"], 0)
121 self.assertEqual(dis.opmap["LOAD_CONST"] in dis.hasconst, True)
122 self.assertEqual(dis.opmap["STORE_NAME"] in dis.hasname, True)
123
124 def test_opname(self):
125 self.assertEqual(dis.opname[dis.opmap["LOAD_FAST"]], "LOAD_FAST")
126
127 def test_boundaries(self):
128 self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG)
129 self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT)
130
131 def test_dis(self):
Michael W. Hudson26848a32003-04-29 17:07:36 +0000132 self.do_disassembly_test(_f, dis_f)
133
134 def test_bug_708901(self):
135 self.do_disassembly_test(bug708901, dis_bug708901)
Skip Montanaroadd0ccc2003-02-27 21:27:07 +0000136
Neal Norwitz51abbc72005-12-18 07:06:23 +0000137 def test_bug_1333982(self):
Guido van Rossume7ba4952007-06-06 23:52:48 +0000138 # XXX: re-enable this test!
Tim Peters83a8c392005-12-25 22:52:32 +0000139 # This one is checking bytecodes generated for an `assert` statement,
140 # so fails if the tests are run with -O. Skip this test then.
Nick Coghlan650f0d02007-04-15 12:05:43 +0000141 pass # Test has been disabled due to change in the way
142 # list comps are handled. The byte code now includes
143 # a memory address and a file location, so they change from
144 # run to run.
145 # if __debug__:
146 # self.do_disassembly_test(bug1333982, dis_bug1333982)
Neal Norwitz51abbc72005-12-18 07:06:23 +0000147
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000148 def test_big_linenos(self):
149 def func(count):
150 namespace = {}
151 func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
Georg Brandl7cae87c2006-09-06 06:51:57 +0000152 exec(func, namespace)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000153 return namespace['foo']
154
155 # Test all small ranges
Guido van Rossum805365e2007-05-07 22:24:25 +0000156 for i in range(1, 300):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000157 expected = _BIG_LINENO_FORMAT % (i + 2)
158 self.do_disassembly_test(func(i), expected)
159
160 # Test some larger ranges too
Guido van Rossum805365e2007-05-07 22:24:25 +0000161 for i in range(300, 5000, 10):
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000162 expected = _BIG_LINENO_FORMAT % (i + 2)
163 self.do_disassembly_test(func(i), expected)
164
Guido van Rossume7ba4952007-06-06 23:52:48 +0000165 def test_big_linenos(self):
166 from test import dis_module
167 self.do_disassembly_test(dis_module, dis_module_expected_results)
168
Skip Montanaroadd0ccc2003-02-27 21:27:07 +0000169def test_main():
170 run_unittest(DisTests)
171
Skip Montanaroadd0ccc2003-02-27 21:27:07 +0000172if __name__ == "__main__":
173 test_main()