diff --git a/test/add-test.py b/test/add-test.py index 758fe934..160c6d82 100755 --- a/test/add-test.py +++ b/test/add-test.py @@ -19,6 +19,7 @@ for path in py_source: else: cfile = "bytecode_%s%s/%s" % (version, suffix, short) + "c" print("byte-compiling %s to %s" % (path, cfile)) - py_compile.compile(path, cfile) + optimize = 2 + py_compile.compile(path, cfile, optimize=optimize) if isinstance(version, str) or version >= (2, 6, 0): os.system("../bin/uncompyle6 -a -T %s" % cfile) diff --git a/test/bytecode_3.7/03_else_removal.pyc b/test/bytecode_3.7/03_else_removal.pyc new file mode 100644 index 00000000..f010c82b Binary files /dev/null and b/test/bytecode_3.7/03_else_removal.pyc differ diff --git a/test/bytecode_3.8/03_else_removal.pyc b/test/bytecode_3.8/03_else_removal.pyc new file mode 100644 index 00000000..06e16fb8 Binary files /dev/null and b/test/bytecode_3.8/03_else_removal.pyc differ diff --git a/test/simple_source/bug37/03_else_removal.py b/test/simple_source/bug37/03_else_removal.py new file mode 100644 index 00000000..fe51da52 --- /dev/null +++ b/test/simple_source/bug37/03_else_removal.py @@ -0,0 +1,12 @@ +# From python3.8/distutils/version.py with optimization -O2 +# The bug was that the other "else" constant propagated removed. + +# NOTE: this program needs to be compile with optimization +def _cmp (b, c): + if b: + if c: + return 0 + else: + return 1 + else: + assert False, "never get here" diff --git a/uncompyle6/parsers/parse37.py b/uncompyle6/parsers/parse37.py index 11c1967a..a4d0bc29 100644 --- a/uncompyle6/parsers/parse37.py +++ b/uncompyle6/parsers/parse37.py @@ -94,6 +94,9 @@ class Python37Parser(Python37BaseParser): else_suitec ::= c_stmts else_suitec ::= returns + else_suite_opt ::= else_suite + else_suite_opt ::= pass + stmt ::= classdef stmt ::= call_stmt @@ -635,6 +638,12 @@ class Python37Parser(Python37BaseParser): if_exp37 ::= expr expr jf_cfs expr COME_FROM jf_cfs ::= JUMP_FORWARD _come_froms ifelsestmt ::= testexpr c_stmts_opt jf_cfs else_suite opt_come_from_except + + # This is probably more realistically an "ifstmt" (with a null else) + # see _cmp() of python3.8/distutils/__pycache__/version.cpython-38.opt-1.pyc + ifelsestmt ::= testexpr stmts jf_cfs else_suite_opt opt_come_from_except + + expr_pjit ::= expr POP_JUMP_IF_TRUE expr_jit ::= expr JUMP_IF_TRUE expr_jt ::= expr jmp_true