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