diff --git a/decompyle3/parsers/p37/base.py b/decompyle3/parsers/p37/base.py index 2069419b..2bb7594a 100644 --- a/decompyle3/parsers/p37/base.py +++ b/decompyle3/parsers/p37/base.py @@ -1004,7 +1004,7 @@ def customize_grammar_rules37(self, tokens, customize): rules_str = """ stmt ::= with stmt ::= with_as_pass - stmt ::= withasstmt + stmt ::= with_as c_stmt ::= c_with c_with ::= expr SETUP_WITH POP_TOP @@ -1021,14 +1021,14 @@ def customize_grammar_rules37(self, tokens, customize): COME_FROM_WITH with_suffix - withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH + with_as ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH with_suffix with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix @@ -1037,7 +1037,7 @@ def customize_grammar_rules37(self, tokens, customize): SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix @@ -1067,16 +1067,16 @@ def customize_grammar_rules37(self, tokens, customize): with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts POP_BLOCK LOAD_CONST COME_FROM_WITH - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts POP_BLOCK BEGIN_FINALLY COME_FROM_WITH with_suffix - # withasstmt ::= expr SETUP_WITH store suite_stmts + # with_as ::= expr SETUP_WITH store suite_stmts # COME_FROM expr COME_FROM POP_BLOCK ROT_TWO # BEGIN_FINALLY WITH_CLEANUP_START WITH_CLEANUP_FINISH # POP_FINALLY RETURN_VALUE COME_FROM_WITH diff --git a/decompyle3/parsers/p37/lambda_custom.py b/decompyle3/parsers/p37/lambda_custom.py index 2ff1ee06..617cb8da 100644 --- a/decompyle3/parsers/p37/lambda_custom.py +++ b/decompyle3/parsers/p37/lambda_custom.py @@ -542,7 +542,7 @@ def customize_grammar_rules_lambda37(self, tokens, customize): WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY # Removes POP_BLOCK LOAD_CONST from 3.6- - withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH + with_as ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY """ if self.version < (3, 8): diff --git a/decompyle3/parsers/p38/full_custom.py b/decompyle3/parsers/p38/full_custom.py index da498c02..359a3057 100644 --- a/decompyle3/parsers/p38/full_custom.py +++ b/decompyle3/parsers/p38/full_custom.py @@ -661,7 +661,7 @@ def customize_grammar_rules_full38(self, tokens, customize): rules_str = """ stmt ::= with stmt ::= with_as_pass - stmt ::= withasstmt + stmt ::= with_as c_stmt ::= c_with @@ -679,23 +679,25 @@ def customize_grammar_rules_full38(self, tokens, customize): COME_FROM_WITH with_suffix - withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH + with ::= expr + SETUP_WITH POP_TOP suite_stmts_opt + POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix - withasstmt ::= expr + + with_as ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix - with ::= expr - SETUP_WITH POP_TOP suite_stmts_opt - POP_BLOCK LOAD_CONST COME_FROM_WITH + with_as ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH with_suffix - withasstmt ::= expr + + with_as ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix @@ -729,16 +731,16 @@ def customize_grammar_rules_full38(self, tokens, customize): with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts POP_BLOCK LOAD_CONST COME_FROM_WITH - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts POP_BLOCK BEGIN_FINALLY COME_FROM_WITH with_suffix - # withasstmt ::= expr SETUP_WITH store suite_stmts + # with_as ::= expr SETUP_WITH store suite_stmts # COME_FROM expr COME_FROM POP_BLOCK ROT_TWO # BEGIN_FINALLY WITH_CLEANUP_START WITH_CLEANUP_FINISH # POP_FINALLY RETURN_VALUE COME_FROM_WITH @@ -1229,7 +1231,7 @@ def customize_grammar_rules38(self, tokens, customize): elif opname == "SETUP_WITH": rules_str = """ stmt ::= with - stmt ::= withasstmt + stmt ::= with_as c_stmt ::= c_with c_with ::= expr SETUP_WITH POP_TOP @@ -1246,14 +1248,14 @@ def customize_grammar_rules38(self, tokens, customize): COME_FROM_WITH with_suffix - withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH + with_as ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH with_suffix with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix @@ -1262,7 +1264,7 @@ def customize_grammar_rules38(self, tokens, customize): SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix @@ -1291,16 +1293,16 @@ def customize_grammar_rules38(self, tokens, customize): with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts POP_BLOCK LOAD_CONST COME_FROM_WITH - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts POP_BLOCK BEGIN_FINALLY COME_FROM_WITH with_suffix - # withasstmt ::= expr SETUP_WITH store suite_stmts + # with_as ::= expr SETUP_WITH store suite_stmts # COME_FROM expr COME_FROM POP_BLOCK ROT_TWO # BEGIN_FINALLY WITH_CLEANUP_START WITH_CLEANUP_FINISH # POP_FINALLY RETURN_VALUE COME_FROM_WITH diff --git a/decompyle3/parsers/p38/lambda_custom.py b/decompyle3/parsers/p38/lambda_custom.py index c646c909..717eea1b 100644 --- a/decompyle3/parsers/p38/lambda_custom.py +++ b/decompyle3/parsers/p38/lambda_custom.py @@ -612,8 +612,8 @@ def customize_grammar_rules_lambda38(self, tokens, customize): WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY # Removes POP_BLOCK LOAD_CONST from 3.6- - withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH - WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY + with_as ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH +a WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY """ if self.version < (3, 8): rules_str += """ diff --git a/decompyle3/parsers/p38pypy/full_custom.py b/decompyle3/parsers/p38pypy/full_custom.py index a0f54c01..c1a4084b 100644 --- a/decompyle3/parsers/p38pypy/full_custom.py +++ b/decompyle3/parsers/p38pypy/full_custom.py @@ -660,7 +660,7 @@ def customize_grammar_rules_full38(self, tokens, customize): elif opname == "SETUP_WITH": rules_str = """ stmt ::= with - stmt ::= withasstmt + stmt ::= with_as c_stmt ::= c_with c_with ::= expr SETUP_WITH POP_TOP @@ -677,14 +677,14 @@ def customize_grammar_rules_full38(self, tokens, customize): COME_FROM_WITH with_suffix - withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH + with_as ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH with_suffix with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix @@ -693,7 +693,7 @@ def customize_grammar_rules_full38(self, tokens, customize): SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix @@ -722,16 +722,16 @@ def customize_grammar_rules_full38(self, tokens, customize): with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts POP_BLOCK LOAD_CONST COME_FROM_WITH - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts POP_BLOCK BEGIN_FINALLY COME_FROM_WITH with_suffix - # withasstmt ::= expr SETUP_WITH store suite_stmts + # with_as ::= expr SETUP_WITH store suite_stmts # COME_FROM expr COME_FROM POP_BLOCK ROT_TWO # BEGIN_FINALLY WITH_CLEANUP_START WITH_CLEANUP_FINISH # POP_FINALLY RETURN_VALUE COME_FROM_WITH @@ -1222,7 +1222,7 @@ def customize_grammar_rules38(self, tokens, customize): elif opname == "SETUP_WITH": rules_str = """ stmt ::= with - stmt ::= withasstmt + stmt ::= with_as c_stmt ::= c_with c_with ::= expr SETUP_WITH POP_TOP @@ -1239,14 +1239,14 @@ def customize_grammar_rules38(self, tokens, customize): COME_FROM_WITH with_suffix - withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH + with_as ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH with_suffix with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix @@ -1255,7 +1255,7 @@ def customize_grammar_rules38(self, tokens, customize): SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts_opt POP_BLOCK LOAD_CONST COME_FROM_WITH with_suffix @@ -1284,20 +1284,20 @@ def customize_grammar_rules38(self, tokens, customize): with_suffix - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts POP_BLOCK LOAD_CONST COME_FROM_WITH - withasstmt ::= expr + with_as ::= expr SETUP_WITH store suite_stmts POP_BLOCK BEGIN_FINALLY COME_FROM_WITH with_suffix - # withasstmt ::= expr SETUP_WITH store suite_stmts - # COME_FROM expr COME_FROM POP_BLOCK ROT_TWO - # BEGIN_FINALLY WITH_CLEANUP_START WITH_CLEANUP_FINISH - # POP_FINALLY RETURN_VALUE COME_FROM_WITH - # WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY + # with_as ::= expr SETUP_WITH store suite_stmts + # COME_FROM expr COME_FROM POP_BLOCK ROT_TWO + # BEGIN_FINALLY WITH_CLEANUP_START WITH_CLEANUP_FINISH + # POP_FINALLY RETURN_VALUE COME_FROM_WITH + # WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY with ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK BEGIN_FINALLY COME_FROM_WITH diff --git a/decompyle3/parsers/p38pypy/lambda_custom.py b/decompyle3/parsers/p38pypy/lambda_custom.py index 9c58a512..ee337ade 100644 --- a/decompyle3/parsers/p38pypy/lambda_custom.py +++ b/decompyle3/parsers/p38pypy/lambda_custom.py @@ -623,7 +623,7 @@ def customize_grammar_rules_lambda38(self, tokens, customize): WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY # Removes POP_BLOCK LOAD_CONST from 3.6- - withasstmt ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH + with_as ::= expr SETUP_WITH store suite_stmts_opt COME_FROM_WITH WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY """ if self.version < (3, 8): diff --git a/decompyle3/semantics/consts.py b/decompyle3/semantics/consts.py index 466d9876..429dedf8 100644 --- a/decompyle3/semantics/consts.py +++ b/decompyle3/semantics/consts.py @@ -577,12 +577,12 @@ "import_from_star": ("%|from %[2]{pattr} import *\n",), # If there are situations where we need "with ... as ()" - # We may need to customize this in n_withasstmt - "withasstmt": ( + # We may need to customize this in n_with_as + "with_as": ( "%|with %c as %c:\n%+%c%-", (0, "expr"), (2, "store"), - (3, "suite_stmts_opt"), + (3, ("suite_stmts_opt", "_stmts")), ), } diff --git a/decompyle3/semantics/transform.py b/decompyle3/semantics/transform.py index d1032dae..5a04dc4d 100644 --- a/decompyle3/semantics/transform.py +++ b/decompyle3/semantics/transform.py @@ -67,7 +67,7 @@ # "return_expr", # "set_comp_func", "tryfinallystmt", - "withasstmt", + "with_as", ) diff --git a/test/bytecode_3.7/run/08_test_contextmanager.pyc b/test/bytecode_3.7/run/08_test_contextmanager.pyc new file mode 100644 index 00000000..e3f7b00e Binary files /dev/null and b/test/bytecode_3.7/run/08_test_contextmanager.pyc differ diff --git a/test/bytecode_3.8/run/08_test_contextmanager.pyc b/test/bytecode_3.8/run/08_test_contextmanager.pyc new file mode 100644 index 00000000..159c6eee Binary files /dev/null and b/test/bytecode_3.8/run/08_test_contextmanager.pyc differ diff --git a/test/simple_source/stmts/08_test_contextmanager.py b/test/simple_source/stmts/08_test_contextmanager.py new file mode 100644 index 00000000..9a6ea5f9 --- /dev/null +++ b/test/simple_source/stmts/08_test_contextmanager.py @@ -0,0 +1,21 @@ +""" +This program is self checking! +""" + + +class TestContextManager: + def __enter__(self): + return 1, 2 + + def __exit__(self, exc_type, exc_value, exc_tb): + return self, exc_type, exc_value, exc_tb + + +with open(__file__) as a: + assert a + +with open(__file__) as a, open(__file__) as b: + assert a.read() == b.read() + +with TestContextManager() as a, b: + assert (a, b) == (1, 2)