diff --git a/test/bytecode_3.7/02_async_for_generator.pyc b/test/bytecode_3.7/02_async_for_generator.pyc index 49369a14..cc9c8b33 100644 Binary files a/test/bytecode_3.7/02_async_for_generator.pyc and b/test/bytecode_3.7/02_async_for_generator.pyc differ diff --git a/test/simple_source/bug37/02_async_for_generator.py b/test/simple_source/bug37/02_async_for_generator.py index 14847ae7..1a497b3f 100644 --- a/test/simple_source/bug37/02_async_for_generator.py +++ b/test/simple_source/bug37/02_async_for_generator.py @@ -3,3 +3,6 @@ def make_arange(n): # This syntax is legal starting with Python 3.7 return (i * 2 async for i in n) + +async def run(m): + return [i async for i in m] diff --git a/uncompyle6/parsers/parse37base.py b/uncompyle6/parsers/parse37base.py index c2ed3799..c7f169a1 100644 --- a/uncompyle6/parsers/parse37base.py +++ b/uncompyle6/parsers/parse37base.py @@ -514,7 +514,20 @@ class Python37BaseParser(PythonParser): store func_async_middle comp_iter JUMP_BACK COME_FROM POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP - """, + + expr ::= listcomp_async + listcomp_async ::= LOAD_LISTCOMP LOAD_STR MAKE_FUNCTION_0 + expr GET_AITER CALL_FUNCTION_1 + GET_AWAITABLE LOAD_CONST + YIELD_FROM + + expr ::= listcomp_async + listcomp_async ::= BUILD_LIST_0 LOAD_FAST func_async_prefix + store func_async_middle list_iter + JUMP_BACK COME_FROM + POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP + + """, nop_func, ) custom_ops_processed.add(opname) diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 64cd1d8b..425f5b68 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1221,6 +1221,8 @@ class SourceWalker(GenericASTTraversal, object): n = k[0] pass pass + elif ast == "listcomp_async": + store = ast[3] else: assert n == "list_iter", n @@ -1287,6 +1289,13 @@ class SourceWalker(GenericASTTraversal, object): self.preorder(n[1]) else: self.preorder(n[0]) + + if node == "listcomp_async": + self.write(" async") + in_node_index = 3 + else: + in_node_index = -3 + self.write(" for ") if comp_store: self.preorder(comp_store) @@ -1295,7 +1304,7 @@ class SourceWalker(GenericASTTraversal, object): # FIXME this is all merely approximate self.write(" in ") - self.preorder(node[-3]) + self.preorder(node[in_node_index]) # Here is where we handle nested list iterations. if ast == "list_comp" and self.version != 3.0: @@ -1434,9 +1443,14 @@ class SourceWalker(GenericASTTraversal, object): if node[0].kind == "load_closure": self.listcomprehension_walk2(node) else: - self.comprehension_walk_newer(node, 1, 0) + if node == "listcomp_async": + list_iter_index = 5 + else: + list_iter_index = 1 + self.comprehension_walk_newer(node, list_iter_index, 0) self.write("]") self.prune() + n_listcomp_async = n_listcomp def setcomprehension_walk3(self, node, collection_index): """Set comprehensions the way they are done in Python3.