You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09: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
|
JUMP_BACK COME_FROM
|
||||||
POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP
|
POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP
|
||||||
list_comp_async ::= BUILD_LIST_0 LOAD_FAST list_afor2
|
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_afor ::= get_aiter list_afor2
|
||||||
list_iter ::= list_afor
|
list_iter ::= list_afor
|
||||||
""",
|
""",
|
||||||
|
@@ -143,6 +143,12 @@ def customize_for_version37(self, version):
|
|||||||
|
|
||||||
"importattr37": ("%c", (0, "IMPORT_NAME_ATTR")),
|
"importattr37": ("%c", (0, "IMPORT_NAME_ATTR")),
|
||||||
"importlist37": ("%C", (0, maxint, ", ")),
|
"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": (" if %p%c", (0, 27), 1),
|
||||||
"list_if37_not": (" if not %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")),
|
"testfalse_not_or": ("not %c or %c", (0, "expr"), (2, "expr")),
|
||||||
|
@@ -963,7 +963,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
|
|
||||||
self.prune()
|
self.prune()
|
||||||
|
|
||||||
def n_listcomp(self, node):
|
def n_list_comp(self, node):
|
||||||
self.write("[")
|
self.write("[")
|
||||||
if node[0].kind == "load_closure":
|
if node[0].kind == "load_closure":
|
||||||
self.listcomprehension_walk2(node)
|
self.listcomprehension_walk2(node)
|
||||||
|
@@ -80,7 +80,7 @@ Python.
|
|||||||
#
|
#
|
||||||
# Escapes in the format string are:
|
# 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.
|
# integer or tuple representing a node index.
|
||||||
# If a tuple is given, the first item is the node index while
|
# If a tuple is given, the first item is the node index while
|
||||||
# the second item is a string giving the node/noterminal name.
|
# 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,
|
# 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.
|
# 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
|
# 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
|
# value of an end node, and a string to be inserted between sibling children
|
||||||
#
|
#
|
||||||
@@ -99,7 +99,7 @@ Python.
|
|||||||
# on the LHS of an assignment statement since BUILD_TUPLE_n pretty-prints
|
# on the LHS of an assignment statement since BUILD_TUPLE_n pretty-prints
|
||||||
# other tuples. The specifier takes no arguments
|
# other tuples. The specifier takes no arguments
|
||||||
#
|
#
|
||||||
# %P same as %C but sets operator precedence. Its argument is a 4-tuple:
|
# %P same as %C but sets operator precedence. Its argument is a 4-tuple:
|
||||||
# the node low and high indices, the separator, a string the precidence
|
# the node low and high indices, the separator, a string the precidence
|
||||||
# value, an integer.
|
# value, an integer.
|
||||||
#
|
#
|
||||||
@@ -115,7 +115,13 @@ Python.
|
|||||||
#
|
#
|
||||||
# %- decrease current indentation level. Takes no arguments.
|
# %- 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.
|
# %% literal '%'. Takes no arguments.
|
||||||
#
|
#
|
||||||
@@ -1205,7 +1211,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
ast = ast[0]
|
ast = ast[0]
|
||||||
|
|
||||||
# Pick out important parts of the comprehension:
|
# Pick out important parts of the comprehension:
|
||||||
# * the variable we interate over: "store"
|
# * the variable we iterate over: "store"
|
||||||
# * the results we accumulate: "n"
|
# * the results we accumulate: "n"
|
||||||
|
|
||||||
is_30_dict_comp = False
|
is_30_dict_comp = False
|
||||||
@@ -1265,17 +1271,25 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
# Iterate to find the innermost store
|
# Iterate to find the innermost store
|
||||||
# We'll come back to the list iteration below.
|
# 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
|
# iterate one nesting deeper
|
||||||
if self.version == 3.0 and len(n) == 3:
|
if self.version == 3.0 and len(n) == 3:
|
||||||
assert n[0] == "expr" and n[1] == "expr"
|
assert n[0] == "expr" and n[1] == "expr"
|
||||||
n = n[1]
|
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:
|
else:
|
||||||
n = n[0]
|
n = n[0]
|
||||||
|
|
||||||
if n in ("list_for", "comp_for"):
|
if n in ("list_for", "comp_for"):
|
||||||
if n[2] == "store" and not store:
|
if n[2] == "store" and not store:
|
||||||
store = n[2]
|
store = n[2]
|
||||||
|
if not comp_store:
|
||||||
|
comp_store = store
|
||||||
n = n[3]
|
n = n[3]
|
||||||
elif n in ("list_if", "list_if_not",
|
elif n in ("list_if", "list_if_not",
|
||||||
"list_if37", "list_if37_not",
|
"list_if37", "list_if37_not",
|
||||||
@@ -2112,7 +2126,6 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
self.prec = p
|
self.prec = p
|
||||||
arg += 1
|
arg += 1
|
||||||
elif typ == "{":
|
elif typ == "{":
|
||||||
d = node.__dict__
|
|
||||||
expr = m.group("expr")
|
expr = m.group("expr")
|
||||||
|
|
||||||
# Line mapping stuff
|
# Line mapping stuff
|
||||||
@@ -2123,10 +2136,16 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
):
|
):
|
||||||
self.source_linemap[self.current_line_number] = node.linestart
|
self.source_linemap[self.current_line_number] = node.linestart
|
||||||
|
|
||||||
try:
|
if expr[0] == "%":
|
||||||
self.write(eval(expr, d, d))
|
index = entry[arg]
|
||||||
except:
|
self.template_engine((expr, index), node)
|
||||||
raise
|
arg += 1
|
||||||
|
else:
|
||||||
|
d = node.__dict__
|
||||||
|
try:
|
||||||
|
self.write(eval(expr, d, d))
|
||||||
|
except:
|
||||||
|
raise
|
||||||
m = escape.search(fmt, i)
|
m = escape.search(fmt, i)
|
||||||
self.write(fmt[i:])
|
self.write(fmt[i:])
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user