PageRenderTime 40ms CodeModel.GetById 28ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/test/test_dis.py

http://unladen-swallow.googlecode.com/
Python | 153 lines | 148 code | 4 blank | 1 comment | 1 complexity | 44ef5c06fbb78ddeed50655d9bc71376 MD5 | raw file
  1# Minimal tests for dis module
  2
  3from test.test_support import run_unittest
  4import unittest
  5import sys
  6import dis
  7import StringIO
  8
  9
 10def _f(a):
 11    print a
 12    return 1
 13
 14dis_f = """\
 15 %-4d         0 LOAD_GLOBAL              0 (#@print_stmt)
 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.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 LOAD_GLOBAL              0 (range)
 33              3 LOAD_CONST               1 (1)
 34
 35 %-4d         6 LOAD_CONST               2 (10)
 36              9 CALL_FUNCTION            2
 37             12 GET_ITER
 38        >>   13 FOR_ITER                 6 (to 22)
 39             16 STORE_FAST               0 (res)
 40
 41 %-4d        19 JUMP_ABSOLUTE           13
 42        >>   22 LOAD_CONST               0 (None)
 43             25 RETURN_VALUE
 44"""%(bug708901.func_code.co_firstlineno + 1,
 45     bug708901.func_code.co_firstlineno + 2,
 46     bug708901.func_code.co_firstlineno + 3)
 47
 48
 49def bug1333982(x=[]):
 50    assert 0, ([s for s in x] +
 51              1)
 52    pass
 53
 54dis_bug1333982 = """\
 55 %-4d         0 LOAD_CONST               1 (0)
 56              3 POP_JUMP_IF_TRUE        44
 57              6 LOAD_GLOBAL              0 (AssertionError)
 58              9 BUILD_LIST               0
 59             12 DUP_TOP
 60             13 STORE_FAST               1 (_[1])
 61             16 LOAD_FAST                0 (x)
 62             19 GET_ITER
 63        >>   20 FOR_ITER                13 (to 36)
 64             23 STORE_FAST               2 (s)
 65             26 LOAD_FAST                1 (_[1])
 66             29 LOAD_FAST                2 (s)
 67             32 LIST_APPEND
 68             33 JUMP_ABSOLUTE           20
 69        >>   36 DELETE_FAST              1 (_[1])
 70
 71 %-4d        39 LOAD_CONST               2 (1)
 72             42 BINARY_ADD
 73             43 RAISE_VARARGS_TWO
 74
 75 %-4d   >>   44 LOAD_CONST               0 (None)
 76             47 RETURN_VALUE
 77"""%(bug1333982.func_code.co_firstlineno + 1,
 78     bug1333982.func_code.co_firstlineno + 2,
 79     bug1333982.func_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
 88class DisTests(unittest.TestCase):
 89    def do_disassembly_test(self, func, expected):
 90        s = StringIO.StringIO()
 91        save_stdout = sys.stdout
 92        sys.stdout = s
 93        dis.dis(func)
 94        sys.stdout = save_stdout
 95        got = s.getvalue()
 96        # Trim trailing blanks (if any).
 97        lines = got.split('\n')
 98        lines = [line.rstrip() for line in lines]
 99        expected = expected.split("\n")
100        import difflib
101        if expected != lines:
102            self.fail(
103                "events did not match expectation:\n" +
104                "\n".join(difflib.ndiff(expected,
105                                        lines)))
106
107    def test_opmap(self):
108        self.assertEqual(dis.opmap["STOP_CODE"], 0)
109        self.assertEqual(dis.opmap["LOAD_CONST"] in dis.hasconst, True)
110        self.assertEqual(dis.opmap["STORE_NAME"] in dis.hasname, True)
111
112    def test_opname(self):
113        self.assertEqual(dis.opname[dis.opmap["LOAD_FAST"]], "LOAD_FAST")
114
115    def test_boundaries(self):
116        self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG)
117        self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT)
118
119    def test_dis(self):
120        self.do_disassembly_test(_f, dis_f)
121
122    def test_bug_708901(self):
123        self.do_disassembly_test(bug708901, dis_bug708901)
124
125    def test_bug_1333982(self):
126        # This one is checking bytecodes generated for an `assert` statement,
127        # so fails if the tests are run with -O.  Skip this test then.
128        if __debug__:
129            self.do_disassembly_test(bug1333982, dis_bug1333982)
130
131    def test_big_linenos(self):
132        def func(count):
133            namespace = {}
134            func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
135            exec func in namespace
136            return namespace['foo']
137
138        # Test all small ranges
139        for i in xrange(1, 300):
140            expected = _BIG_LINENO_FORMAT % (i + 2)
141            self.do_disassembly_test(func(i), expected)
142
143        # Test some larger ranges too
144        for i in xrange(300, 5000, 10):
145            expected = _BIG_LINENO_FORMAT % (i + 2)
146            self.do_disassembly_test(func(i), expected)
147
148def test_main():
149    run_unittest(DisTests)
150
151
152if __name__ == "__main__":
153    test_main()