You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Add deparse_code_with_fragments_and_map and simplify
This commit is contained in:
@@ -11,20 +11,14 @@ src_dir = get_srcdir()
|
||||
os.chdir(src_dir)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("test_tuple", "function_to_test"), [
|
||||
(
|
||||
@pytest.mark.parametrize(("test_tuple"), [
|
||||
('../test/bytecode_2.7/05_if.pyc', 'testdata/if-2.7.right',),
|
||||
disassemble_file
|
||||
),
|
||||
(
|
||||
('../test/bytecode_2.7/05_ifelse.pyc', 'testdata/ifelse-2.7.right',),
|
||||
disassemble_file
|
||||
),
|
||||
])
|
||||
def test_funcoutput(capfd, test_tuple, function_to_test):
|
||||
def test_funcoutput(capfd, test_tuple):
|
||||
|
||||
in_file, filename_expected = test_tuple
|
||||
function_to_test(in_file, native=False)
|
||||
disassemble_file(in_file)
|
||||
resout, reserr = capfd.readouterr()
|
||||
expected = open(filename_expected, "r").read()
|
||||
if resout != expected:
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2015-2016 by Rocky Bernstein
|
||||
# Copyright (c) 2015-2016, 2818 by Rocky Bernstein
|
||||
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
|
||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
# Copyright (c) 1999 John Aycock
|
||||
@@ -13,7 +13,7 @@ that is doing the extraction.
|
||||
|
||||
Second, we need structured instruction information for the
|
||||
(de)-parsing step. Python 3.4 and up provides this, but we still do
|
||||
want to run on Python 2.7.
|
||||
want to run on earlier Python versions.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
@@ -23,7 +23,6 @@ from collections import deque
|
||||
|
||||
import uncompyle6
|
||||
|
||||
from xdis.main import disassemble_file as xdisassemble_file
|
||||
from xdis.code import iscode
|
||||
from xdis.load import check_object_path, load_module
|
||||
from uncompyle6.scanner import get_scanner
|
||||
@@ -65,17 +64,13 @@ def disco_loop(disasm, queue, real_out):
|
||||
pass
|
||||
pass
|
||||
|
||||
def disassemble_file(filename, outstream=None, native=False):
|
||||
def disassemble_file(filename, outstream=None):
|
||||
"""
|
||||
disassemble Python byte-code file (.pyc)
|
||||
|
||||
If given a Python source file (".py") file, we'll
|
||||
try to find the corresponding compiled object.
|
||||
"""
|
||||
if native:
|
||||
xdisassemble_file(filename, outstream)
|
||||
return
|
||||
|
||||
filename = check_object_path(filename)
|
||||
(version, timestamp, magic_int, co, is_pypy,
|
||||
source_size) = load_module(filename)
|
||||
@@ -90,14 +85,14 @@ def _test():
|
||||
"""Simple test program to disassemble a file."""
|
||||
argc = len(sys.argv)
|
||||
if argc != 2:
|
||||
if argc == 1 and uncompyle6.PYTHON3:
|
||||
if argc == 1:
|
||||
fn = __file__
|
||||
else:
|
||||
sys.stderr.write("usage: %s [-|CPython compiled file]\n" % __file__)
|
||||
sys.exit(2)
|
||||
else:
|
||||
fn = sys.argv[1]
|
||||
disassemble_file(fn, native=True)
|
||||
disassemble_file(fn)
|
||||
|
||||
if __name__ == "__main__":
|
||||
_test()
|
||||
|
@@ -1643,7 +1643,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
||||
pass
|
||||
|
||||
def deparse_code(version, co, out=StringIO(), showasm=False, showast=False,
|
||||
showgrammar=False, is_pypy=False):
|
||||
showgrammar=False, is_pypy=False, walker=FragmentsWalker):
|
||||
"""
|
||||
Convert the code object co into a python source fragment.
|
||||
|
||||
@@ -1683,7 +1683,8 @@ def deparse_code(version, co, out=StringIO(), showasm=False, showast=False,
|
||||
|
||||
# Build AST from disassembly.
|
||||
# deparsed = pysource.FragmentsWalker(out, scanner, showast=showast)
|
||||
deparsed = FragmentsWalker(version, scanner, showast=showast, debug_parser=debug_parser)
|
||||
deparsed = walker(version, scanner, showast=showast,
|
||||
debug_parser=debug_parser)
|
||||
|
||||
deparsed.ast = deparsed.build_ast(tokens, customize)
|
||||
|
||||
|
@@ -1,10 +1,9 @@
|
||||
# Copyright (c) 2018 by Rocky Bernstein
|
||||
from uncompyle6.semantics.pysource import SourceWalker, deparse_code
|
||||
import uncompyle6.semantics.fragments as fragments
|
||||
|
||||
# FIXME: does this handle nested code, and lambda properly
|
||||
class LineMapWalker(SourceWalker):
|
||||
def __init__(self, *args, **kwargs):
|
||||
if 'first_line' not in kwargs:
|
||||
first_line = 0
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(LineMapWalker, self).__init__(*args, **kwargs)
|
||||
self.source_linemap = {}
|
||||
@@ -28,6 +27,12 @@ class LineMapWalker(SourceWalker):
|
||||
self.source_linemap[self.current_line_number] = node.linestart
|
||||
return super(LineMapWalker, self).default(node)
|
||||
|
||||
class LineMapFragmentWalker(fragments.FragmentsWalker, LineMapWalker):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(LineMapFragmentWalker, self).__init__(*args, **kwargs)
|
||||
self.source_linemap = {}
|
||||
self.current_line_number = 0
|
||||
|
||||
def deparse_code_with_map(*args, **kwargs):
|
||||
"""
|
||||
Like deparse_code but saves line number correspondences.
|
||||
@@ -35,13 +40,21 @@ def deparse_code_with_map(*args, **kwargs):
|
||||
kwargs['walker'] = LineMapWalker
|
||||
return deparse_code(*args, **kwargs)
|
||||
|
||||
def deparse_code_with_fragments_and_map(*args, **kwargs):
|
||||
"""
|
||||
Like deparse_code_with_map but saves fragments.
|
||||
"""
|
||||
kwargs['walker'] = LineMapFragmentWalker
|
||||
return fragments.deparse_code(*args, **kwargs)
|
||||
|
||||
if __name__ == '__main__':
|
||||
def deparse_test(co):
|
||||
"This is a docstring"
|
||||
import sys
|
||||
sys_version = float(sys.version[0:3])
|
||||
# deparsed = deparse_code(sys_version, co, showasm=True, showast=True)
|
||||
deparsed = deparse_code_with_map(sys_version, co, showasm=False, showast=False,
|
||||
deparsed = deparse_code_with_map(sys_version, co, showasm=False,
|
||||
showast=False,
|
||||
showgrammar=False)
|
||||
a = 1; b = 2
|
||||
print("\n")
|
||||
@@ -49,5 +62,16 @@ if __name__ == '__main__':
|
||||
for line_no in
|
||||
sorted(deparsed.source_linemap.keys())]
|
||||
print(linemap)
|
||||
deparsed = deparse_code_with_fragments_and_map(sys_version,
|
||||
co, showasm=False,
|
||||
showast=False,
|
||||
showgrammar=False)
|
||||
a = 1; b = 2
|
||||
print("\n")
|
||||
linemap2 = [(line_no, deparsed.source_linemap[line_no])
|
||||
for line_no in
|
||||
sorted(deparsed.source_linemap.keys())]
|
||||
print(linemap2)
|
||||
assert linemap == linemap2
|
||||
return
|
||||
deparse_test(deparse_test.__code__)
|
||||
|
Reference in New Issue
Block a user