diff --git a/test/simple_source/expression/09_yield_from.py b/test/simple_source/expression/09_yield_from.py index e8d5eb20..68821db1 100644 --- a/test/simple_source/expression/09_yield_from.py +++ b/test/simple_source/expression/09_yield_from.py @@ -17,9 +17,9 @@ def ybug(g): # From 3.5.1 _wakrefset.py # # 3.5: -# withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt -# POP_BLOCK LOAD_CONST COME_FROM -# WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY +# with ::= expr SETUP_WITH POP_TOP suite_stmts_opt +# POP_BLOCK LOAD_CONST COME_FROM +# WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY def __iter__(self, IterationGuard): diff --git a/uncompyle6/parser.py b/uncompyle6/parser.py index 3ed46808..cf5cce6e 100644 --- a/uncompyle6/parser.py +++ b/uncompyle6/parser.py @@ -352,7 +352,7 @@ class PythonParser(GenericASTBuilder): stmt ::= try_except stmt ::= tryelsestmt stmt ::= tryfinallystmt - stmt ::= withstmt + stmt ::= with stmt ::= withasstmt stmt ::= del_stmt diff --git a/uncompyle6/parsers/parse24.py b/uncompyle6/parsers/parse24.py index 2d3b932c..dccf9db9 100644 --- a/uncompyle6/parsers/parse24.py +++ b/uncompyle6/parsers/parse24.py @@ -88,8 +88,8 @@ class Python24Parser(Python25Parser): with_cleanup ::= LOAD_FAST DELETE_FAST WITH_CLEANUP END_FINALLY with_cleanup ::= LOAD_NAME DELETE_NAME WITH_CLEANUP END_FINALLY withasstmt ::= expr setupwithas store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM with_cleanup - withstmt ::= expr setupwith SETUP_FINALLY suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM with_cleanup - stmt ::= withstmt + with ::= expr setupwith SETUP_FINALLY suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM with_cleanup + stmt ::= with stmt ::= withasstmt """) super(Python24Parser, self).customize_grammar_rules(tokens, customize) diff --git a/uncompyle6/parsers/parse25.py b/uncompyle6/parsers/parse25.py index 1f5ed48b..3c30a2e4 100644 --- a/uncompyle6/parsers/parse25.py +++ b/uncompyle6/parsers/parse25.py @@ -27,7 +27,7 @@ class Python25Parser(Python26Parser): setup_finally # opcode SETUP_WITH setupwith ::= DUP_TOP LOAD_ATTR store LOAD_ATTR CALL_FUNCTION_0 POP_TOP - withstmt ::= expr setupwith SETUP_FINALLY suite_stmts_opt + with ::= expr setupwith SETUP_FINALLY suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM with_cleanup # Semantic actions want store to be at index 2 @@ -62,7 +62,7 @@ class Python25Parser(Python26Parser): # Remove grammar rules inherited from Python 2.6 or Python 2 self.remove_rules(""" setupwith ::= DUP_TOP LOAD_ATTR ROT_TWO LOAD_ATTR CALL_FUNCTION_0 POP_TOP - withstmt ::= expr setupwith SETUP_FINALLY suite_stmts_opt + with ::= expr setupwith SETUP_FINALLY suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY withasstmt ::= expr setupwithas store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY diff --git a/uncompyle6/parsers/parse26.py b/uncompyle6/parsers/parse26.py index 7a7f2271..2853fa41 100644 --- a/uncompyle6/parsers/parse26.py +++ b/uncompyle6/parsers/parse26.py @@ -119,8 +119,8 @@ class Python26Parser(Python2Parser): ifelsestmtc ::= testexpr c_stmts_opt ja_cf_pop else_suitec # Semantic actions want suite_stmts_opt to be at index 3 - withstmt ::= expr setupwith SETUP_FINALLY suite_stmts_opt - POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY + with ::= expr setupwith SETUP_FINALLY suite_stmts_opt + POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY # Semantic actions want store to be at index 2 withasstmt ::= expr setupwithas store suite_stmts_opt diff --git a/uncompyle6/parsers/parse27.py b/uncompyle6/parsers/parse27.py index 1792b83c..e1bb86ab 100644 --- a/uncompyle6/parsers/parse27.py +++ b/uncompyle6/parsers/parse27.py @@ -143,7 +143,7 @@ class Python27Parser(Python2Parser): for_block ::= returns _come_froms - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index fd3b103f..cac4649f 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -269,9 +269,9 @@ class Python3Parser(PythonParser): jmp_abs ::= JUMP_ABSOLUTE jmp_abs ::= JUMP_BACK - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt - POP_BLOCK LOAD_CONST COME_FROM_WITH - WITH_CLEANUP END_FINALLY + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt + POP_BLOCK LOAD_CONST COME_FROM_WITH + WITH_CLEANUP END_FINALLY withasstmt ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH diff --git a/uncompyle6/parsers/parse30.py b/uncompyle6/parsers/parse30.py index 3b1d0390..82510688 100644 --- a/uncompyle6/parsers/parse30.py +++ b/uncompyle6/parsers/parse30.py @@ -212,7 +212,7 @@ class Python30Parser(Python31Parser): whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK JUMP_BACK COME_FROM_LOOP whilestmt ::= SETUP_LOOP testexpr returns POP_TOP POP_BLOCK COME_FROM_LOOP withasstmt ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY # lc_body ::= LOAD_FAST expr LIST_APPEND # lc_body ::= LOAD_NAME expr LIST_APPEND diff --git a/uncompyle6/parsers/parse31.py b/uncompyle6/parsers/parse31.py index 642bd757..a5d8a74a 100644 --- a/uncompyle6/parsers/parse31.py +++ b/uncompyle6/parsers/parse31.py @@ -15,7 +15,7 @@ class Python31Parser(Python32Parser): setupwith ::= DUP_TOP LOAD_ATTR store LOAD_ATTR CALL_FUNCTION_0 POP_TOP setupwithas ::= DUP_TOP LOAD_ATTR store LOAD_ATTR CALL_FUNCTION_0 store - withstmt ::= expr setupwith SETUP_FINALLY + with ::= expr setupwith SETUP_FINALLY suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_FINALLY load del_stmt WITH_CLEANUP END_FINALLY diff --git a/uncompyle6/parsers/parse35.py b/uncompyle6/parsers/parse35.py index 28a2a0c6..5de7c6c4 100644 --- a/uncompyle6/parsers/parse35.py +++ b/uncompyle6/parsers/parse35.py @@ -50,7 +50,7 @@ class Python35Parser(Python34Parser): # Python 3.5+ has WITH_CLEANUP_START/FINISH - withstmt ::= expr + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY @@ -138,7 +138,7 @@ class Python35Parser(Python34Parser): self.remove_rules(""" yield_from ::= expr GET_ITER LOAD_CONST YIELD_FROM yield_from ::= expr expr YIELD_FROM - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP END_FINALLY withasstmt ::= expr SETUP_WITH store suite_stmts_opt @@ -209,10 +209,10 @@ class Python35Parser(Python34Parser): elif opname == 'SETUP_WITH': # Python 3.5+ has WITH_CLEANUP_START/FINISH rules_str = """ - withstmt ::= expr - SETUP_WITH POP_TOP suite_stmts_opt - POP_BLOCK LOAD_CONST COME_FROM_WITH - WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY + with ::= expr + SETUP_WITH POP_TOP suite_stmts_opt + POP_BLOCK LOAD_CONST COME_FROM_WITH + WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY withasstmt ::= expr SETUP_WITH store suite_stmts_opt diff --git a/uncompyle6/parsers/parse36.py b/uncompyle6/parsers/parse36.py index 9abcedc0..09fb49fb 100644 --- a/uncompyle6/parsers/parse36.py +++ b/uncompyle6/parsers/parse36.py @@ -307,7 +307,7 @@ class Python36Parser(Python35Parser): self.check_reduce['assign'] = 'token' elif opname == 'SETUP_WITH': rules_str = """ - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY # Removes POP_BLOCK LOAD_CONST from 3.6- @@ -316,13 +316,13 @@ class Python36Parser(Python35Parser): """ if self.version < 3.8: rules_str += """ - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY """ else: rules_str += """ - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK BEGIN_FINALLY COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY diff --git a/uncompyle6/parsers/parse37.py b/uncompyle6/parsers/parse37.py index 0d8a33ae..40e53227 100644 --- a/uncompyle6/parsers/parse37.py +++ b/uncompyle6/parsers/parse37.py @@ -1271,7 +1271,7 @@ class Python37Parser(Python37BaseParser): self.addRule(rule, nop_func) elif opname == "SETUP_WITH": rules_str = """ - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY # Removes POP_BLOCK LOAD_CONST from 3.6- @@ -1280,13 +1280,13 @@ class Python37Parser(Python37BaseParser): """ if self.version < 3.8: rules_str += """ - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY """ else: rules_str += """ - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK BEGIN_FINALLY COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY diff --git a/uncompyle6/parsers/parse37base.py b/uncompyle6/parsers/parse37base.py index 3e58ef6c..0643e906 100644 --- a/uncompyle6/parsers/parse37base.py +++ b/uncompyle6/parsers/parse37base.py @@ -995,15 +995,15 @@ class Python37BaseParser(PythonParser): elif opname == "SETUP_WITH": rules_str = """ - stmt ::= withstmt + stmt ::= with stmt ::= withasstmt - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY - withstmt ::= expr + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY @@ -1012,7 +1012,7 @@ class Python37BaseParser(PythonParser): POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY - withstmt ::= expr + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY @@ -1023,13 +1023,13 @@ class Python37BaseParser(PythonParser): """ if self.version < 3.8: rules_str += """ - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY """ else: rules_str += """ - withstmt ::= expr + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY @@ -1038,7 +1038,7 @@ class Python37BaseParser(PythonParser): SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH - withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK + with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK BEGIN_FINALLY COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY @@ -1184,8 +1184,16 @@ class Python37BaseParser(PythonParser): n = len(tokens) last = min(last, n-1) fn = self.reduce_check_table.get(lhs, None) - if fn: - return fn(self, lhs, n, rule, ast, tokens, first, last) + try: + if fn: + return fn(self, lhs, n, rule, ast, tokens, first, last) + except: + import sys, traceback + print(f"Exception in {fn.__name__} {sys.exc_info()[1]}\n" + + f"rule: {rule2str(rule)}\n" + + f"offsets {tokens[first].offset} .. {tokens[last].offset}") + print(traceback.print_tb(sys.exc_info()[2],-1)) + raise ParserError(tokens[last], tokens[last].off2int(), self.debug["rules"]) if lhs in ("aug_assign1", "aug_assign2") and ast[0][0] == "and": return True diff --git a/uncompyle6/parsers/treenode.py b/uncompyle6/parsers/treenode.py index 733db58c..4369393e 100644 --- a/uncompyle6/parsers/treenode.py +++ b/uncompyle6/parsers/treenode.py @@ -6,6 +6,7 @@ from spark_parser.ast import AST as spark_AST if PYTHON3: intern = sys.intern + class SyntaxTree(spark_AST): def __init__(self, *args, **kwargs): super(SyntaxTree, self).__init__(*args, **kwargs) @@ -17,7 +18,7 @@ class SyntaxTree(spark_AST): return len(self.data) == 1 and NoneToken == self.data[0] def __repr__(self): - return self.__repr1__('', None) + return self.__repr1__("", None) def __repr1__(self, indent, sibNum=None): rv = str(self.kind) @@ -33,16 +34,16 @@ class SyntaxTree(spark_AST): else: rv += " (transformed by %s)" % self.transformed_by rv = indent + rv - indent += ' ' + indent += " " i = 0 for node in self: - if hasattr(node, '__repr1__'): + if hasattr(node, "__repr1__"): if enumerate_children: - child = node.__repr1__(indent, i) + child = node.__repr1__(indent, i) else: child = node.__repr1__(indent, None) else: - inst = node.format(line_prefix='L.') + inst = node.format(line_prefix="") if inst.startswith("\n"): # Nuke leading \n inst = inst[1:] diff --git a/uncompyle6/semantics/customize25.py b/uncompyle6/semantics/customize25.py index 46f85631..911997a9 100644 --- a/uncompyle6/semantics/customize25.py +++ b/uncompyle6/semantics/customize25.py @@ -31,7 +31,7 @@ def customize_for_version25(self, version): # With/as is allowed as "from future" thing in 2.5 # Note: It is safe to put the variables after "as" in parenthesis, # and sometimes it is needed. - 'withstmt': ( '%|with %c:\n%+%c%-', 0, 3), + 'with': ( '%|with %c:\n%+%c%-', 0, 3), 'withasstmt': ( '%|with %c as (%c):\n%+%c%-', 0, 2, 3), }) diff --git a/uncompyle6/semantics/customize3.py b/uncompyle6/semantics/customize3.py index ea7c55f6..f695c0d5 100644 --- a/uncompyle6/semantics/customize3.py +++ b/uncompyle6/semantics/customize3.py @@ -54,7 +54,7 @@ def customize_for_version3(self, version): "raise_stmt2": ("%|raise %c from %c\n", 0, 1), "tf_tryelsestmtl3": ( '%c%-%c%|else:\n%+%c', 1, 3, 5 ), "store_locals": ("%|# inspect.currentframe().f_locals = __locals__\n",), - "withstmt": ("%|with %c:\n%+%c%-", 0, 3), + "with": ("%|with %c:\n%+%c%-", 0, 3), "withasstmt": ("%|with %c as (%c):\n%+%c%-", 0, 2, 3), } ) diff --git a/uncompyle6/semantics/customize37.py b/uncompyle6/semantics/customize37.py index 0bd5d934..63555717 100644 --- a/uncompyle6/semantics/customize37.py +++ b/uncompyle6/semantics/customize37.py @@ -295,3 +295,13 @@ def customize_for_version37(self, version): return self.n_importlist37 = n_importlist37 + + def n_list_comp_async(node): + self.write("[") + if node[0].kind == "load_closure": + self.listcomp_closure3(node) + else: + self.comprehension_walk_newer(node, iter_index=3, code_index=0) + self.write("]") + self.prune() + self.n_list_comp_async = n_list_comp_async diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 4cd63a43..cb1c7629 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -1241,7 +1241,7 @@ class SourceWalker(GenericASTTraversal, object): n = k[0] pass pass - elif ast == "listcomp_async": + elif ast == "list_comp_async": store = ast[2][1] else: assert n == "list_iter", n @@ -1291,7 +1291,7 @@ class SourceWalker(GenericASTTraversal, object): # Python 2.7+ starts including set_comp_body # Python 3.5+ starts including set_comp_func # Python 3.0 is yet another snowflake - if self.version != 3.0: + if self.version != 3.0 and self.version < 3.7: assert n.kind in ( "lc_body", "list_if37", @@ -1317,7 +1317,7 @@ class SourceWalker(GenericASTTraversal, object): else: self.preorder(n[0]) - if node == "listcomp_async": + if node == "list_comp_async": self.write(" async") in_node_index = 3 else: @@ -1367,7 +1367,6 @@ class SourceWalker(GenericASTTraversal, object): 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.