mirror of
https://github.com/python/cpython.git
synced 2025-08-03 00:23:06 +00:00
This commit is contained in:
parent
00d60623e9
commit
8bf5b89212
3 changed files with 95 additions and 4 deletions
|
@ -4,15 +4,19 @@ import contextlib
|
|||
import dis
|
||||
import functools
|
||||
import io
|
||||
import itertools
|
||||
import opcode
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
import textwrap
|
||||
import types
|
||||
import unittest
|
||||
from test.support import (captured_stdout, requires_debug_ranges,
|
||||
requires_specialization, cpython_only)
|
||||
requires_specialization, cpython_only,
|
||||
os_helper)
|
||||
from test.support.bytecode_helper import BytecodeTestCase
|
||||
|
||||
import opcode
|
||||
|
||||
CACHE = dis.opmap["CACHE"]
|
||||
|
||||
|
@ -2281,5 +2285,91 @@ def _unroll_caches_as_Instructions(instrs, show_caches=False):
|
|||
False, None, None, instr.positions)
|
||||
|
||||
|
||||
class TestDisCLI(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.filename = tempfile.mktemp()
|
||||
self.addCleanup(os_helper.unlink, self.filename)
|
||||
|
||||
@staticmethod
|
||||
def text_normalize(string):
|
||||
"""Dedent *string* and strip it from its surrounding whitespaces.
|
||||
|
||||
This method is used by the other utility functions so that any
|
||||
string to write or to match against can be freely indented.
|
||||
"""
|
||||
return textwrap.dedent(string).strip()
|
||||
|
||||
def set_source(self, content):
|
||||
with open(self.filename, 'w') as fp:
|
||||
fp.write(self.text_normalize(content))
|
||||
|
||||
def invoke_dis(self, *flags):
|
||||
output = io.StringIO()
|
||||
with contextlib.redirect_stdout(output):
|
||||
dis.main(args=[*flags, self.filename])
|
||||
return self.text_normalize(output.getvalue())
|
||||
|
||||
def check_output(self, source, expect, *flags):
|
||||
with self.subTest(source=source, flags=flags):
|
||||
self.set_source(source)
|
||||
res = self.invoke_dis(*flags)
|
||||
expect = self.text_normalize(expect)
|
||||
self.assertListEqual(res.splitlines(), expect.splitlines())
|
||||
|
||||
def test_invocation(self):
|
||||
# test various combinations of parameters
|
||||
base_flags = [
|
||||
('-C', '--show-caches'),
|
||||
('-O', '--show-offsets'),
|
||||
]
|
||||
|
||||
self.set_source('''
|
||||
def f():
|
||||
print(x)
|
||||
return None
|
||||
''')
|
||||
|
||||
for r in range(1, len(base_flags) + 1):
|
||||
for choices in itertools.combinations(base_flags, r=r):
|
||||
for args in itertools.product(*choices):
|
||||
with self.subTest(args=args[1:]):
|
||||
_ = self.invoke_dis(*args)
|
||||
|
||||
with self.assertRaises(SystemExit):
|
||||
# suppress argparse error message
|
||||
with contextlib.redirect_stderr(io.StringIO()):
|
||||
_ = self.invoke_dis('--unknown')
|
||||
|
||||
def test_show_cache(self):
|
||||
# test 'python -m dis -C/--show-caches'
|
||||
source = 'print()'
|
||||
expect = '''
|
||||
0 RESUME 0
|
||||
|
||||
1 LOAD_NAME 0 (print)
|
||||
PUSH_NULL
|
||||
CALL 0
|
||||
CACHE 0 (counter: 0)
|
||||
CACHE 0 (func_version: 0)
|
||||
CACHE 0
|
||||
POP_TOP
|
||||
RETURN_CONST 0 (None)
|
||||
'''
|
||||
for flag in ['-C', '--show-caches']:
|
||||
self.check_output(source, expect, flag)
|
||||
|
||||
def test_show_offsets(self):
|
||||
# test 'python -m dis -O/--show-offsets'
|
||||
source = 'pass'
|
||||
expect = '''
|
||||
0 0 RESUME 0
|
||||
|
||||
1 2 RETURN_CONST 0 (None)
|
||||
'''
|
||||
for flag in ['-O', '--show-offsets']:
|
||||
self.check_output(source, expect, flag)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue