diff --git a/test/bytecode_3.6/03_async_from_coroutine.pyc b/test/bytecode_3.6/03_async_from_coroutine.pyc index 437a659b..da634c61 100644 Binary files a/test/bytecode_3.6/03_async_from_coroutine.pyc and b/test/bytecode_3.6/03_async_from_coroutine.pyc differ diff --git a/test/bytecode_3.7/03_async_from_coroutine.pyc b/test/bytecode_3.7/03_async_from_coroutine.pyc new file mode 100644 index 00000000..7aad71ed Binary files /dev/null and b/test/bytecode_3.7/03_async_from_coroutine.pyc differ diff --git a/test/bytecode_3.8/03_async_from_coroutine.pyc b/test/bytecode_3.8/03_async_from_coroutine.pyc new file mode 100644 index 00000000..50c0dde1 Binary files /dev/null and b/test/bytecode_3.8/03_async_from_coroutine.pyc differ diff --git a/test/simple_source/bug36/03_async_from_coroutine.py b/test/simple_source/bug36/03_async_from_coroutine.py index 6afdfe4c..30d3fcd1 100644 --- a/test/simple_source/bug36/03_async_from_coroutine.py +++ b/test/simple_source/bug36/03_async_from_coroutine.py @@ -1,4 +1,13 @@ # These are from 3.6 test_coroutines.py +async def run_gen(f): + return (10 async for i in f) + +async def run_list(f): + return [i async for i in f()] + +# async def run_dict(): +# return {i + 1 async for i in [10, 20]} + async def iterate(gen): res = [] async for i in gen: diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index c1d414d2..a6a9bbf9 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -192,6 +192,8 @@ class Python36Parser(Python35Parser): compare_chained2 ::= expr COMPARE_OP come_froms JUMP_FORWARD + stmt ::= genexpr_func + genexpr_func ::= LOAD_ARG _come_froms FOR_ITER store comp_iter JUMP_BACK """ # Some of this is duplicated from parse37. Eventually we'll probably rebase from @@ -336,9 +338,9 @@ class Python36Parser(Python35Parser): self.addRule( """ expr ::= generator_exp_async - generator_exp_async ::= load_genexpr LOAD_STR MAKE_FUNCTION_0 expr - GET_AITER CALL_FUNCTION_1 + generator_exp_async ::= load_genexpr LOAD_STR MAKE_FUNCTION_0 expr + GET_AITER LOAD_CONST YIELD_FROM CALL_FUNCTION_1 stmt ::= genexpr_func_async func_async_prefix ::= _come_froms @@ -349,7 +351,7 @@ class Python36Parser(Python35Parser): END_FINALLY COME_FROM genexpr_func_async ::= LOAD_ARG func_async_prefix store func_async_middle comp_iter - JUMP_BACK COME_FROM + JUMP_BACK POP_TOP POP_TOP POP_TOP POP_EXCEPT POP_TOP expr ::= list_comp_async diff --git a/uncompyle6/semantics/gencomp.py b/uncompyle6/semantics/gencomp.py index 0ce44256..c9a05895 100644 --- a/uncompyle6/semantics/gencomp.py +++ b/uncompyle6/semantics/gencomp.py @@ -182,7 +182,7 @@ class ComprehensionMixin: self.write(" in ") if node[2] == "expr": iter_expr = node[2] - elif node[3] == "get_aiter": + elif node[3] in ("expr", "get_aiter"): iter_expr = node[3] else: iter_expr = node[-3] diff --git a/uncompyle6/semantics/n_actions.py b/uncompyle6/semantics/n_actions.py index 32626822..50b4771a 100644 --- a/uncompyle6/semantics/n_actions.py +++ b/uncompyle6/semantics/n_actions.py @@ -681,17 +681,20 @@ class NonterminalActions: self.write("(") iter_index = 3 if self.version > (3, 2): - code_index = -6 - if self.version > (3, 6): - # Python 3.7+ adds optional "come_froms" at node[0] + if self.version >= (3, 6): if node[0].kind in ("load_closure", "load_genexpr") and self.version >= (3, 8): + code_index = -6 is_lambda = self.is_lambda if node[0].kind == "load_genexpr": self.is_lambda = False self.closure_walk(node, collection_index=4) self.is_lambda = is_lambda else: - code_index = -6 + # Python 3.7+ adds optional "come_froms" at node[0] so count from the end + if node == "generator_exp_async" and self.version[:2] == (3, 6): + code_index = 0 + else: + code_index = -6 iter_index = 4 if self.version < (3, 8) else 3 self.comprehension_walk(node, iter_index=iter_index, code_index=code_index) pass