mirror of
https://github.com/python/cpython.git
synced 2025-12-04 08:34:25 +00:00
improve dis test coverage (closes #11559)
Thanks Matias Bordese. (a few modifications of my own)
This commit is contained in:
parent
2ef76981a0
commit
d6afe724cb
2 changed files with 99 additions and 8 deletions
|
|
@ -1,11 +1,35 @@
|
||||||
# Minimal tests for dis module
|
# Minimal tests for dis module
|
||||||
|
|
||||||
from test.support import run_unittest, captured_stdout
|
from test.support import run_unittest, captured_stdout
|
||||||
|
import difflib
|
||||||
import unittest
|
import unittest
|
||||||
import sys
|
import sys
|
||||||
import dis
|
import dis
|
||||||
import io
|
import io
|
||||||
|
|
||||||
|
class _C:
|
||||||
|
def __init__(self, x):
|
||||||
|
self.x = x == 1
|
||||||
|
|
||||||
|
dis_c_instance_method = """\
|
||||||
|
%-4d 0 LOAD_FAST 1 (x)
|
||||||
|
3 LOAD_CONST 1 (1)
|
||||||
|
6 COMPARE_OP 2 (==)
|
||||||
|
9 LOAD_FAST 0 (self)
|
||||||
|
12 STORE_ATTR 0 (x)
|
||||||
|
15 LOAD_CONST 0 (None)
|
||||||
|
18 RETURN_VALUE
|
||||||
|
""" % (_C.__init__.__code__.co_firstlineno + 1,)
|
||||||
|
|
||||||
|
dis_c_instance_method_bytes = """\
|
||||||
|
0 LOAD_FAST 1 (1)
|
||||||
|
3 LOAD_CONST 1 (1)
|
||||||
|
6 COMPARE_OP 2 (==)
|
||||||
|
9 LOAD_FAST 0 (0)
|
||||||
|
12 STORE_ATTR 0 (0)
|
||||||
|
15 LOAD_CONST 0 (0)
|
||||||
|
18 RETURN_VALUE
|
||||||
|
"""
|
||||||
|
|
||||||
def _f(a):
|
def _f(a):
|
||||||
print(a)
|
print(a)
|
||||||
|
|
@ -23,6 +47,16 @@ dis_f = """\
|
||||||
_f.__code__.co_firstlineno + 2)
|
_f.__code__.co_firstlineno + 2)
|
||||||
|
|
||||||
|
|
||||||
|
dis_f_co_code = """\
|
||||||
|
0 LOAD_GLOBAL 0 (0)
|
||||||
|
3 LOAD_FAST 0 (0)
|
||||||
|
6 CALL_FUNCTION 1
|
||||||
|
9 POP_TOP
|
||||||
|
10 LOAD_CONST 1 (1)
|
||||||
|
13 RETURN_VALUE
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def bug708901():
|
def bug708901():
|
||||||
for res in range(1,
|
for res in range(1,
|
||||||
10):
|
10):
|
||||||
|
|
@ -138,18 +172,27 @@ dis_compound_stmt_str = """\
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class DisTests(unittest.TestCase):
|
class DisTests(unittest.TestCase):
|
||||||
def do_disassembly_test(self, func, expected):
|
|
||||||
|
def get_disassembly(self, func, lasti=-1, wrapper=True):
|
||||||
s = io.StringIO()
|
s = io.StringIO()
|
||||||
save_stdout = sys.stdout
|
save_stdout = sys.stdout
|
||||||
sys.stdout = s
|
sys.stdout = s
|
||||||
|
try:
|
||||||
|
if wrapper:
|
||||||
dis.dis(func)
|
dis.dis(func)
|
||||||
|
else:
|
||||||
|
dis.disassemble(func, lasti)
|
||||||
|
finally:
|
||||||
sys.stdout = save_stdout
|
sys.stdout = save_stdout
|
||||||
got = s.getvalue()
|
|
||||||
# Trim trailing blanks (if any).
|
# Trim trailing blanks (if any).
|
||||||
lines = got.split('\n')
|
return [line.rstrip() for line in s.getvalue().splitlines()]
|
||||||
lines = [line.rstrip() for line in lines]
|
|
||||||
expected = expected.split("\n")
|
def get_disassemble_as_string(self, func, lasti=-1):
|
||||||
import difflib
|
return '\n'.join(self.get_disassembly(func, lasti, False))
|
||||||
|
|
||||||
|
def do_disassembly_test(self, func, expected):
|
||||||
|
lines = self.get_disassembly(func)
|
||||||
|
expected = expected.splitlines()
|
||||||
if expected != lines:
|
if expected != lines:
|
||||||
self.fail(
|
self.fail(
|
||||||
"events did not match expectation:\n" +
|
"events did not match expectation:\n" +
|
||||||
|
|
@ -211,6 +254,46 @@ class DisTests(unittest.TestCase):
|
||||||
self.do_disassembly_test(simple_stmt_str, dis_simple_stmt_str)
|
self.do_disassembly_test(simple_stmt_str, dis_simple_stmt_str)
|
||||||
self.do_disassembly_test(compound_stmt_str, dis_compound_stmt_str)
|
self.do_disassembly_test(compound_stmt_str, dis_compound_stmt_str)
|
||||||
|
|
||||||
|
def test_disassemble_bytes(self):
|
||||||
|
self.do_disassembly_test(_f.__code__.co_code, dis_f_co_code)
|
||||||
|
|
||||||
|
def test_disassemble_method(self):
|
||||||
|
self.do_disassembly_test(_C(1).__init__, dis_c_instance_method)
|
||||||
|
|
||||||
|
def test_disassemble_method_bytes(self):
|
||||||
|
method_bytecode = _C(1).__init__.__code__.co_code
|
||||||
|
self.do_disassembly_test(method_bytecode, dis_c_instance_method_bytes)
|
||||||
|
|
||||||
|
def test_dis_none(self):
|
||||||
|
self.assertRaises(RuntimeError, dis.dis, None)
|
||||||
|
|
||||||
|
def test_dis_object(self):
|
||||||
|
self.assertRaises(TypeError, dis.dis, object())
|
||||||
|
|
||||||
|
def test_dis_traceback(self):
|
||||||
|
not_defined = object()
|
||||||
|
tb = None
|
||||||
|
old = getattr(sys, 'last_traceback', not_defined)
|
||||||
|
|
||||||
|
def cleanup():
|
||||||
|
if old != not_defined:
|
||||||
|
sys.last_traceback = old
|
||||||
|
else:
|
||||||
|
del sys.last_traceback
|
||||||
|
|
||||||
|
try:
|
||||||
|
1/0
|
||||||
|
except Exception as e:
|
||||||
|
tb = e.__traceback__
|
||||||
|
sys.last_traceback = tb
|
||||||
|
self.addCleanup(cleanup)
|
||||||
|
|
||||||
|
tb_dis = self.get_disassemble_as_string(tb.tb_frame.f_code, tb.tb_lasti)
|
||||||
|
self.do_disassembly_test(None, tb_dis)
|
||||||
|
|
||||||
|
def test_dis_object(self):
|
||||||
|
self.assertRaises(TypeError, dis.dis, object())
|
||||||
|
|
||||||
code_info_code_info = """\
|
code_info_code_info = """\
|
||||||
Name: code_info
|
Name: code_info
|
||||||
Filename: (.*)
|
Filename: (.*)
|
||||||
|
|
@ -363,6 +446,13 @@ class CodeInfoTests(unittest.TestCase):
|
||||||
dis.show_code(x)
|
dis.show_code(x)
|
||||||
self.assertRegex(output.getvalue(), expected+"\n")
|
self.assertRegex(output.getvalue(), expected+"\n")
|
||||||
|
|
||||||
|
def test_code_info_object(self):
|
||||||
|
self.assertRaises(TypeError, dis.code_info, object())
|
||||||
|
|
||||||
|
def test_pretty_flags_no_flags(self):
|
||||||
|
self.assertEqual(dis.pretty_flags(0), '0x0')
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
run_unittest(DisTests, CodeInfoTests)
|
run_unittest(DisTests, CodeInfoTests)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ David Bolen
|
||||||
Forest Bond
|
Forest Bond
|
||||||
Gawain Bolton
|
Gawain Bolton
|
||||||
Gregory Bond
|
Gregory Bond
|
||||||
|
Matias Bordese
|
||||||
Jurjen Bos
|
Jurjen Bos
|
||||||
Peter Bosch
|
Peter Bosch
|
||||||
Eric Bouck
|
Eric Bouck
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue