source: trunk/essentials/dev-lang/python/Lib/test/test_dis.py@ 3951

Last change on this file since 3951 was 3225, checked in by bird, 19 years ago

Python 2.5

File size: 4.7 KB
Line 
1from 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
10def _f(a):
11 print a
12 return 1
13
14dis_f = """\
15 %-4d 0 LOAD_FAST 0 (a)
16 3 PRINT_ITEM
17 4 PRINT_NEWLINE
18
19 %-4d 5 LOAD_CONST 1 (1)
20 8 RETURN_VALUE
21"""%(_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)
48
49
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)
57 3 JUMP_IF_TRUE 41 (to 47)
58 6 POP_TOP
59 7 LOAD_GLOBAL 0 (AssertionError)
60 10 BUILD_LIST 0
61 13 DUP_TOP
62 14 STORE_FAST 1 (_[1])
63 17 LOAD_FAST 0 (x)
64 20 GET_ITER
65 >> 21 FOR_ITER 13 (to 37)
66 24 STORE_FAST 2 (s)
67 27 LOAD_FAST 1 (_[1])
68 30 LOAD_FAST 2 (s)
69 33 LIST_APPEND
70 34 JUMP_ABSOLUTE 21
71 >> 37 DELETE_FAST 1 (_[1])
72
73 %-4d 40 LOAD_CONST 2 (1)
74 43 BINARY_ADD
75 44 RAISE_VARARGS 2
76 >> 47 POP_TOP
77
78 %-4d 48 LOAD_CONST 0 (None)
79 51 RETURN_VALUE
80"""%(bug1333982.func_code.co_firstlineno + 1,
81 bug1333982.func_code.co_firstlineno + 2,
82 bug1333982.func_code.co_firstlineno + 3)
83
84_BIG_LINENO_FORMAT = """\
85%3d 0 LOAD_GLOBAL 0 (spam)
86 3 POP_TOP
87 4 LOAD_CONST 0 (None)
88 7 RETURN_VALUE
89"""
90
91class DisTests(unittest.TestCase):
92 def do_disassembly_test(self, func, expected):
93 s = StringIO.StringIO()
94 save_stdout = sys.stdout
95 sys.stdout = s
96 dis.dis(func)
97 sys.stdout = save_stdout
98 got = s.getvalue()
99 # Trim trailing blanks (if any).
100 lines = got.split('\n')
101 lines = [line.rstrip() for line in lines]
102 expected = expected.split("\n")
103 import difflib
104 if expected != lines:
105 self.fail(
106 "events did not match expectation:\n" +
107 "\n".join(difflib.ndiff(expected,
108 lines)))
109
110 def test_opmap(self):
111 self.assertEqual(dis.opmap["STOP_CODE"], 0)
112 self.assertEqual(dis.opmap["LOAD_CONST"] in dis.hasconst, True)
113 self.assertEqual(dis.opmap["STORE_NAME"] in dis.hasname, True)
114
115 def test_opname(self):
116 self.assertEqual(dis.opname[dis.opmap["LOAD_FAST"]], "LOAD_FAST")
117
118 def test_boundaries(self):
119 self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG)
120 self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT)
121
122 def test_dis(self):
123 self.do_disassembly_test(_f, dis_f)
124
125 def test_bug_708901(self):
126 self.do_disassembly_test(bug708901, dis_bug708901)
127
128 def test_bug_1333982(self):
129 # This one is checking bytecodes generated for an `assert` statement,
130 # so fails if the tests are run with -O. Skip this test then.
131 if __debug__:
132 self.do_disassembly_test(bug1333982, dis_bug1333982)
133
134 def test_big_linenos(self):
135 def func(count):
136 namespace = {}
137 func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
138 exec func in namespace
139 return namespace['foo']
140
141 # Test all small ranges
142 for i in xrange(1, 300):
143 expected = _BIG_LINENO_FORMAT % (i + 2)
144 self.do_disassembly_test(func(i), expected)
145
146 # Test some larger ranges too
147 for i in xrange(300, 5000, 10):
148 expected = _BIG_LINENO_FORMAT % (i + 2)
149 self.do_disassembly_test(func(i), expected)
150
151def test_main():
152 run_unittest(DisTests)
153
154
155if __name__ == "__main__":
156 test_main()
Note: See TracBrowser for help on using the repository browser.