Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 1 | # Minimal tests for dis module |
| 2 | |
Benjamin Peterson | ee8712c | 2008-05-20 21:35:26 +0000 | [diff] [blame] | 3 | from test.support import run_unittest |
Guido van Rossum | d8faa36 | 2007-04-27 19:54:29 +0000 | [diff] [blame] | 4 | import unittest |
Skip Montanaro | add0ccc | 2003-02-27 21:27:07 +0000 | [diff] [blame] | 5 | import sys |
| 6 | import dis |
Guido van Rossum | 34d1928 | 2007-08-09 01:03:29 +0000 | [diff] [blame] | 7 | import io |
Skip Montanaro | add0ccc | 2003-02-27 21:27:07 +0000 | [diff] [blame] | 8 | |
Skip Montanaro | add0ccc | 2003-02-27 21:27:07 +0000 | [diff] [blame] | 9 | |
Skip Montanaro | add0ccc | 2003-02-27 21:27:07 +0000 | [diff] [blame] | 10 | def _f(a): |
Guido van Rossum | be19ed7 | 2007-02-09 05:37:30 +0000 | [diff] [blame] | 11 | print(a) |
Tim Peters | eabafeb | 2003-03-07 15:55:36 +0000 | [diff] [blame] | 12 | return 1 |
Skip Montanaro | add0ccc | 2003-02-27 21:27:07 +0000 | [diff] [blame] | 13 | |
| 14 | dis_f = """\ |
Georg Brandl | 88fc664 | 2007-02-09 21:28:07 +0000 | [diff] [blame] | 15 | %-4d 0 LOAD_GLOBAL 0 (print) |
| 16 | 3 LOAD_FAST 0 (a) |
| 17 | 6 CALL_FUNCTION 1 |
| 18 | 9 POP_TOP |
Skip Montanaro | add0ccc | 2003-02-27 21:27:07 +0000 | [diff] [blame] | 19 | |
Georg Brandl | 88fc664 | 2007-02-09 21:28:07 +0000 | [diff] [blame] | 20 | %-4d 10 LOAD_CONST 1 (1) |
| 21 | 13 RETURN_VALUE |
Neal Norwitz | 221085d | 2007-02-25 20:55:47 +0000 | [diff] [blame] | 22 | """%(_f.__code__.co_firstlineno + 1, |
| 23 | _f.__code__.co_firstlineno + 2) |
Michael W. Hudson | 26848a3 | 2003-04-29 17:07:36 +0000 | [diff] [blame] | 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 |
Neal Norwitz | 221085d | 2007-02-25 20:55:47 +0000 | [diff] [blame] | 46 | """%(bug708901.__code__.co_firstlineno + 1, |
| 47 | bug708901.__code__.co_firstlineno + 2, |
| 48 | bug708901.__code__.co_firstlineno + 3) |
Skip Montanaro | add0ccc | 2003-02-27 21:27:07 +0000 | [diff] [blame] | 49 | |
Neal Norwitz | 51abbc7 | 2005-12-18 07:06:23 +0000 | [diff] [blame] | 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) |
Neal Norwitz | 10be2ea | 2006-03-03 20:29:11 +0000 | [diff] [blame] | 58 | 3 JUMP_IF_TRUE 41 (to 47) |
Neal Norwitz | 51abbc7 | 2005-12-18 07:06:23 +0000 | [diff] [blame] | 59 | 6 POP_TOP |
| 60 | 7 LOAD_GLOBAL 0 (AssertionError) |
| 61 | 10 BUILD_LIST 0 |
| 62 | 13 DUP_TOP |
Neal Norwitz | 10be2ea | 2006-03-03 20:29:11 +0000 | [diff] [blame] | 63 | 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 Norwitz | 51abbc7 | 2005-12-18 07:06:23 +0000 | [diff] [blame] | 73 | |
Neal Norwitz | 10be2ea | 2006-03-03 20:29:11 +0000 | [diff] [blame] | 74 | %-4d 40 LOAD_CONST 2 (1) |
| 75 | 43 BINARY_ADD |
| 76 | 44 RAISE_VARARGS 2 |
| 77 | >> 47 POP_TOP |
Neal Norwitz | 51abbc7 | 2005-12-18 07:06:23 +0000 | [diff] [blame] | 78 | |
Neal Norwitz | 10be2ea | 2006-03-03 20:29:11 +0000 | [diff] [blame] | 79 | %-4d 48 LOAD_CONST 0 (None) |
| 80 | 51 RETURN_VALUE |
Neal Norwitz | 221085d | 2007-02-25 20:55:47 +0000 | [diff] [blame] | 81 | """%(bug1333982.__code__.co_firstlineno + 1, |
| 82 | bug1333982.__code__.co_firstlineno + 2, |
| 83 | bug1333982.__code__.co_firstlineno + 3) |
Neal Norwitz | 51abbc7 | 2005-12-18 07:06:23 +0000 | [diff] [blame] | 84 | |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 85 | _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 | |
Guido van Rossum | e7ba495 | 2007-06-06 23:52:48 +0000 | [diff] [blame] | 92 | dis_module_expected_results = """\ |
| 93 | Disassembly of f: |
| 94 | 4 0 LOAD_CONST 0 (None) |
| 95 | 3 RETURN_VALUE |
| 96 | |
| 97 | Disassembly of g: |
| 98 | 5 0 LOAD_CONST 0 (None) |
| 99 | 3 RETURN_VALUE |
| 100 | |
| 101 | """ |
| 102 | |
| 103 | |
Skip Montanaro | add0ccc | 2003-02-27 21:27:07 +0000 | [diff] [blame] | 104 | class DisTests(unittest.TestCase): |
Michael W. Hudson | 26848a3 | 2003-04-29 17:07:36 +0000 | [diff] [blame] | 105 | def do_disassembly_test(self, func, expected): |
Guido van Rossum | 34d1928 | 2007-08-09 01:03:29 +0000 | [diff] [blame] | 106 | s = io.StringIO() |
Michael W. Hudson | 26848a3 | 2003-04-29 17:07:36 +0000 | [diff] [blame] | 107 | save_stdout = sys.stdout |
| 108 | sys.stdout = s |
| 109 | dis.dis(func) |
| 110 | sys.stdout = save_stdout |
| 111 | got = s.getvalue() |
| 112 | # Trim trailing blanks (if any). |
| 113 | lines = got.split('\n') |
| 114 | lines = [line.rstrip() for line in lines] |
| 115 | expected = expected.split("\n") |
| 116 | import difflib |
| 117 | if expected != lines: |
| 118 | self.fail( |
| 119 | "events did not match expectation:\n" + |
| 120 | "\n".join(difflib.ndiff(expected, |
| 121 | lines))) |
| 122 | |
Skip Montanaro | add0ccc | 2003-02-27 21:27:07 +0000 | [diff] [blame] | 123 | def test_opmap(self): |
| 124 | self.assertEqual(dis.opmap["STOP_CODE"], 0) |
| 125 | self.assertEqual(dis.opmap["LOAD_CONST"] in dis.hasconst, True) |
| 126 | self.assertEqual(dis.opmap["STORE_NAME"] in dis.hasname, True) |
| 127 | |
| 128 | def test_opname(self): |
| 129 | self.assertEqual(dis.opname[dis.opmap["LOAD_FAST"]], "LOAD_FAST") |
| 130 | |
| 131 | def test_boundaries(self): |
| 132 | self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG) |
| 133 | self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT) |
| 134 | |
| 135 | def test_dis(self): |
Michael W. Hudson | 26848a3 | 2003-04-29 17:07:36 +0000 | [diff] [blame] | 136 | self.do_disassembly_test(_f, dis_f) |
| 137 | |
| 138 | def test_bug_708901(self): |
| 139 | self.do_disassembly_test(bug708901, dis_bug708901) |
Skip Montanaro | add0ccc | 2003-02-27 21:27:07 +0000 | [diff] [blame] | 140 | |
Neal Norwitz | 51abbc7 | 2005-12-18 07:06:23 +0000 | [diff] [blame] | 141 | def test_bug_1333982(self): |
Guido van Rossum | e7ba495 | 2007-06-06 23:52:48 +0000 | [diff] [blame] | 142 | # XXX: re-enable this test! |
Tim Peters | 83a8c39 | 2005-12-25 22:52:32 +0000 | [diff] [blame] | 143 | # This one is checking bytecodes generated for an `assert` statement, |
| 144 | # so fails if the tests are run with -O. Skip this test then. |
Nick Coghlan | 650f0d0 | 2007-04-15 12:05:43 +0000 | [diff] [blame] | 145 | pass # Test has been disabled due to change in the way |
| 146 | # list comps are handled. The byte code now includes |
| 147 | # a memory address and a file location, so they change from |
| 148 | # run to run. |
| 149 | # if __debug__: |
| 150 | # self.do_disassembly_test(bug1333982, dis_bug1333982) |
Neal Norwitz | 51abbc7 | 2005-12-18 07:06:23 +0000 | [diff] [blame] | 151 | |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 152 | def test_big_linenos(self): |
| 153 | def func(count): |
| 154 | namespace = {} |
| 155 | func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"]) |
Georg Brandl | 7cae87c | 2006-09-06 06:51:57 +0000 | [diff] [blame] | 156 | exec(func, namespace) |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 157 | return namespace['foo'] |
| 158 | |
| 159 | # Test all small ranges |
Guido van Rossum | 805365e | 2007-05-07 22:24:25 +0000 | [diff] [blame] | 160 | for i in range(1, 300): |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 161 | expected = _BIG_LINENO_FORMAT % (i + 2) |
| 162 | self.do_disassembly_test(func(i), expected) |
| 163 | |
| 164 | # Test some larger ranges too |
Guido van Rossum | 805365e | 2007-05-07 22:24:25 +0000 | [diff] [blame] | 165 | for i in range(300, 5000, 10): |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 166 | expected = _BIG_LINENO_FORMAT % (i + 2) |
| 167 | self.do_disassembly_test(func(i), expected) |
| 168 | |
Guido van Rossum | e7ba495 | 2007-06-06 23:52:48 +0000 | [diff] [blame] | 169 | def test_big_linenos(self): |
| 170 | from test import dis_module |
| 171 | self.do_disassembly_test(dis_module, dis_module_expected_results) |
| 172 | |
Skip Montanaro | add0ccc | 2003-02-27 21:27:07 +0000 | [diff] [blame] | 173 | def test_main(): |
| 174 | run_unittest(DisTests) |
| 175 | |
Skip Montanaro | add0ccc | 2003-02-27 21:27:07 +0000 | [diff] [blame] | 176 | if __name__ == "__main__": |
| 177 | test_main() |