blob: ab70778b321d95de2a5aa926981b1f93353da81e [file] [log] [blame]
Skip Montanaroadd0ccc2003-02-27 21:27:07 +00001from test.test_support import verify, verbose, TestFailed, run_unittest
2import sys
3import dis
4import StringIO
5
6# Minimal tests for dis module
7
8import unittest
9
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
Michael W. Hudson26848a32003-04-29 17:07:36 +000022"""%(_f.func_code.co_firstlineno + 1,
23 _f.func_code.co_firstlineno + 2)
24
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
46"""%(bug708901.func_code.co_firstlineno + 1,
47 bug708901.func_code.co_firstlineno + 2,
48 bug708901.func_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)
Neal Norwitz10be2ea2006-03-03 20:29:11 +000058 3 JUMP_IF_TRUE 41 (to 47)
Neal Norwitz51abbc72005-12-18 07:06:23 +000059 6 POP_TOP
60 7 LOAD_GLOBAL 0 (AssertionError)
61 10 BUILD_LIST 0
62 13 DUP_TOP
Neal Norwitz10be2ea2006-03-03 20:29:11 +000063 14 STORE_FAST 1 (_[1])
64 17 LOAD_FAST 0 (x)
65 20 GET_ITER
66 >> 21 FOR_ITER 13 (to 37)
67 24 STORE_FAST 2 (s)
68 27 LOAD_FAST 1 (_[1])
69 30 LOAD_FAST 2 (s)
70 33 LIST_APPEND
71 34 JUMP_ABSOLUTE 21
72 >> 37 DELETE_FAST 1 (_[1])
Neal Norwitz51abbc72005-12-18 07:06:23 +000073
Neal Norwitz10be2ea2006-03-03 20:29:11 +000074 %-4d 40 LOAD_CONST 2 (1)
75 43 BINARY_ADD
76 44 RAISE_VARARGS 2
77 >> 47 POP_TOP
Neal Norwitz51abbc72005-12-18 07:06:23 +000078
Neal Norwitz10be2ea2006-03-03 20:29:11 +000079 %-4d 48 LOAD_CONST 0 (None)
80 51 RETURN_VALUE
Neal Norwitz51abbc72005-12-18 07:06:23 +000081"""%(bug1333982.func_code.co_firstlineno + 1,
82 bug1333982.func_code.co_firstlineno + 2,
83 bug1333982.func_code.co_firstlineno + 3)
84
Thomas Wouters0e3f5912006-08-11 14:57:12 +000085_BIG_LINENO_FORMAT = """\
86%3d 0 LOAD_GLOBAL 0 (spam)
87 3 POP_TOP
88 4 LOAD_CONST 0 (None)
89 7 RETURN_VALUE
90"""
91
Skip Montanaroadd0ccc2003-02-27 21:27:07 +000092class DisTests(unittest.TestCase):
Michael W. Hudson26848a32003-04-29 17:07:36 +000093 def do_disassembly_test(self, func, expected):
94 s = StringIO.StringIO()
95 save_stdout = sys.stdout
96 sys.stdout = s
97 dis.dis(func)
98 sys.stdout = save_stdout
99 got = s.getvalue()
100 # Trim trailing blanks (if any).
101 lines = got.split('\n')
102 lines = [line.rstrip() for line in lines]
103 expected = expected.split("\n")
104 import difflib
105 if expected != lines:
106 self.fail(
107 "events did not match expectation:\n" +
108 "\n".join(difflib.ndiff(expected,
109 lines)))
110
Skip Montanaroadd0ccc2003-02-27 21:27:07 +0000111 def test_opmap(self):
112 self.assertEqual(dis.opmap["STOP_CODE"], 0)
113 self.assertEqual(dis.opmap["LOAD_CONST"] in dis.hasconst, True)
114 self.assertEqual(dis.opmap["STORE_NAME"] in dis.hasname, True)
115
116 def test_opname(self):
117 self.assertEqual(dis.opname[dis.opmap["LOAD_FAST"]], "LOAD_FAST")
118
119 def test_boundaries(self):
120 self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG)
121 self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT)
122
123 def test_dis(self):
Michael W. Hudson26848a32003-04-29 17:07:36 +0000124 self.do_disassembly_test(_f, dis_f)
125
126 def test_bug_708901(self):
127 self.do_disassembly_test(bug708901, dis_bug708901)
Skip Montanaroadd0ccc2003-02-27 21:27:07 +0000128
Neal Norwitz51abbc72005-12-18 07:06:23 +0000129 def test_bug_1333982(self):
Tim Peters83a8c392005-12-25 22:52:32 +0000130 # This one is checking bytecodes generated for an `assert` statement,
131 # so fails if the tests are run with -O. Skip this test then.
132 if __debug__:
133 self.do_disassembly_test(bug1333982, dis_bug1333982)
Neal Norwitz51abbc72005-12-18 07:06:23 +0000134
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000135 def test_big_linenos(self):
136 def func(count):
137 namespace = {}
138 func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
Georg Brandl7cae87c2006-09-06 06:51:57 +0000139 exec(func, namespace)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000140 return namespace['foo']
141
142 # Test all small ranges
143 for i in xrange(1, 300):
144 expected = _BIG_LINENO_FORMAT % (i + 2)
145 self.do_disassembly_test(func(i), expected)
146
147 # Test some larger ranges too
148 for i in xrange(300, 5000, 10):
149 expected = _BIG_LINENO_FORMAT % (i + 2)
150 self.do_disassembly_test(func(i), expected)
151
Skip Montanaroadd0ccc2003-02-27 21:27:07 +0000152def test_main():
153 run_unittest(DisTests)
154
155
156if __name__ == "__main__":
157 test_main()