You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Add uncompyle6 option to show fragments
This commit is contained in:
@@ -95,10 +95,10 @@ x = []
|
||||
------
|
||||
6
|
||||
y = {}
|
||||
--
|
||||
-
|
||||
Contained in...
|
||||
y = {}
|
||||
------
|
||||
--
|
||||
9
|
||||
y = {}
|
||||
-
|
||||
|
@@ -34,6 +34,7 @@ Options:
|
||||
-d print timestamps
|
||||
-p <integer> use <integer> number of processes
|
||||
-r recurse directories looking for .pyc and .pyo files
|
||||
--fragments use fragments deparser
|
||||
--verify compare generated source with input byte-code
|
||||
--verify-run compile generated source, run it and check exit code
|
||||
--weak-verify compile generated source
|
||||
@@ -85,7 +86,7 @@ def main_bin():
|
||||
try:
|
||||
opts, files = getopt.getopt(sys.argv[1:], 'hagtdrVo:c:p:',
|
||||
'help asm grammar linemaps recurse timestamp tree '
|
||||
'verify verify-run version weak-verify '
|
||||
'fragments verify verify-run version weak-verify '
|
||||
'showgrammar'.split(' '))
|
||||
except getopt.GetoptError as e:
|
||||
print('%s: %s' % (os.path.basename(sys.argv[0]), e), file=sys.stderr)
|
||||
@@ -103,6 +104,8 @@ def main_bin():
|
||||
options['do_verify'] = 'strong'
|
||||
elif opt == '--weak-verify':
|
||||
options['do_verify'] = 'weak'
|
||||
elif opt == '--fragments':
|
||||
options['do_fragments'] = True
|
||||
elif opt == '--verify-run':
|
||||
options['do_verify'] = 'verify-run'
|
||||
elif opt == '--linemaps':
|
||||
|
@@ -7,9 +7,10 @@ from uncompyle6.disas import check_object_path
|
||||
from uncompyle6.semantics import pysource
|
||||
from uncompyle6.parser import ParserError
|
||||
from uncompyle6.version import VERSION
|
||||
from uncompyle6.linenumbers import line_number_mapping
|
||||
# from uncompyle6.linenumbers import line_number_mapping
|
||||
|
||||
from uncompyle6.semantics.pysource import deparse_code
|
||||
from uncompyle6.semantics.fragments import deparse_code as deparse_code_fragments
|
||||
from uncompyle6.semantics.linemap import deparse_code_with_map
|
||||
|
||||
from xdis.load import load_module
|
||||
@@ -29,7 +30,7 @@ def decompile(
|
||||
bytecode_version, co, out=None, showasm=None, showast=False,
|
||||
timestamp=None, showgrammar=False, code_objects={},
|
||||
source_size=None, is_pypy=False, magic_int=None,
|
||||
mapstream=None):
|
||||
mapstream=None, do_fragments=False):
|
||||
"""
|
||||
ingests and deparses a given code block 'co'
|
||||
|
||||
@@ -75,9 +76,13 @@ def decompile(
|
||||
sorted(deparsed.source_linemap.keys())]
|
||||
mapstream.write("\n\n# %s\n" % linemap)
|
||||
else:
|
||||
deparsed = deparse_code(bytecode_version, co, out, showasm, showast,
|
||||
showgrammar, code_objects=code_objects,
|
||||
is_pypy=is_pypy)
|
||||
if do_fragments:
|
||||
deparse_fn = deparse_code_fragments
|
||||
else:
|
||||
deparse_fn = deparse_code
|
||||
deparsed = deparse_fn(bytecode_version, co, out, showasm, showast,
|
||||
showgrammar, code_objects=code_objects,
|
||||
is_pypy=is_pypy)
|
||||
pass
|
||||
return deparsed
|
||||
except pysource.SourceWalkerError as e:
|
||||
@@ -85,7 +90,7 @@ def decompile(
|
||||
raise pysource.SourceWalkerError(str(e))
|
||||
|
||||
def decompile_file(filename, outstream=None, showasm=None, showast=False,
|
||||
showgrammar=False, mapstream=None):
|
||||
showgrammar=False, mapstream=None, do_fragments=False):
|
||||
"""
|
||||
decompile Python byte-code file (.pyc). Return objects to
|
||||
all of the deparsed objects found in `filename`.
|
||||
@@ -109,7 +114,7 @@ def decompile_file(filename, outstream=None, showasm=None, showast=False,
|
||||
timestamp, showgrammar,
|
||||
code_objects=code_objects, source_size=source_size,
|
||||
is_pypy=is_pypy, magic_int=magic_int,
|
||||
mapstream=mapstream)]
|
||||
mapstream=mapstream, do_fragments=do_fragments)]
|
||||
co = None
|
||||
return deparsed
|
||||
|
||||
@@ -118,7 +123,7 @@ def decompile_file(filename, outstream=None, showasm=None, showast=False,
|
||||
def main(in_base, out_base, files, codes, outfile=None,
|
||||
showasm=None, showast=False, do_verify=False,
|
||||
showgrammar=False, raise_on_error=False,
|
||||
do_linemaps=False):
|
||||
do_linemaps=False, do_fragments=False):
|
||||
"""
|
||||
in_base base directory for input files
|
||||
out_base base directory for output files (ignored when
|
||||
@@ -189,7 +194,24 @@ def main(in_base, out_base, files, codes, outfile=None,
|
||||
|
||||
# Try to uncompile the input file
|
||||
try:
|
||||
decompile_file(infile, outstream, showasm, showast, showgrammar, linemap_stream)
|
||||
deparsed = decompile_file(infile, outstream, showasm, showast, showgrammar,
|
||||
linemap_stream, do_fragments)
|
||||
if do_fragments:
|
||||
for d in deparsed:
|
||||
last_mod = None
|
||||
offsets = d.offsets
|
||||
for e in sorted(offsets.keys()):
|
||||
if e[0] != last_mod:
|
||||
line = '=' * len(e[0])
|
||||
outstream.write("%s\n%s\n%s\n" % (line, e[0], line))
|
||||
last_mod = e[0]
|
||||
info = offsets[e]
|
||||
extractInfo = d.extract_node_info(info)
|
||||
outstream.write("%s" % info.node.format().strip() + "\n")
|
||||
outstream.write(extractInfo.selectedLine + "\n")
|
||||
outstream.write(extractInfo.markerLine + "\n\n")
|
||||
pass
|
||||
pass
|
||||
tot_files += 1
|
||||
except (ValueError, SyntaxError, ParserError, pysource.SourceWalkerError) as e:
|
||||
sys.stdout.write("\n")
|
||||
|
@@ -1287,6 +1287,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
||||
sep = INDENT_PER_LEVEL[:-1]
|
||||
start = len(self.f.getvalue())
|
||||
self.write('{')
|
||||
self.set_pos_info(node[0], start, start+1)
|
||||
|
||||
if self.version > 3.0:
|
||||
if node[0].kind.startswith('kvlist'):
|
||||
@@ -1355,9 +1356,6 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
||||
sep = line_seperator
|
||||
self.write('}')
|
||||
finish = len(self.f.getvalue())
|
||||
for n in node:
|
||||
n.parent = node
|
||||
self.set_pos_info(n, start, finish)
|
||||
self.set_pos_info(node, start, finish)
|
||||
self.indent_less(INDENT_PER_LEVEL)
|
||||
self.prec = p
|
||||
@@ -1610,7 +1608,8 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
||||
pass
|
||||
|
||||
def deparse_code(version, co, out=StringIO(), showasm=False, showast=False,
|
||||
showgrammar=False, is_pypy=False, walker=FragmentsWalker):
|
||||
showgrammar=False, code_objects={}, compile_mode='exec',
|
||||
is_pypy=False, walker=FragmentsWalker):
|
||||
"""
|
||||
Convert the code object co into a python source fragment.
|
||||
|
||||
@@ -1638,7 +1637,8 @@ def deparse_code(version, co, out=StringIO(), showasm=False, showast=False,
|
||||
# store final output stream for case of error
|
||||
scanner = get_scanner(version, is_pypy=is_pypy)
|
||||
|
||||
tokens, customize = scanner.ingest(co)
|
||||
tokens, customize = scanner.ingest(co, code_objects=code_objects,
|
||||
show_asm=showasm)
|
||||
|
||||
tokens, customize = scanner.ingest(co)
|
||||
maybe_show_asm(showasm, tokens)
|
||||
@@ -1651,7 +1651,8 @@ def deparse_code(version, co, out=StringIO(), showasm=False, showast=False,
|
||||
# Build AST from disassembly.
|
||||
# deparsed = pysource.FragmentsWalker(out, scanner, showast=showast)
|
||||
deparsed = walker(version, scanner, showast=showast,
|
||||
debug_parser=debug_parser)
|
||||
debug_parser=debug_parser, compile_mode=compile_mode,
|
||||
is_pypy=is_pypy)
|
||||
|
||||
deparsed.ast = deparsed.build_ast(tokens, customize)
|
||||
|
||||
|
Reference in New Issue
Block a user