You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
sync with decompile3
This commit is contained in:
@@ -597,16 +597,6 @@ class Scanner:
|
|||||||
return self.Token
|
return self.Token
|
||||||
|
|
||||||
|
|
||||||
def prefer_double_quote(string: str) -> str:
|
|
||||||
"""
|
|
||||||
Prefer a double quoted string over a
|
|
||||||
single quoted string when possible
|
|
||||||
"""
|
|
||||||
if string.find("'") == -1:
|
|
||||||
return f'"{string}"'
|
|
||||||
return str(string)
|
|
||||||
|
|
||||||
|
|
||||||
def get_scanner(version: Union[str, tuple], is_pypy=False, show_asm=None) -> Scanner:
|
def get_scanner(version: Union[str, tuple], is_pypy=False, show_asm=None) -> Scanner:
|
||||||
# If version is a string, turn that into the corresponding float.
|
# If version is a string, turn that into the corresponding float.
|
||||||
if isinstance(version, str):
|
if isinstance(version, str):
|
||||||
@@ -659,6 +649,16 @@ def get_scanner(version: Union[str, tuple], is_pypy=False, show_asm=None) -> Sca
|
|||||||
return scanner
|
return scanner
|
||||||
|
|
||||||
|
|
||||||
|
def prefer_double_quote(string: str) -> str:
|
||||||
|
"""
|
||||||
|
Prefer a double quoted string over a
|
||||||
|
single quoted string when possible
|
||||||
|
"""
|
||||||
|
if string.find("'") == -1:
|
||||||
|
return f'"{string}"'
|
||||||
|
return repr(string)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2017-2023 by Rocky Bernstein
|
# Copyright (c) 2017-2024 by Rocky Bernstein
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,9 +14,11 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
"""Constants and initial table values used in pysource.py and fragments.py"""
|
"""Constants and initial table values used in pysource.py and fragments.py"""
|
||||||
|
|
||||||
import re, sys
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
from uncompyle6.parsers.treenode import SyntaxTree
|
from uncompyle6.parsers.treenode import SyntaxTree
|
||||||
from uncompyle6.scanners.tok import Token, NoneToken
|
from uncompyle6.scanners.tok import NoneToken, Token
|
||||||
|
|
||||||
minint = -sys.maxsize - 1
|
minint = -sys.maxsize - 1
|
||||||
maxint = sys.maxsize
|
maxint = sys.maxsize
|
||||||
@@ -46,6 +48,7 @@ maxint = sys.maxsize
|
|||||||
# call((.. op ..)).
|
# call((.. op ..)).
|
||||||
|
|
||||||
NO_PARENTHESIS_EVER = 100
|
NO_PARENTHESIS_EVER = 100
|
||||||
|
PARENTHESIS_ALWAYS = -2
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
PRECEDENCE = {
|
PRECEDENCE = {
|
||||||
|
@@ -18,7 +18,14 @@ Custom Nonterminal action functions. See NonterminalActions docstring.
|
|||||||
|
|
||||||
from uncompyle6.parsers.treenode import SyntaxTree
|
from uncompyle6.parsers.treenode import SyntaxTree
|
||||||
from uncompyle6.scanners.tok import Token
|
from uncompyle6.scanners.tok import Token
|
||||||
from uncompyle6.semantics.consts import INDENT_PER_LEVEL, NONE, PRECEDENCE, minint
|
from uncompyle6.semantics.consts import (
|
||||||
|
INDENT_PER_LEVEL,
|
||||||
|
NO_PARENTHESIS_EVER,
|
||||||
|
NONE,
|
||||||
|
PARENTHESIS_ALWAYS,
|
||||||
|
PRECEDENCE,
|
||||||
|
minint,
|
||||||
|
)
|
||||||
from uncompyle6.semantics.helper import find_code_node, flatten_list
|
from uncompyle6.semantics.helper import find_code_node, flatten_list
|
||||||
from uncompyle6.util import better_repr, get_code_name
|
from uncompyle6.util import better_repr, get_code_name
|
||||||
|
|
||||||
@@ -41,7 +48,7 @@ class NonterminalActions:
|
|||||||
self.prec = 1000
|
self.prec = 1000
|
||||||
self.in_format_string = False
|
self.in_format_string = False
|
||||||
|
|
||||||
def n_alias(self, node):
|
def n_alias(self, node: SyntaxTree):
|
||||||
if self.version <= (2, 1):
|
if self.version <= (2, 1):
|
||||||
if len(node) == 2:
|
if len(node) == 2:
|
||||||
store = node[1]
|
store = node[1]
|
||||||
@@ -66,7 +73,7 @@ class NonterminalActions:
|
|||||||
|
|
||||||
n_alias37 = n_alias
|
n_alias37 = n_alias
|
||||||
|
|
||||||
def n_assign(self, node):
|
def n_assign(self, node: SyntaxTree):
|
||||||
# A horrible hack for Python 3.0 .. 3.2
|
# A horrible hack for Python 3.0 .. 3.2
|
||||||
if (3, 0) <= self.version <= (3, 2) and len(node) == 2:
|
if (3, 0) <= self.version <= (3, 2) and len(node) == 2:
|
||||||
if (
|
if (
|
||||||
@@ -77,19 +84,19 @@ class NonterminalActions:
|
|||||||
self.prune()
|
self.prune()
|
||||||
self.default(node)
|
self.default(node)
|
||||||
|
|
||||||
def n_assign2(self, node):
|
def n_assign2(self, node: SyntaxTree):
|
||||||
for n in node[-2:]:
|
for n in node[-2:]:
|
||||||
if n[0] == "unpack":
|
if n[0] == "unpack":
|
||||||
n[0].kind = "unpack_w_parens"
|
n[0].kind = "unpack_w_parens"
|
||||||
self.default(node)
|
self.default(node)
|
||||||
|
|
||||||
def n_assign3(self, node):
|
def n_assign3(self, node: SyntaxTree):
|
||||||
for n in node[-3:]:
|
for n in node[-3:]:
|
||||||
if n[0] == "unpack":
|
if n[0] == "unpack":
|
||||||
n[0].kind = "unpack_w_parens"
|
n[0].kind = "unpack_w_parens"
|
||||||
self.default(node)
|
self.default(node)
|
||||||
|
|
||||||
def n_attribute(self, node):
|
def n_attribute(self, node: SyntaxTree):
|
||||||
if node[0] == "LOAD_CONST" or node[0] == "expr" and node[0][0] == "LOAD_CONST":
|
if node[0] == "LOAD_CONST" or node[0] == "expr" and node[0][0] == "LOAD_CONST":
|
||||||
# FIXME: I didn't record which constants parenthesis is
|
# FIXME: I didn't record which constants parenthesis is
|
||||||
# necessary. However, I suspect that we could further
|
# necessary. However, I suspect that we could further
|
||||||
@@ -99,7 +106,7 @@ class NonterminalActions:
|
|||||||
node.kind = "attribute_w_parens"
|
node.kind = "attribute_w_parens"
|
||||||
self.default(node)
|
self.default(node)
|
||||||
|
|
||||||
def n_bin_op(self, node):
|
def n_bin_op(self, node: SyntaxTree):
|
||||||
"""bin_op (formerly "binary_expr") is the Python AST BinOp"""
|
"""bin_op (formerly "binary_expr") is the Python AST BinOp"""
|
||||||
self.preorder(node[0])
|
self.preorder(node[0])
|
||||||
self.write(" ")
|
self.write(" ")
|
||||||
@@ -111,9 +118,9 @@ class NonterminalActions:
|
|||||||
self.prec += 1
|
self.prec += 1
|
||||||
self.prune()
|
self.prune()
|
||||||
|
|
||||||
def n_build_slice2(self, node):
|
def n_build_slice2(self, node: SyntaxTree):
|
||||||
p = self.prec
|
p = self.prec
|
||||||
self.prec = 100
|
self.prec = NO_PARENTHESIS_EVER
|
||||||
if not node[0].isNone():
|
if not node[0].isNone():
|
||||||
self.preorder(node[0])
|
self.preorder(node[0])
|
||||||
self.write(":")
|
self.write(":")
|
||||||
@@ -122,9 +129,9 @@ class NonterminalActions:
|
|||||||
self.prec = p
|
self.prec = p
|
||||||
self.prune() # stop recursing
|
self.prune() # stop recursing
|
||||||
|
|
||||||
def n_build_slice3(self, node):
|
def n_build_slice3(self, node: SyntaxTree):
|
||||||
p = self.prec
|
p = self.prec
|
||||||
self.prec = 100
|
self.prec = NO_PARENTHESIS_EVER
|
||||||
if not node[0].isNone():
|
if not node[0].isNone():
|
||||||
self.preorder(node[0])
|
self.preorder(node[0])
|
||||||
self.write(":")
|
self.write(":")
|
||||||
@@ -136,7 +143,7 @@ class NonterminalActions:
|
|||||||
self.prec = p
|
self.prec = p
|
||||||
self.prune() # stop recursing
|
self.prune() # stop recursing
|
||||||
|
|
||||||
def n_classdef(self, node):
|
def n_classdef(self, node: SyntaxTree):
|
||||||
if self.version >= (3, 6):
|
if self.version >= (3, 6):
|
||||||
self.n_classdef36(node)
|
self.n_classdef36(node)
|
||||||
elif self.version >= (3, 0):
|
elif self.version >= (3, 0):
|
||||||
@@ -199,7 +206,7 @@ class NonterminalActions:
|
|||||||
|
|
||||||
n_classdefdeco2 = n_classdef
|
n_classdefdeco2 = n_classdef
|
||||||
|
|
||||||
def n_const_list(self, node):
|
def n_const_list(self, node: SyntaxTree):
|
||||||
"""
|
"""
|
||||||
prettyprint a constant dict, list, set or tuple.
|
prettyprint a constant dict, list, set or tuple.
|
||||||
"""
|
"""
|
||||||
@@ -293,7 +300,7 @@ class NonterminalActions:
|
|||||||
self.prune()
|
self.prune()
|
||||||
return
|
return
|
||||||
|
|
||||||
def n_delete_subscript(self, node):
|
def n_delete_subscript(self, node: SyntaxTree):
|
||||||
if node[-2][0] == "build_list" and node[-2][0][-1].kind.startswith(
|
if node[-2][0] == "build_list" and node[-2][0][-1].kind.startswith(
|
||||||
"BUILD_TUPLE"
|
"BUILD_TUPLE"
|
||||||
):
|
):
|
||||||
@@ -303,7 +310,7 @@ class NonterminalActions:
|
|||||||
|
|
||||||
n_store_subscript = n_subscript = n_delete_subscript
|
n_store_subscript = n_subscript = n_delete_subscript
|
||||||
|
|
||||||
def n_dict(self, node):
|
def n_dict(self, node: SyntaxTree):
|
||||||
"""
|
"""
|
||||||
Prettyprint a dict.
|
Prettyprint a dict.
|
||||||
'dict' is something like k = {'a': 1, 'b': 42}"
|
'dict' is something like k = {'a': 1, 'b': 42}"
|
||||||
@@ -315,7 +322,7 @@ class NonterminalActions:
|
|||||||
return
|
return
|
||||||
|
|
||||||
p = self.prec
|
p = self.prec
|
||||||
self.prec = 100
|
self.prec = PRECEDENCE["dict"]
|
||||||
|
|
||||||
self.indent_more(INDENT_PER_LEVEL)
|
self.indent_more(INDENT_PER_LEVEL)
|
||||||
sep = INDENT_PER_LEVEL[:-1]
|
sep = INDENT_PER_LEVEL[:-1]
|
||||||
@@ -327,8 +334,8 @@ class NonterminalActions:
|
|||||||
if node[0].kind.startswith("kvlist"):
|
if node[0].kind.startswith("kvlist"):
|
||||||
# Python 3.5+ style key/value list in dict
|
# Python 3.5+ style key/value list in dict
|
||||||
kv_node = node[0]
|
kv_node = node[0]
|
||||||
l = list(kv_node)
|
ll = list(kv_node)
|
||||||
length = len(l)
|
length = len(ll)
|
||||||
if kv_node[-1].kind.startswith("BUILD_MAP"):
|
if kv_node[-1].kind.startswith("BUILD_MAP"):
|
||||||
length -= 1
|
length -= 1
|
||||||
i = 0
|
i = 0
|
||||||
@@ -336,7 +343,7 @@ class NonterminalActions:
|
|||||||
# Respect line breaks from source
|
# Respect line breaks from source
|
||||||
while i < length:
|
while i < length:
|
||||||
self.write(sep)
|
self.write(sep)
|
||||||
name = self.traverse(l[i], indent="")
|
name = self.traverse(ll[i], indent="")
|
||||||
if i > 0:
|
if i > 0:
|
||||||
line_number = self.indent_if_source_nl(
|
line_number = self.indent_if_source_nl(
|
||||||
line_number, self.indent + INDENT_PER_LEVEL[:-1]
|
line_number, self.indent + INDENT_PER_LEVEL[:-1]
|
||||||
@@ -344,7 +351,7 @@ class NonterminalActions:
|
|||||||
line_number = self.line_number
|
line_number = self.line_number
|
||||||
self.write(name, ": ")
|
self.write(name, ": ")
|
||||||
value = self.traverse(
|
value = self.traverse(
|
||||||
l[i + 1], indent=self.indent + (len(name) + 2) * " "
|
ll[i + 1], indent=self.indent + (len(name) + 2) * " "
|
||||||
)
|
)
|
||||||
self.write(value)
|
self.write(value)
|
||||||
sep = ", "
|
sep = ", "
|
||||||
@@ -357,15 +364,15 @@ class NonterminalActions:
|
|||||||
elif len(node) > 1 and node[1].kind.startswith("kvlist"):
|
elif len(node) > 1 and node[1].kind.startswith("kvlist"):
|
||||||
# Python 3.0..3.4 style key/value list in dict
|
# Python 3.0..3.4 style key/value list in dict
|
||||||
kv_node = node[1]
|
kv_node = node[1]
|
||||||
l = list(kv_node)
|
ll = list(kv_node)
|
||||||
if len(l) > 0 and l[0].kind == "kv3":
|
if len(ll) > 0 and ll[0].kind == "kv3":
|
||||||
# Python 3.2 does this
|
# Python 3.2 does this
|
||||||
kv_node = node[1][0]
|
kv_node = node[1][0]
|
||||||
l = list(kv_node)
|
ll = list(kv_node)
|
||||||
i = 0
|
i = 0
|
||||||
while i < len(l):
|
while i < len(ll):
|
||||||
self.write(sep)
|
self.write(sep)
|
||||||
name = self.traverse(l[i + 1], indent="")
|
name = self.traverse(ll[i + 1], indent="")
|
||||||
if i > 0:
|
if i > 0:
|
||||||
line_number = self.indent_if_source_nl(
|
line_number = self.indent_if_source_nl(
|
||||||
line_number, self.indent + INDENT_PER_LEVEL[:-1]
|
line_number, self.indent + INDENT_PER_LEVEL[:-1]
|
||||||
@@ -374,7 +381,7 @@ class NonterminalActions:
|
|||||||
line_number = self.line_number
|
line_number = self.line_number
|
||||||
self.write(name, ": ")
|
self.write(name, ": ")
|
||||||
value = self.traverse(
|
value = self.traverse(
|
||||||
l[i], indent=self.indent + (len(name) + 2) * " "
|
ll[i], indent=self.indent + (len(name) + 2) * " "
|
||||||
)
|
)
|
||||||
self.write(value)
|
self.write(value)
|
||||||
sep = ", "
|
sep = ", "
|
||||||
@@ -592,7 +599,7 @@ class NonterminalActions:
|
|||||||
self.println(lines[-1], quote)
|
self.println(lines[-1], quote)
|
||||||
self.prune()
|
self.prune()
|
||||||
|
|
||||||
def n_elifelsestmtr(self, node):
|
def n_elifelsestmtr(self, node: SyntaxTree):
|
||||||
if node[2] == "COME_FROM":
|
if node[2] == "COME_FROM":
|
||||||
return_stmts_node = node[3]
|
return_stmts_node = node[3]
|
||||||
node.kind = "elifelsestmtr2"
|
node.kind = "elifelsestmtr2"
|
||||||
@@ -623,7 +630,7 @@ class NonterminalActions:
|
|||||||
self.indent_less()
|
self.indent_less()
|
||||||
self.prune()
|
self.prune()
|
||||||
|
|
||||||
def n_except_cond2(self, node):
|
def n_except_cond2(self, node: SyntaxTree):
|
||||||
if node[-1] == "come_from_opt":
|
if node[-1] == "come_from_opt":
|
||||||
unpack_node = -3
|
unpack_node = -3
|
||||||
else:
|
else:
|
||||||
@@ -637,7 +644,7 @@ class NonterminalActions:
|
|||||||
# FIXME: figure out how to get this into customization
|
# FIXME: figure out how to get this into customization
|
||||||
# put so that we can get access via super from
|
# put so that we can get access via super from
|
||||||
# the fragments routine.
|
# the fragments routine.
|
||||||
def n_exec_stmt(self, node):
|
def n_exec_stmt(self, node: SyntaxTree):
|
||||||
"""
|
"""
|
||||||
exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT
|
exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT
|
||||||
exec_stmt ::= expr exprlist EXEC_STMT
|
exec_stmt ::= expr exprlist EXEC_STMT
|
||||||
@@ -669,7 +676,9 @@ class NonterminalActions:
|
|||||||
# hasattr(self, 'current_line_number')):
|
# hasattr(self, 'current_line_number')):
|
||||||
# self.source_linemap[self.current_line_number] = n.linestart
|
# self.source_linemap[self.current_line_number] = n.linestart
|
||||||
|
|
||||||
self.prec = PRECEDENCE.get(n.kind, -2)
|
if n.kind != "expr":
|
||||||
|
self.prec = PRECEDENCE.get(n.kind, PARENTHESIS_ALWAYS)
|
||||||
|
|
||||||
if n == "LOAD_CONST" and repr(n.pattr)[0] == "-":
|
if n == "LOAD_CONST" and repr(n.pattr)[0] == "-":
|
||||||
self.prec = 6
|
self.prec = 6
|
||||||
|
|
||||||
@@ -726,7 +735,7 @@ class NonterminalActions:
|
|||||||
self.write(")")
|
self.write(")")
|
||||||
self.prune()
|
self.prune()
|
||||||
|
|
||||||
n_generator_exp_async = n_generator_exp
|
n_genexpr_func = n_generator_exp_async = n_generator_exp
|
||||||
|
|
||||||
def n_ifelsestmtr(self, node):
|
def n_ifelsestmtr(self, node):
|
||||||
if node[2] == "COME_FROM":
|
if node[2] == "COME_FROM":
|
||||||
@@ -806,7 +815,7 @@ class NonterminalActions:
|
|||||||
self.make_function(node, is_lambda=True, code_node=node[-2])
|
self.make_function(node, is_lambda=True, code_node=node[-2])
|
||||||
self.prune() # stop recursing
|
self.prune() # stop recursing
|
||||||
|
|
||||||
def n_list(self, node):
|
def n_list(self, node: SyntaxTree):
|
||||||
"""
|
"""
|
||||||
prettyprint a dict, list, set or tuple.
|
prettyprint a dict, list, set or tuple.
|
||||||
"""
|
"""
|
||||||
@@ -837,13 +846,16 @@ class NonterminalActions:
|
|||||||
if lastnodetype.startswith("BUILD_LIST"):
|
if lastnodetype.startswith("BUILD_LIST"):
|
||||||
self.write("[")
|
self.write("[")
|
||||||
endchar = "]"
|
endchar = "]"
|
||||||
|
|
||||||
elif lastnodetype.startswith("BUILD_MAP_UNPACK"):
|
elif lastnodetype.startswith("BUILD_MAP_UNPACK"):
|
||||||
self.write("{*")
|
self.write("{*")
|
||||||
endchar = "}"
|
endchar = "}"
|
||||||
|
|
||||||
elif lastnodetype.startswith("BUILD_SET"):
|
elif lastnodetype.startswith("BUILD_SET"):
|
||||||
self.write("{")
|
self.write("{")
|
||||||
endchar = "}"
|
endchar = "}"
|
||||||
elif lastnodetype.startswith("BUILD_TUPLE"):
|
|
||||||
|
elif lastnodetype.startswith("BUILD_TUPLE") or node == "tuple":
|
||||||
# Tuples can appear places that can NOT
|
# Tuples can appear places that can NOT
|
||||||
# have parenthesis around them, like array
|
# have parenthesis around them, like array
|
||||||
# subscripts. We check for that by seeing
|
# subscripts. We check for that by seeing
|
||||||
@@ -864,6 +876,7 @@ class NonterminalActions:
|
|||||||
elif lastnodetype.startswith("ROT_TWO"):
|
elif lastnodetype.startswith("ROT_TWO"):
|
||||||
self.write("(")
|
self.write("(")
|
||||||
endchar = ")"
|
endchar = ")"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"Internal Error: n_build_list expects list, tuple, set, or unpack"
|
"Internal Error: n_build_list expects list, tuple, set, or unpack"
|
||||||
@@ -902,7 +915,7 @@ class NonterminalActions:
|
|||||||
self.prune()
|
self.prune()
|
||||||
return
|
return
|
||||||
|
|
||||||
n_set = n_tuple = n_build_set = n_list
|
n_set = n_build_set = n_tuple = n_list
|
||||||
|
|
||||||
def n_list_comp(self, node):
|
def n_list_comp(self, node):
|
||||||
"""List comprehensions"""
|
"""List comprehensions"""
|
||||||
|
Reference in New Issue
Block a user