mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2024-11-23 13:09:49 +00:00
Propagate show_asm debug option down to functions
This commit is contained in:
parent
ed5346e526
commit
16c900ff1d
@ -264,7 +264,7 @@ See Also
|
||||
|
||||
|
||||
.. _Cython: https://en.wikipedia.org/wiki/Cython
|
||||
.. _trepan: https://pypi.python.org/pypi/trepan2g
|
||||
.. _trepan: https://pypi.python.org/pypi/trepan3k
|
||||
.. _compiler: https://pypi.python.org/pypi/spark_parser
|
||||
.. _HISTORY: https://github.com/rocky/python-uncompyle6/blob/master/HISTORY.md
|
||||
.. _debuggers: https://pypi.python.org/pypi/trepan3k
|
||||
|
@ -92,11 +92,11 @@ class Code(object):
|
||||
the diassembled code is stored in the attribute '_tokens'.
|
||||
"""
|
||||
|
||||
def __init__(self, co, scanner, classname=None):
|
||||
def __init__(self, co, scanner, classname=None, show_asm=None):
|
||||
for i in dir(co):
|
||||
if i.startswith("co_"):
|
||||
setattr(self, i, getattr(co, i))
|
||||
self._tokens, self._customize = scanner.ingest(co, classname)
|
||||
self._tokens, self._customize = scanner.ingest(co, classname, show_asm=show_asm)
|
||||
|
||||
|
||||
class Scanner(object):
|
||||
|
@ -194,6 +194,7 @@ class Scanner37Base(Scanner):
|
||||
Also, when we encounter certain tokens, we add them to a set which will cause custom
|
||||
grammar rules. Specifically, variable arg tokens like MAKE_FUNCTION or BUILD_LIST
|
||||
cause specific rules for the specific number of arguments they take.
|
||||
|
||||
"""
|
||||
|
||||
def tokens_append(j, token):
|
||||
@ -455,7 +456,7 @@ class Scanner37Base(Scanner):
|
||||
# as CONTINUE, but that's okay since we add a grammar
|
||||
# rule for that.
|
||||
pattr = argval
|
||||
target = self.get_target(inst.offset)
|
||||
target = inst.argval
|
||||
if target <= inst.offset:
|
||||
next_opname = self.insts[i + 1].opname
|
||||
|
||||
|
@ -84,12 +84,15 @@ def customize_for_version3(self, version):
|
||||
"""List comprehensions in Python 3 when handled as a closure.
|
||||
See if we can combine code.
|
||||
"""
|
||||
|
||||
# FIXME: DRY with comprehension_walk_newer
|
||||
p = self.prec
|
||||
self.prec = 27
|
||||
|
||||
code_obj = node[1].attr
|
||||
assert iscode(code_obj)
|
||||
code = Code(code_obj, self.scanner, self.currentclass)
|
||||
assert iscode(code_obj), node[1]
|
||||
code = Code(code_obj, self.scanner, self.currentclass, self.debug_opts["asm"])
|
||||
|
||||
ast = self.build_ast(code._tokens, code._customize, code)
|
||||
self.customize(code._customize)
|
||||
|
||||
@ -103,6 +106,10 @@ def customize_for_version3(self, version):
|
||||
|
||||
n = ast[1]
|
||||
|
||||
# Pick out important parts of the comprehension:
|
||||
# * the variables we iterate over: "stores"
|
||||
# * the results we accumulate: "n"
|
||||
|
||||
# collections is the name of the expression(s) we are iterating over
|
||||
collections = [node[-3]]
|
||||
list_ifs = []
|
||||
|
@ -1149,13 +1149,15 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
||||
|
||||
n_classdefdeco2 = n_classdef
|
||||
|
||||
def gen_source(self, ast, name, customize, is_lambda=False, returnNone=False):
|
||||
def gen_source(self, ast, name, customize, is_lambda=False, returnNone=False,
|
||||
debug_opts=None):
|
||||
"""convert parse tree to Python source code"""
|
||||
|
||||
rn = self.return_none
|
||||
self.return_none = returnNone
|
||||
old_name = self.name
|
||||
self.name = name
|
||||
self.debug_opts = debug_opts
|
||||
# if code would be empty, append 'pass'
|
||||
if len(ast) == 0:
|
||||
self.println(self.indent, "pass")
|
||||
|
@ -659,7 +659,12 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
|
||||
has_none = "None" in code.co_names
|
||||
rn = has_none and not find_none(ast)
|
||||
self.gen_source(
|
||||
ast, code.co_name, scanner_code._customize, is_lambda=is_lambda, returnNone=rn
|
||||
ast,
|
||||
code.co_name,
|
||||
scanner_code._customize,
|
||||
is_lambda=is_lambda,
|
||||
returnNone=rn,
|
||||
debug_opts=self.debug_opts,
|
||||
)
|
||||
|
||||
# In obscure cases, a function may be a generator but the "yield"
|
||||
|
@ -38,7 +38,7 @@ from uncompyle6.show import maybe_show_tree_param_default
|
||||
|
||||
def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
||||
"""Dump function definition, doc string, and function body in
|
||||
Python version 3.6 and above.
|
||||
Python version 3.6 and above.
|
||||
"""
|
||||
# MAKE_CLOSURE adds an additional closure slot
|
||||
|
||||
@ -51,8 +51,8 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
||||
|
||||
def build_param(ast, name, default, annotation=None):
|
||||
"""build parameters:
|
||||
- handle defaults
|
||||
- handle format tuple parameters
|
||||
- handle defaults
|
||||
- handle format tuple parameters
|
||||
"""
|
||||
value = default
|
||||
maybe_show_tree_param_default(self.showast, name, value)
|
||||
@ -124,8 +124,6 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
||||
kw_node = node[pos_args]
|
||||
if kw_node == "expr":
|
||||
kw_node = kw_node[0]
|
||||
if kw_node == "dict":
|
||||
kw_pairs = kw_node[-1].attr
|
||||
|
||||
defparams = []
|
||||
# FIXME: DRY with code below
|
||||
@ -150,7 +148,8 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
||||
code = code_node.attr
|
||||
|
||||
assert iscode(code)
|
||||
scanner_code = Code(code, self.scanner, self.currentclass)
|
||||
debug_opts = self.debug_opts["asm"] if self.debug_opts else None
|
||||
scanner_code = Code(code, self.scanner, self.currentclass, debug_opts)
|
||||
|
||||
# add defaults values to parameter names
|
||||
argc = code.co_argcount
|
||||
@ -347,7 +346,12 @@ def make_function36(self, node, is_lambda, nested=1, code_node=None):
|
||||
has_none = "None" in code.co_names
|
||||
rn = has_none and not find_none(ast)
|
||||
self.gen_source(
|
||||
ast, code.co_name, scanner_code._customize, is_lambda=is_lambda, returnNone=rn
|
||||
ast,
|
||||
code.co_name,
|
||||
scanner_code._customize,
|
||||
is_lambda=is_lambda,
|
||||
returnNone=rn,
|
||||
debug_opts=self.debug_opts,
|
||||
)
|
||||
|
||||
# In obscure cases, a function may be a generator but the "yield"
|
||||
|
@ -182,6 +182,7 @@ from uncompyle6.semantics.consts import (
|
||||
from uncompyle6.show import maybe_show_tree
|
||||
from uncompyle6.util import better_repr
|
||||
|
||||
DEFAULT_DEBUG_OPTS = {"asm": False, "tree": False, "grammar": False}
|
||||
|
||||
def unicode(x): return x
|
||||
from io import StringIO
|
||||
@ -648,7 +649,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
attr = node.attr
|
||||
data = node.pattr
|
||||
datatype = type(data)
|
||||
if isinstance(data, float) :
|
||||
if isinstance(data, float):
|
||||
self.write(better_repr(data, self.version))
|
||||
elif isinstance(data, complex):
|
||||
self.write(better_repr(data, self.version))
|
||||
@ -1179,10 +1180,11 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
"""
|
||||
p = self.prec
|
||||
self.prec = 27
|
||||
code = node[code_index].attr
|
||||
|
||||
assert iscode(code), node[code_index]
|
||||
code = Code(code, self.scanner, self.currentclass)
|
||||
code_obj = node[code_index].attr
|
||||
assert iscode(code_obj), node[code_index]
|
||||
|
||||
code = Code(code_obj, self.scanner, self.currentclass, self.debug_opts["asm"])
|
||||
|
||||
ast = self.build_ast(code._tokens, code._customize, code)
|
||||
self.customize(code._customize)
|
||||
@ -2426,13 +2428,22 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
|
||||
self.classes.pop(-1)
|
||||
|
||||
def gen_source(self, ast, name, customize, is_lambda=False, returnNone=False):
|
||||
def gen_source(
|
||||
self,
|
||||
ast,
|
||||
name,
|
||||
customize,
|
||||
is_lambda=False,
|
||||
returnNone=False,
|
||||
debug_opts=DEFAULT_DEBUG_OPTS,
|
||||
):
|
||||
"""convert SyntaxTree to Python source code"""
|
||||
|
||||
rn = self.return_none
|
||||
self.return_none = returnNone
|
||||
old_name = self.name
|
||||
self.name = name
|
||||
self.debug_opts = debug_opts
|
||||
# if code would be empty, append 'pass'
|
||||
if len(ast) == 0:
|
||||
self.println(self.indent, "pass")
|
||||
@ -2525,10 +2536,6 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
return MAP.get(node, MAP_DIRECT)
|
||||
|
||||
|
||||
#
|
||||
DEFAULT_DEBUG_OPTS = {"asm": False, "tree": False, "grammar": False}
|
||||
|
||||
|
||||
def code_deparse(
|
||||
co,
|
||||
out=sys.stdout,
|
||||
@ -2623,7 +2630,9 @@ def code_deparse(
|
||||
)
|
||||
|
||||
# What we've been waiting for: Generate source from Syntax Tree!
|
||||
deparsed.gen_source(deparsed.ast, co.co_name, customize)
|
||||
deparsed.gen_source(
|
||||
deparsed.ast, name=co.co_name, customize=customize, debug_opts=debug_opts
|
||||
)
|
||||
|
||||
for g in sorted(deparsed.mod_globs):
|
||||
deparsed.write("# global %s ## Warning: Unused global\n" % g)
|
||||
|
Loading…
Reference in New Issue
Block a user