From 5355cb5404c7669b4106ca791eb8502a8329d488 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 8 Feb 2020 20:31:06 -0500 Subject: [PATCH] async with rules back to 3.5 and ... add precidence on cascaded "await" expressions --- test/bytecode_3.6/04_async.pyc | Bin 0 -> 897 bytes test/stdlib/3.5-exclude.sh | 5 ++-- test/stdlib/3.6-exclude.sh | 2 +- test/stdlib/3.7-exclude.sh | 2 +- uncompyle6/parsers/parse35.py | 39 ++++++++++++++++------------ uncompyle6/parsers/parse36.py | 26 ++++++++++--------- uncompyle6/semantics/consts.py | 2 ++ uncompyle6/semantics/customize35.py | 21 ++++++++++----- uncompyle6/semantics/customize37.py | 7 ++++- 9 files changed, 64 insertions(+), 40 deletions(-) create mode 100644 test/bytecode_3.6/04_async.pyc diff --git a/test/bytecode_3.6/04_async.pyc b/test/bytecode_3.6/04_async.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca37ce391ac9af0362f8f06207a1cb57ce9db44f GIT binary patch literal 897 zcmZ`%O=}cE5UuJNlX1UXF$iAtCM?KCNFWkIj4Yx#WIz)z%)w@yo+O*hPRH(9k`395 zyP!FH(tqIZ@L$Z;)BXidR`tfPD>zV(?&*53s$ca=yF2zp@n-N^XF%)<#MzBp9uW3CJNVs~v z|GqxN!W+TOzA+REDa6owM~pYud2eB#SeJMb*!{x)g#Vr?pgz2C!i`MmF4R;M#MY*! z*tXGPFV5q`)I=32<1{Z)BW1L3ruC85W#ffQ>+1ZaG1|2J(zj`LP%b8#GS7<=&r2Nq z027ex??<-VJIzvQb>AfE@`wK6%G&bNRT zOfw3GB*pY_Lg({Exr?vNdO}dZ>;w?L(6ra!iu~W5n}Aajp<$O>7>Uk~Go^*4*9rIB z+T5nI(mT-l9;+`9fM{ZX7mw$z&~`SRb&DhUti6%xB+l$+n`l!-Vc0y=U|`={XzILn z>eU%8zc$OcK<-{V_-~DnObn#V<6bIdN$;SiRiEZ4%bJuQ`*AisF?YBMSDXPZYN`ZH m3d^1c==NdDi>lMnOYX_d)}73-otW!8*q9dGbPt1dYPCN?JiQqJ literal 0 HcmV?d00001 diff --git a/test/stdlib/3.5-exclude.sh b/test/stdlib/3.5-exclude.sh index 2c15ae3d..4dc17f76 100644 --- a/test/stdlib/3.5-exclude.sh +++ b/test/stdlib/3.5-exclude.sh @@ -1,4 +1,5 @@ SKIP_TESTS=( + [test_buffer.py]=1 # FIXME: Works on c90ff51 [test_platform.py]=1 # FIXME: Works on c90ff51 [test_pyclbr.py]=1 # FIXME: Works on c90ff51 [test_tempfile.py]=1 # FIXME: Works on c90ff51 @@ -22,7 +23,6 @@ SKIP_TESTS=( [test_collections.py]=1 [test_compile.py]=1 # Code introspects on co_consts in a non-decompilable way [test_concurrent_futures.py]=1 # Takes long to run - [test_coroutines.py]=1 # Syntax error Investigate [test_curses.py]=1 # [test_devpoll.py]=1 # it fails on its own @@ -90,7 +90,7 @@ SKIP_TESTS=( [test_selectors.py]=1 # Takes too long 17 seconds [test_set.py]=1 # # test assert failure and doesn't terminate [test_signal.py]=1 # too long? - [test_smtpd.py]=1 # test failures + [test_smtplib.py]=1 # probably control flow [test_socket.py]=1 # long [test_socketserver.py]=1 [test_strtod.py]=1 # Test assert failure @@ -131,7 +131,6 @@ SKIP_TESTS=( if (( batch )) ; then SKIP_TESTS[test_asyncore.py]=1 # Ok, but takes more than 15 seconds to run SKIP_TESTS[test_bisect.py]=1 - SKIP_TESTS[test_buffer.py]=1 # too long SKIP_TESTS[test_compileall.py]=1 # Something weird on POWER SKIP_TESTS[test_codeccallbacks.py]=1 # Something differenet in locale? SKIP_TESTS[test_distutils.py]=1 diff --git a/test/stdlib/3.6-exclude.sh b/test/stdlib/3.6-exclude.sh index 56b5c15e..21f08abc 100644 --- a/test/stdlib/3.6-exclude.sh +++ b/test/stdlib/3.6-exclude.sh @@ -41,7 +41,7 @@ SKIP_TESTS=( [test_concurrent_futures.py]=1 # Takes long [test_contextlib.py]=1 # test assertion failure [test_contextlib_async.py]=1 # Investigate - [test_coroutines.py]=1 # Parse error + [test_coroutines.py]=1 # parse error [test_curses.py]=1 # Parse error [test_ctypes.py]=1 # it fails on its own diff --git a/test/stdlib/3.7-exclude.sh b/test/stdlib/3.7-exclude.sh index 4079ba39..52bff135 100644 --- a/test/stdlib/3.7-exclude.sh +++ b/test/stdlib/3.7-exclude.sh @@ -30,7 +30,7 @@ SKIP_TESTS=( [test_compileall.py]=1 # fails on its own [test_compile.py]=1 # Code introspects on co_consts in a non-decompilable way [test_concurrent_futures.py]=1 # too long - [test_coroutines.py]=1 # Investigate: Parse error - async/yield stuff? + [test_coroutines.py]=1 # test [test_codecs.py]=1 # test assert failures; encoding/decoding stuff [test_ctypes.py]=1 # it fails on its own [test_curses.py]=1 # probably byte string not handled properly diff --git a/uncompyle6/parsers/parse35.py b/uncompyle6/parsers/parse35.py index 8a91363e..28a2a0c6 100644 --- a/uncompyle6/parsers/parse35.py +++ b/uncompyle6/parsers/parse35.py @@ -171,26 +171,33 @@ class Python35Parser(Python34Parser): elif opname == 'BEFORE_ASYNC_WITH' and self.version < 3.8: # Some Python 3.5+ async additions rules_str = """ - async_with_stmt ::= expr - stmt ::= async_with_stmt + async_with_stmt ::= expr + stmt ::= async_with_stmt + async_with_pre ::= BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM SETUP_ASYNC_WITH + async_with_post ::= COME_FROM_ASYNC_WITH + WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM + WITH_CLEANUP_FINISH END_FINALLY - async_with_stmt ::= expr - BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM - SETUP_ASYNC_WITH POP_TOP suite_stmts_opt - POP_BLOCK LOAD_CONST COME_FROM_ASYNC_WITH - WITH_CLEANUP_START - GET_AWAITABLE LOAD_CONST YIELD_FROM - WITH_CLEANUP_FINISH END_FINALLY + async_with_stmt ::= expr + async_with_pre + POP_TOP + suite_stmts_opt + POP_BLOCK LOAD_CONST + async_with_post + async_with_stmt ::= expr + async_with_pre + POP_TOP + suite_stmts_opt + async_with_post - stmt ::= async_with_as_stmt + stmt ::= async_with_as_stmt async_with_as_stmt ::= expr - BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM - SETUP_ASYNC_WITH store suite_stmts_opt - POP_BLOCK LOAD_CONST COME_FROM_ASYNC_WITH - WITH_CLEANUP_START - GET_AWAITABLE LOAD_CONST YIELD_FROM - WITH_CLEANUP_FINISH END_FINALLY + async_with_pre + store + suite_stmts_opt + POP_BLOCK LOAD_CONST + async_with_post """ self.addRule(rules_str, nop_func) elif opname == 'BUILD_MAP_UNPACK': diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index 67d15f60..9abcedc0 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -240,24 +240,26 @@ class Python36Parser(Python35Parser): elif opname == 'BEFORE_ASYNC_WITH': rules_str = """ stmt ::= async_with_stmt + async_with_pre ::= BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM SETUP_ASYNC_WITH + async_with_post ::= COME_FROM_ASYNC_WITH + WITH_CLEANUP_START GET_AWAITABLE LOAD_CONST YIELD_FROM + WITH_CLEANUP_FINISH END_FINALLY async_with_as_stmt ::= expr - BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM - SETUP_ASYNC_WITH store + async_with_pre + store suite_stmts_opt POP_BLOCK LOAD_CONST - COME_FROM_ASYNC_WITH - WITH_CLEANUP_START - GET_AWAITABLE LOAD_CONST YIELD_FROM - WITH_CLEANUP_FINISH END_FINALLY + async_with_post stmt ::= async_with_as_stmt async_with_stmt ::= expr - BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM - SETUP_ASYNC_WITH POP_TOP suite_stmts_opt + POP_TOP + suite_stmts_opt POP_BLOCK LOAD_CONST - COME_FROM_ASYNC_WITH - WITH_CLEANUP_START - GET_AWAITABLE LOAD_CONST YIELD_FROM - WITH_CLEANUP_FINISH END_FINALLY + async_with_post + async_with_stmt ::= expr + POP_TOP + suite_stmts_opt + async_with_post """ self.addRule(rules_str, nop_func) diff --git a/uncompyle6/semantics/consts.py b/uncompyle6/semantics/consts.py index a962f87b..41141c2b 100644 --- a/uncompyle6/semantics/consts.py +++ b/uncompyle6/semantics/consts.py @@ -92,6 +92,8 @@ PRECEDENCE = { 'BINARY_POWER': 4, # Exponentiation, * + 'await_expr': 3, # await x, * + 'attribute': 2, # x.attribute 'buildslice2': 2, # x[index] 'buildslice3': 2, # x[index:index] diff --git a/uncompyle6/semantics/customize35.py b/uncompyle6/semantics/customize35.py index 587eadc5..23c3b6d2 100644 --- a/uncompyle6/semantics/customize35.py +++ b/uncompyle6/semantics/customize35.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019 by Rocky Bernstein +# Copyright (c) 2019-2020 by Rocky Bernstein # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,7 +17,12 @@ from xdis.code import iscode from xdis.util import COMPILER_FLAG_BIT -from uncompyle6.semantics.consts import INDENT_PER_LEVEL, TABLE_DIRECT +from uncompyle6.semantics.consts import ( + INDENT_PER_LEVEL, + PRECEDENCE, + TABLE_DIRECT, +) + from uncompyle6.semantics.helper import flatten_list, gen_function_parens_adjust ####################### @@ -26,7 +31,11 @@ from uncompyle6.semantics.helper import flatten_list, gen_function_parens_adjust def customize_for_version35(self, version): TABLE_DIRECT.update( { - "await_expr": ("await %c", 0), + # nested await expressions like: + # return await (await bar()) + # need parenthesis. + "await_expr": ("await %p", (0, PRECEDENCE["await_expr"]-1)), + "await_stmt": ("%|%c\n", 0), "async_for_stmt": ("%|async for %c in %c:\n%+%|%c%-\n\n", 9, 1, 25), "async_forelse_stmt": ( @@ -36,12 +45,12 @@ def customize_for_version35(self, version): 25, (27, "else_suite"), ), - "async_with_stmt": ("%|async with %c:\n%+%c%-", (0, "expr"), 7), + "async_with_stmt": ("%|async with %c:\n%+%c%-", (0, "expr"), 3), "async_with_as_stmt": ( "%|async with %c as %c:\n%+%c%-", (0, "expr"), - (6, "store"), - 7, + (2, "store"), + 3, ), "unmap_dict": ("{**%C}", (0, -1, ", **")), # "unmapexpr": ( "{**%c}", 0), # done by n_unmapexpr diff --git a/uncompyle6/semantics/customize37.py b/uncompyle6/semantics/customize37.py index 9fad7357..0bd5d934 100644 --- a/uncompyle6/semantics/customize37.py +++ b/uncompyle6/semantics/customize37.py @@ -79,7 +79,12 @@ def customize_for_version37(self, version): "attributes37": ("%[0]{pattr} import %c", (0, "IMPORT_NAME_ATTR"), (1, "IMPORT_FROM")), - "await_expr": ("await %c", 0), + + # nested await expressions like: + # return await (await bar()) + # need parenthesis. + "await_expr": ("await %p", (0, PRECEDENCE["await_expr"]-1)), + "await_stmt": ("%|%c\n", 0), "call_ex": ("%c(%p)", (0, "expr"), (1, 100)), "compare_chained1a_37": (