You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 16:59:52 +08:00
Bugs in nested async for...
* Generalize asyc_for rule Fix bug in picking out comprehension iterator in async for * fix bug in getting expression in such a comprehension * Add %[n]{%x} pattern to template_engine()
This commit is contained in:
@@ -614,7 +614,7 @@ class Python37BaseParser(PythonParser):
|
||||
JUMP_BACK COME_FROM
|
||||
POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP
|
||||
list_comp_async ::= BUILD_LIST_0 LOAD_FAST list_afor2
|
||||
get_aiter ::= LOAD_DEREF GET_AITER
|
||||
get_aiter ::= expr GET_AITER
|
||||
list_afor ::= get_aiter list_afor2
|
||||
list_iter ::= list_afor
|
||||
""",
|
||||
|
@@ -143,6 +143,12 @@ def customize_for_version37(self, version):
|
||||
|
||||
"importattr37": ("%c", (0, "IMPORT_NAME_ATTR")),
|
||||
"importlist37": ("%C", (0, maxint, ", ")),
|
||||
|
||||
"list_afor": (
|
||||
" async for %[1]{%c} in %c%[1]{%c}",
|
||||
(1, "store"), (0, "get_aiter"), (3, "list_iter"),
|
||||
),
|
||||
|
||||
"list_if37": (" if %p%c", (0, 27), 1),
|
||||
"list_if37_not": (" if not %p%c", (0, 27), 1),
|
||||
"testfalse_not_or": ("not %c or %c", (0, "expr"), (2, "expr")),
|
||||
|
@@ -963,7 +963,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
||||
|
||||
self.prune()
|
||||
|
||||
def n_listcomp(self, node):
|
||||
def n_list_comp(self, node):
|
||||
self.write("[")
|
||||
if node[0].kind == "load_closure":
|
||||
self.listcomprehension_walk2(node)
|
||||
|
@@ -80,7 +80,7 @@ Python.
|
||||
#
|
||||
# Escapes in the format string are:
|
||||
#
|
||||
# %c evaluate the node recursively. Its argument is a single
|
||||
# %c evaluate/traverse the node recursively. Its argument is a single
|
||||
# integer or tuple representing a node index.
|
||||
# If a tuple is given, the first item is the node index while
|
||||
# the second item is a string giving the node/noterminal name.
|
||||
@@ -91,7 +91,7 @@ Python.
|
||||
# index and the precedence value, an integer. If 3 items are given,
|
||||
# the second item is the nonterminal name and the precedence is given last.
|
||||
#
|
||||
# %C evaluate children recursively, with sibling children separated by the
|
||||
# %C evaluate/travers children recursively, with sibling children separated by the
|
||||
# given string. It needs a 3-tuple: a starting node, the maximimum
|
||||
# value of an end node, and a string to be inserted between sibling children
|
||||
#
|
||||
@@ -115,7 +115,13 @@ Python.
|
||||
#
|
||||
# %- decrease current indentation level. Takes no arguments.
|
||||
#
|
||||
# %{...} evaluate ... in context of N
|
||||
# %{EXPR} Python eval(EXPR) in context of node. Takes no arguments
|
||||
#
|
||||
# %[N]{EXPR} Python eval(EXPR) in context of node[N]. Takes no arguments
|
||||
#
|
||||
# %[N]{%X} evaluate/recurse on child node[N], using specifier %X.
|
||||
# %X can be one of the above, e.g. %c, %p, etc. Takes the arguemnts
|
||||
# that the specifier uses.
|
||||
#
|
||||
# %% literal '%'. Takes no arguments.
|
||||
#
|
||||
@@ -1205,7 +1211,7 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
ast = ast[0]
|
||||
|
||||
# Pick out important parts of the comprehension:
|
||||
# * the variable we interate over: "store"
|
||||
# * the variable we iterate over: "store"
|
||||
# * the results we accumulate: "n"
|
||||
|
||||
is_30_dict_comp = False
|
||||
@@ -1265,17 +1271,25 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
# Iterate to find the innermost store
|
||||
# We'll come back to the list iteration below.
|
||||
|
||||
while n in ("list_iter", "comp_iter"):
|
||||
while n in ("list_iter", "list_afor", "list_afor2", "comp_iter"):
|
||||
# iterate one nesting deeper
|
||||
if self.version == 3.0 and len(n) == 3:
|
||||
assert n[0] == "expr" and n[1] == "expr"
|
||||
n = n[1]
|
||||
elif n == "list_afor":
|
||||
n = n[1]
|
||||
elif n == "list_afor2":
|
||||
if n[1] == "store":
|
||||
store = n[1]
|
||||
n = n[3]
|
||||
else:
|
||||
n = n[0]
|
||||
|
||||
if n in ("list_for", "comp_for"):
|
||||
if n[2] == "store" and not store:
|
||||
store = n[2]
|
||||
if not comp_store:
|
||||
comp_store = store
|
||||
n = n[3]
|
||||
elif n in ("list_if", "list_if_not",
|
||||
"list_if37", "list_if37_not",
|
||||
@@ -2112,7 +2126,6 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
self.prec = p
|
||||
arg += 1
|
||||
elif typ == "{":
|
||||
d = node.__dict__
|
||||
expr = m.group("expr")
|
||||
|
||||
# Line mapping stuff
|
||||
@@ -2123,6 +2136,12 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
):
|
||||
self.source_linemap[self.current_line_number] = node.linestart
|
||||
|
||||
if expr[0] == "%":
|
||||
index = entry[arg]
|
||||
self.template_engine((expr, index), node)
|
||||
arg += 1
|
||||
else:
|
||||
d = node.__dict__
|
||||
try:
|
||||
self.write(eval(expr, d, d))
|
||||
except:
|
||||
|
Reference in New Issue
Block a user