diff --git a/.circleci/config.yml b/.circleci/config.yml index 2b2bf6c6..c2dfe464 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,13 +10,6 @@ jobs: CIRCLE_ARTIFACTS: /tmp/circleci-artifacts CIRCLE_TEST_REPORTS: /tmp/circleci-test-results COMPILE: --compile - # In CircleCI 1.0 we used a pre-configured image with a large number of languages and other packages. - # In CircleCI 2.0 you can now specify your own image, or use one of our pre-configured images. - # The following configuration line tells CircleCI to use the specified docker image as the runtime environment for you job. - # We have selected a pre-built image that mirrors the build environment we use on - # the 1.0 platform, but we recommend you choose an image more tailored to the needs - # of each job. For more information on choosing an image (or alternatively using a - # VM instead of a container) see https://circleci.com/docs/2.0/executor-types/ # To see the list of pre-built images that CircleCI provides for most common languages see # https://circleci.com/docs/2.0/circleci-images/ machine: diff --git a/__pkginfo__.py b/__pkginfo__.py index 60ec1573..c6993049 100644 --- a/__pkginfo__.py +++ b/__pkginfo__.py @@ -58,7 +58,7 @@ entry_points = { ]} ftp_url = None install_requires = ["spark-parser >= 1.8.9, < 1.9.0", - "xdis >= 4.2.0, < 4.3.0"] + "xdis >= 4.2.1, < 4.3.0"] license = "GPL3" mailing_list = "python-debugger@googlegroups.com" 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/test/stdlib/runtests.sh b/test/stdlib/runtests.sh index f38e1d16..532a4549 100755 --- a/test/stdlib/runtests.sh +++ b/test/stdlib/runtests.sh @@ -162,6 +162,14 @@ case $PYVERSION in [test_quopri.py]=1 # Only fails on POWER ) ;; + 3.7) + SKIP_TESTS=( + [test_argparse.py]=1 # + [test_ast.py]=1 # + [test_contains.py]=1 # Code "while False: yield None" is optimized away in compilation + [test_decorators.py]=1 # Control flow wrt "if elif" + ) + ;; *) SKIP_TESTS=( [test_aepack.py]=1 [audiotests.py]=1 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/customize37.py b/uncompyle6/semantics/customize37.py index ba77f407..2002cf21 100644 --- a/uncompyle6/semantics/customize37.py +++ b/uncompyle6/semantics/customize37.py @@ -33,7 +33,7 @@ def customize_for_version37(self, version): '%|async for %c in %c:\n%+%c%-%|else:\n%+%c%-\n\n', (7, 'store'), (1, 'expr'), (17, 'for_block'), (25, 'else_suite') ), 'async_for_stmt': ( - '%|async for %c in %c:\n%+%c%-%-\n\n', + '%|async for %c in %c:\n%+%c%-\n\n', (7, 'store'), (1, 'expr'), (17, 'for_block')), 'async_for_stmt37': ( '%|async for %c in %c:\n%+%c%-%-\n\n', diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 655371c4..3a9540bb 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.