~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Lib/test/test_dis.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Minimal tests for dis module
 
2
 
 
3
from test.support import run_unittest
 
4
import unittest
 
5
import sys
 
6
import dis
 
7
import io
 
8
 
 
9
 
 
10
def _f(a):
 
11
    print(a)
 
12
    return 1
 
13
 
 
14
dis_f = """\
 
15
 %-4d         0 LOAD_GLOBAL              0 (print)
 
16
              3 LOAD_FAST                0 (a)
 
17
              6 CALL_FUNCTION            1
 
18
              9 POP_TOP
 
19
 
 
20
 %-4d        10 LOAD_CONST               1 (1)
 
21
             13 RETURN_VALUE
 
22
"""%(_f.__code__.co_firstlineno + 1,
 
23
     _f.__code__.co_firstlineno + 2)
 
24
 
 
25
 
 
26
def bug708901():
 
27
    for res in range(1,
 
28
                     10):
 
29
        pass
 
30
 
 
31
dis_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.__code__.co_firstlineno + 1,
 
47
     bug708901.__code__.co_firstlineno + 2,
 
48
     bug708901.__code__.co_firstlineno + 3)
 
49
 
 
50
 
 
51
def bug1333982(x=[]):
 
52
    assert 0, ([s for s in x] +
 
53
              1)
 
54
    pass
 
55
 
 
56
dis_bug1333982 = """\
 
57
 %-4d         0 LOAD_CONST               1 (0)
 
58
              3 JUMP_IF_TRUE            33 (to 39)
 
59
              6 POP_TOP
 
60
              7 LOAD_GLOBAL              0 (AssertionError)
 
61
             10 BUILD_LIST               0
 
62
             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
 
69
 
 
70
 %-4d   >>   32 LOAD_CONST               2 (1)
 
71
             35 BINARY_ADD
 
72
             36 RAISE_VARARGS            2
 
73
        >>   39 POP_TOP
 
74
 
 
75
 %-4d        40 LOAD_CONST               0 (None)
 
76
             43 RETURN_VALUE
 
77
"""%(bug1333982.__code__.co_firstlineno + 1,
 
78
     bug1333982.__code__.co_firstlineno + 2,
 
79
     bug1333982.__code__.co_firstlineno + 3)
 
80
 
 
81
_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
 
 
88
dis_module_expected_results = """\
 
89
Disassembly of f:
 
90
  4           0 LOAD_CONST               0 (None)
 
91
              3 RETURN_VALUE
 
92
 
 
93
Disassembly of g:
 
94
  5           0 LOAD_CONST               0 (None)
 
95
              3 RETURN_VALUE
 
96
 
 
97
"""
 
98
 
 
99
 
 
100
class DisTests(unittest.TestCase):
 
101
    def do_disassembly_test(self, func, expected):
 
102
        s = io.StringIO()
 
103
        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
 
 
119
    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):
 
132
        self.do_disassembly_test(_f, dis_f)
 
133
 
 
134
    def test_bug_708901(self):
 
135
        self.do_disassembly_test(bug708901, dis_bug708901)
 
136
 
 
137
    def test_bug_1333982(self):
 
138
        # XXX: re-enable this test!
 
139
        # This one is checking bytecodes generated for an `assert` statement,
 
140
        # so fails if the tests are run with -O.  Skip this test then.
 
141
        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)
 
147
 
 
148
    def test_big_linenos(self):
 
149
        def func(count):
 
150
            namespace = {}
 
151
            func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
 
152
            exec(func, namespace)
 
153
            return namespace['foo']
 
154
 
 
155
        # Test all small ranges
 
156
        for i in range(1, 300):
 
157
            expected = _BIG_LINENO_FORMAT % (i + 2)
 
158
            self.do_disassembly_test(func(i), expected)
 
159
 
 
160
        # Test some larger ranges too
 
161
        for i in range(300, 5000, 10):
 
162
            expected = _BIG_LINENO_FORMAT % (i + 2)
 
163
            self.do_disassembly_test(func(i), expected)
 
164
 
 
165
    def test_big_linenos(self):
 
166
        from test import dis_module
 
167
        self.do_disassembly_test(dis_module, dis_module_expected_results)
 
168
 
 
169
def test_main():
 
170
    run_unittest(DisTests)
 
171
 
 
172
if __name__ == "__main__":
 
173
    test_main()