You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
lint
This commit is contained in:
@@ -90,7 +90,7 @@ def decompile(
|
||||
run_pypy_str = "PyPy " if IS_PYPY else ""
|
||||
sys_version_lines = sys.version.split("\n")
|
||||
if source_encoding:
|
||||
write("# -*- coding: %s -*-" % source_encoding)
|
||||
write(f"# -*- coding: {source_encoding} -*-")
|
||||
write(
|
||||
"# uncompyle6 version %s\n"
|
||||
"# %sPython bytecode version base %s%s\n# Decompiled from: %sPython %s"
|
||||
@@ -104,9 +104,9 @@ def decompile(
|
||||
)
|
||||
)
|
||||
if co.co_filename:
|
||||
write("# Embedded file name: %s" % co.co_filename)
|
||||
write(f"# Embedded file name: {co.co_filename}")
|
||||
if timestamp:
|
||||
write("# Compiled at: %s" % datetime.datetime.fromtimestamp(timestamp))
|
||||
write(f"# Compiled at: {datetime.datetime.fromtimestamp(timestamp)}")
|
||||
if source_size:
|
||||
write("# Size of source mod 2**32: %d bytes" % source_size)
|
||||
|
||||
@@ -129,13 +129,14 @@ def decompile(
|
||||
version=bytecode_version,
|
||||
code_objects=code_objects,
|
||||
is_pypy=is_pypy,
|
||||
debug_opts=debug_opts,
|
||||
)
|
||||
header_count = 3 + len(sys_version_lines)
|
||||
linemap = [
|
||||
(line_no, deparsed.source_linemap[line_no] + header_count)
|
||||
for line_no in sorted(deparsed.source_linemap.keys())
|
||||
]
|
||||
mapstream.write("\n\n# %s\n" % linemap)
|
||||
mapstream.write(f"\n\n# {linemap}\n")
|
||||
else:
|
||||
if do_fragments:
|
||||
deparse_fn = code_deparse_fragments
|
||||
@@ -163,11 +164,11 @@ def compile_file(source_path: str) -> str:
|
||||
basename = source_path
|
||||
|
||||
if hasattr(sys, "pypy_version_info"):
|
||||
bytecode_path = "%s-pypy%s.pyc" % (basename, version_tuple_to_str())
|
||||
bytecode_path = f"{basename}-pypy{version_tuple_to_str()}.pyc"
|
||||
else:
|
||||
bytecode_path = "%s-%s.pyc" % (basename, version_tuple_to_str())
|
||||
bytecode_path = f"{basename}-{version_tuple_to_str()}.pyc"
|
||||
|
||||
print("compiling %s to %s" % (source_path, bytecode_path))
|
||||
print(f"compiling {source_path} to {bytecode_path}")
|
||||
py_compile.compile(source_path, bytecode_path, "exec")
|
||||
return bytecode_path
|
||||
|
||||
@@ -232,7 +233,6 @@ def decompile_file(
|
||||
compile_mode="exec",
|
||||
)
|
||||
]
|
||||
co = None
|
||||
return deparsed
|
||||
|
||||
|
||||
@@ -245,7 +245,6 @@ def main(
|
||||
outfile=None,
|
||||
showasm: Optional[str] = None,
|
||||
showast={},
|
||||
do_verify=False,
|
||||
showgrammar=False,
|
||||
source_encoding=None,
|
||||
raise_on_error=False,
|
||||
@@ -274,7 +273,7 @@ def main(
|
||||
infile = os.path.join(in_base, filename)
|
||||
# print("XXX", infile)
|
||||
if not os.path.exists(infile):
|
||||
sys.stderr.write("File '%s' doesn't exist. Skipped\n" % infile)
|
||||
sys.stderr.write(f"File '{infile}' doesn't exist. Skipped\n")
|
||||
continue
|
||||
|
||||
if do_linemaps:
|
||||
@@ -322,13 +321,13 @@ def main(
|
||||
):
|
||||
if e[0] != last_mod:
|
||||
line = "=" * len(e[0])
|
||||
outstream.write("%s\n%s\n%s\n" % (line, e[0], line))
|
||||
outstream.write(f"{line}\n{e[0]}\n{line}\n")
|
||||
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")
|
||||
extract_info = d.extract_node_info(info)
|
||||
outstream.write(f"{info.node.format().strip()}" + "\n")
|
||||
outstream.write(extract_info.selectedLine + "\n")
|
||||
outstream.write(extract_info.markerLine + "\n\n")
|
||||
pass
|
||||
pass
|
||||
tot_files += 1
|
||||
@@ -349,14 +348,14 @@ def main(
|
||||
if str(e).startswith("Unsupported Python"):
|
||||
sys.stdout.write("\n")
|
||||
sys.stderr.write(
|
||||
"\n# Unsupported bytecode in file %s\n# %s\n" % (infile, e)
|
||||
f"\n# Unsupported bytecode in file {infile}\n# {e}\n"
|
||||
)
|
||||
else:
|
||||
if outfile:
|
||||
outstream.close()
|
||||
os.remove(outfile)
|
||||
sys.stdout.write("\n")
|
||||
sys.stderr.write("\nLast file: %s " % (infile))
|
||||
sys.stderr.write(f"\nLast file: {infile} ")
|
||||
raise
|
||||
|
||||
# except:
|
||||
@@ -376,7 +375,7 @@ def main(
|
||||
okay_files += 1
|
||||
if not current_outfile:
|
||||
mess = "\n# okay decompiling"
|
||||
# mem_usage = __memUsage()
|
||||
# mem_usage = __mem_usage()
|
||||
print(mess, infile)
|
||||
if current_outfile:
|
||||
sys.stdout.write(
|
||||
@@ -384,7 +383,6 @@ def main(
|
||||
% (
|
||||
infile,
|
||||
status_msg(
|
||||
do_verify,
|
||||
tot_files,
|
||||
okay_files,
|
||||
failed_files,
|
||||
@@ -405,14 +403,14 @@ def main(
|
||||
except Exception:
|
||||
pass
|
||||
pass
|
||||
return (tot_files, okay_files, failed_files, verify_failed_files)
|
||||
return tot_files, okay_files, failed_files, verify_failed_files
|
||||
|
||||
|
||||
# ---- main ----
|
||||
|
||||
if sys.platform.startswith("linux") and os.uname()[2][:2] in ["2.", "3.", "4."]:
|
||||
|
||||
def __memUsage():
|
||||
def __mem_sage():
|
||||
mi = open("/proc/self/stat", "r")
|
||||
mu = mi.readline().split()[22]
|
||||
mi.close()
|
||||
@@ -420,11 +418,11 @@ if sys.platform.startswith("linux") and os.uname()[2][:2] in ["2.", "3.", "4."]:
|
||||
|
||||
else:
|
||||
|
||||
def __memUsage():
|
||||
def __mem_usage():
|
||||
return ""
|
||||
|
||||
|
||||
def status_msg(do_verify, tot_files, okay_files, failed_files, verify_failed_files):
|
||||
def status_msg(tot_files, okay_files, failed_files, verify_failed_files):
|
||||
if tot_files == 1:
|
||||
if failed_files:
|
||||
return "\n# decompile failed"
|
||||
|
@@ -1,5 +1,6 @@
|
||||
# Copyright (c) 2018, 2024 by Rocky Bernstein
|
||||
#
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
@@ -13,7 +14,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from uncompyle6.semantics.fragments import FragmentsWalker, code_deparse as fragments_code_deparse
|
||||
from uncompyle6.semantics.fragments import (
|
||||
FragmentsWalker,
|
||||
code_deparse as fragments_code_deparse,
|
||||
)
|
||||
from uncompyle6.semantics.pysource import SourceWalker, code_deparse
|
||||
|
||||
|
||||
@@ -25,9 +29,9 @@ class LineMapWalker(SourceWalker):
|
||||
self.current_line_number = 1
|
||||
|
||||
def write(self, *data):
|
||||
"""Augment write routine to keep track of current line"""
|
||||
"""Augment write routine to keep track of current line."""
|
||||
for line in data:
|
||||
## print("XXX write: '%s'" % l)
|
||||
# print(f"XXX write: '{line}'")
|
||||
for i in str(line):
|
||||
if i == "\n":
|
||||
self.current_line_number += 1
|
||||
@@ -39,7 +43,7 @@ class LineMapWalker(SourceWalker):
|
||||
# Note n_expr needs treatment too
|
||||
|
||||
def default(self, node):
|
||||
"""Augment write default routine to record line number changes"""
|
||||
"""Augment default-write routine to record line number changes."""
|
||||
if hasattr(node, "linestart"):
|
||||
if node.linestart:
|
||||
self.source_linemap[self.current_line_number] = node.linestart
|
||||
@@ -85,7 +89,7 @@ def code_deparse_with_fragments_and_map(*args, **kwargs):
|
||||
if __name__ == "__main__":
|
||||
|
||||
def deparse_test(co):
|
||||
"This is a docstring"
|
||||
"""This is a docstring"""
|
||||
deparsed = code_deparse_with_map(co)
|
||||
a = 1
|
||||
b = 2
|
||||
|
@@ -141,17 +141,25 @@ from uncompyle6.parsers.treenode import SyntaxTree
|
||||
from uncompyle6.scanner import Code, get_scanner
|
||||
from uncompyle6.scanners.tok import Token
|
||||
from uncompyle6.semantics.check_ast import checker
|
||||
from uncompyle6.semantics.consts import (ASSIGN_TUPLE_PARAM,
|
||||
INDENT_PER_LEVEL, LINE_LENGTH, MAP,
|
||||
MAP_DIRECT, NAME_MODULE, NONE, PASS,
|
||||
PRECEDENCE, RETURN_LOCALS,
|
||||
RETURN_NONE, TAB, TABLE_R, escape)
|
||||
from uncompyle6.semantics.consts import (
|
||||
ASSIGN_TUPLE_PARAM,
|
||||
INDENT_PER_LEVEL,
|
||||
LINE_LENGTH,
|
||||
MAP,
|
||||
MAP_DIRECT,
|
||||
NAME_MODULE,
|
||||
NONE,
|
||||
PASS,
|
||||
PRECEDENCE,
|
||||
RETURN_LOCALS,
|
||||
RETURN_NONE,
|
||||
TAB,
|
||||
TABLE_R,
|
||||
escape,
|
||||
)
|
||||
from uncompyle6.semantics.customize import customize_for_version
|
||||
from uncompyle6.semantics.gencomp import ComprehensionMixin
|
||||
from uncompyle6.semantics.helper import (
|
||||
find_globals_and_nonlocals,
|
||||
print_docstring
|
||||
)
|
||||
from uncompyle6.semantics.helper import find_globals_and_nonlocals, print_docstring
|
||||
from uncompyle6.semantics.make_function1 import make_function1
|
||||
from uncompyle6.semantics.make_function2 import make_function2
|
||||
from uncompyle6.semantics.make_function3 import make_function3
|
||||
@@ -162,9 +170,11 @@ from uncompyle6.semantics.transform import TreeTransform, is_docstring
|
||||
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
|
||||
def unicode(x):
|
||||
return x
|
||||
|
||||
|
||||
from io import StringIO
|
||||
|
||||
PARSER_DEFAULT_DEBUG = {
|
||||
@@ -200,6 +210,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
Class to traverses a Parse Tree of the bytecode instruction built from parsing to produce some sort of source text.
|
||||
The Parse tree may be turned an Abstract Syntax tree as an intermediate step.
|
||||
"""
|
||||
|
||||
stacked_params = ("f", "indent", "is_lambda", "_globals")
|
||||
|
||||
def __init__(
|
||||
@@ -288,7 +299,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
self.in_format_string = None
|
||||
|
||||
# hide_internal suppresses displaying the additional instructions that sometimes
|
||||
# exist in code but but were not written in the source code.
|
||||
# exist in code but were not written in the source code.
|
||||
# An example is:
|
||||
# __module__ = __name__
|
||||
self.hide_internal = True
|
||||
@@ -355,7 +366,6 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
indent += " "
|
||||
i = 0
|
||||
for node in ast:
|
||||
|
||||
if hasattr(node, "__repr1__"):
|
||||
if enumerate_children:
|
||||
child = self.str_with_template1(node, indent, i)
|
||||
@@ -375,9 +385,9 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
i += 1
|
||||
return rv
|
||||
|
||||
def indent_if_source_nl(self, line_number, indent):
|
||||
def indent_if_source_nl(self, line_number: int, indent: int):
|
||||
if line_number != self.line_number:
|
||||
self.write("\n" + self.indent + INDENT_PER_LEVEL[:-1])
|
||||
self.write("\n" + indent + INDENT_PER_LEVEL[:-1])
|
||||
return self.line_number
|
||||
|
||||
f = property(
|
||||
@@ -685,7 +695,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
|
||||
def template_engine(self, entry, startnode):
|
||||
"""The format template interpretation engine. See the comment at the
|
||||
beginning of this module for the how we interpret format
|
||||
beginning of this module for how we interpret format
|
||||
specifications such as %c, %C, and so on.
|
||||
"""
|
||||
|
||||
@@ -729,20 +739,31 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
if isinstance(index[1], str):
|
||||
# if node[index[0]] != index[1]:
|
||||
# from trepan.api import debug; debug()
|
||||
assert node[index[0]] == index[1], (
|
||||
"at %s[%d], expected '%s' node; got '%s'"
|
||||
% (node.kind, arg, index[1], node[index[0]].kind,)
|
||||
assert (
|
||||
node[index[0]] == index[1]
|
||||
), "at %s[%d], expected '%s' node; got '%s'" % (
|
||||
node.kind,
|
||||
arg,
|
||||
index[1],
|
||||
node[index[0]].kind,
|
||||
)
|
||||
else:
|
||||
assert node[index[0]] in index[1], (
|
||||
"at %s[%d], expected to be in '%s' node; got '%s'"
|
||||
% (node.kind, arg, index[1], node[index[0]].kind,)
|
||||
assert (
|
||||
node[index[0]] in index[1]
|
||||
), "at %s[%d], expected to be in '%s' node; got '%s'" % (
|
||||
node.kind,
|
||||
arg,
|
||||
index[1],
|
||||
node[index[0]].kind,
|
||||
)
|
||||
|
||||
index = index[0]
|
||||
assert isinstance(index, int), (
|
||||
"at %s[%d], %s should be int or tuple"
|
||||
% (node.kind, arg, type(index),)
|
||||
assert isinstance(
|
||||
index, int
|
||||
), "at %s[%d], %s should be int or tuple" % (
|
||||
node.kind,
|
||||
arg,
|
||||
type(index),
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -765,14 +786,22 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
if len(tup) == 3:
|
||||
(index, nonterm_name, self.prec) = tup
|
||||
if isinstance(tup[1], str):
|
||||
assert node[index] == nonterm_name, (
|
||||
"at %s[%d], expected '%s' node; got '%s'"
|
||||
% (node.kind, arg, nonterm_name, node[index].kind,)
|
||||
assert (
|
||||
node[index] == nonterm_name
|
||||
), "at %s[%d], expected '%s' node; got '%s'" % (
|
||||
node.kind,
|
||||
arg,
|
||||
nonterm_name,
|
||||
node[index].kind,
|
||||
)
|
||||
else:
|
||||
assert node[tup[0]] in tup[1], (
|
||||
"at %s[%d], expected to be in '%s' node; got '%s'"
|
||||
% (node.kind, arg, index[1], node[index[0]].kind,)
|
||||
assert (
|
||||
node[tup[0]] in tup[1]
|
||||
), "at %s[%d], expected to be in '%s' node; got '%s'" % (
|
||||
node.kind,
|
||||
arg,
|
||||
index[1],
|
||||
node[index[0]].kind,
|
||||
)
|
||||
|
||||
else:
|
||||
@@ -885,52 +914,51 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
"CALL_FUNCTION_VAR_KW",
|
||||
"CALL_FUNCTION_KW",
|
||||
):
|
||||
|
||||
# FIXME: handle everything in customize.
|
||||
# Right now, some of this is here, and some in that.
|
||||
|
||||
if v == 0:
|
||||
str = "%c(%C" # '%C' is a dummy here ...
|
||||
p2 = (0, 0, None) # .. because of the None in this
|
||||
template_str = "%c(%C" # '%C' is a dummy here ...
|
||||
p2 = (0, 0, None) # because of the None in this
|
||||
else:
|
||||
str = "%c(%C, "
|
||||
template_str = "%c(%C, "
|
||||
p2 = (1, -2, ", ")
|
||||
if op == "CALL_FUNCTION_VAR":
|
||||
# Python 3.5 only puts optional args (the VAR part)
|
||||
# the lowest down the stack
|
||||
if self.version == (3, 5):
|
||||
if str == "%c(%C, ":
|
||||
if template_str == "%c(%C, ":
|
||||
entry = ("%c(*%C, %c)", 0, p2, -2)
|
||||
elif str == "%c(%C":
|
||||
elif template_str == "%c(%C":
|
||||
entry = ("%c(*%C)", 0, (1, 100, ""))
|
||||
elif self.version == (3, 4):
|
||||
# CALL_FUNCTION_VAR's top element of the stack contains
|
||||
# the variable argument list
|
||||
if v == 0:
|
||||
str = "%c(*%c)"
|
||||
entry = (str, 0, -2)
|
||||
template_str = "%c(*%c)"
|
||||
entry = (template_str, 0, -2)
|
||||
else:
|
||||
str = "%c(%C, *%c)"
|
||||
entry = (str, 0, p2, -2)
|
||||
template_str = "%c(%C, *%c)"
|
||||
entry = (template_str, 0, p2, -2)
|
||||
else:
|
||||
str += "*%c)"
|
||||
entry = (str, 0, p2, -2)
|
||||
template_str += "*%c)"
|
||||
entry = (template_str, 0, p2, -2)
|
||||
elif op == "CALL_FUNCTION_KW":
|
||||
str += "**%c)"
|
||||
entry = (str, 0, p2, -2)
|
||||
template_str += "**%c)"
|
||||
entry = (template_str, 0, p2, -2)
|
||||
elif op == "CALL_FUNCTION_VAR_KW":
|
||||
str += "*%c, **%c)"
|
||||
template_str += "*%c, **%c)"
|
||||
# Python 3.5 only puts optional args (the VAR part)
|
||||
# the lowest down the stack
|
||||
na = v & 0xFF # positional parameters
|
||||
if self.version == (3, 5) and na == 0:
|
||||
if p2[2]:
|
||||
p2 = (2, -2, ", ")
|
||||
entry = (str, 0, p2, 1, -2)
|
||||
entry = (template_str, 0, p2, 1, -2)
|
||||
else:
|
||||
if p2[2]:
|
||||
p2 = (1, -3, ", ")
|
||||
entry = (str, 0, p2, -3, -2)
|
||||
entry = (template_str, 0, p2, -3, -2)
|
||||
pass
|
||||
else:
|
||||
assert False, "Unhandled CALL_FUNCTION %s" % op
|
||||
@@ -1014,7 +1042,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
if ast[0] == "sstmt":
|
||||
ast[0] = ast[0][0]
|
||||
first_stmt = ast[0]
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
@@ -1023,7 +1051,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
del ast[0]
|
||||
first_stmt = ast[0]
|
||||
pass
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
have_qualname = False
|
||||
@@ -1035,17 +1063,15 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
if self.version < (3, 0):
|
||||
# Should we ditch this in favor of the "else" case?
|
||||
qualname = ".".join(self.classes)
|
||||
QUAL_NAME = SyntaxTree(
|
||||
qual_name_tree = SyntaxTree(
|
||||
"assign",
|
||||
[
|
||||
SyntaxTree("expr", [Token("LOAD_CONST", pattr=qualname)]),
|
||||
SyntaxTree(
|
||||
"store", [Token("STORE_NAME", pattr="__qualname__")]
|
||||
),
|
||||
SyntaxTree("store", [Token("STORE_NAME", pattr="__qualname__")]),
|
||||
],
|
||||
)
|
||||
# FIXME: is this right now that we've redone the grammar?
|
||||
have_qualname = ast[0] == QUAL_NAME
|
||||
have_qualname = ast[0] == qual_name_tree
|
||||
else:
|
||||
# Python 3.4+ has constants like 'cmp_to_key.<locals>.K'
|
||||
# which are not simple classes like the < 3 case.
|
||||
@@ -1057,7 +1083,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
and first_stmt[1][0] == Token("STORE_NAME", pattr="__qualname__")
|
||||
):
|
||||
have_qualname = True
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if have_qualname:
|
||||
@@ -1078,7 +1104,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
try:
|
||||
# FIXME: Is there an extra [0]?
|
||||
docstring = ast[i][0][0][0][0].pattr
|
||||
except:
|
||||
except Exception:
|
||||
docstring = code.co_consts[0]
|
||||
if print_docstring(self, indent, docstring):
|
||||
self.println()
|
||||
@@ -1104,7 +1130,6 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
# else:
|
||||
# print stmt[-1]
|
||||
|
||||
|
||||
globals, nonlocals = find_globals_and_nonlocals(
|
||||
ast, set(), set(), code, self.version
|
||||
)
|
||||
@@ -1148,7 +1173,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
else:
|
||||
self.customize(customize)
|
||||
self.text = self.traverse(ast, is_lambda=is_lambda)
|
||||
# In a formatted string using "lambda', we should not add "\n".
|
||||
# In a formatted string using "lambda", we should not add "\n".
|
||||
# For example in:
|
||||
# f'{(lambda x:x)("8")!r}'
|
||||
# Adding a "\n" after "lambda x: x" will give an error message:
|
||||
@@ -1167,7 +1192,6 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
noneInNames=False,
|
||||
is_top_level_module=False,
|
||||
):
|
||||
|
||||
# FIXME: DRY with fragments.py
|
||||
|
||||
# assert isinstance(tokens[0], Token)
|
||||
@@ -1298,7 +1322,7 @@ def code_deparse(
|
||||
is_top_level_module=is_top_level_module,
|
||||
)
|
||||
|
||||
#### XXX workaround for profiling
|
||||
# XXX workaround for profiling
|
||||
if deparsed.ast is None:
|
||||
return None
|
||||
|
||||
@@ -1406,7 +1430,7 @@ def deparse_code2str(
|
||||
if __name__ == "__main__":
|
||||
|
||||
def deparse_test(co):
|
||||
"This is a docstring"
|
||||
"""This is a docstring"""
|
||||
s = deparse_code2str(co)
|
||||
# s = deparse_code2str(co, debug_opts={"asm": "after", "tree": {'before': False, 'after': False}})
|
||||
print(s)
|
||||
|
Reference in New Issue
Block a user