diff --git a/test/bytecode_3.5_run/04_importlist.pyc b/test/bytecode_3.5_run/04_importlist.pyc index 6d739fe7..96a13e10 100644 Binary files a/test/bytecode_3.5_run/04_importlist.pyc and b/test/bytecode_3.5_run/04_importlist.pyc differ diff --git a/test/bytecode_3.6_run/01_conditional.pyc b/test/bytecode_3.6_run/01_conditional.pyc index c24dde9c..1738b028 100644 Binary files a/test/bytecode_3.6_run/01_conditional.pyc and b/test/bytecode_3.6_run/01_conditional.pyc differ diff --git a/test/bytecode_3.6_run/04_importlist.pyc b/test/bytecode_3.6_run/04_importlist.pyc index 6e5471a0..3b697c2c 100644 Binary files a/test/bytecode_3.6_run/04_importlist.pyc and b/test/bytecode_3.6_run/04_importlist.pyc differ diff --git a/test/bytecode_3.7_run/01_conditional.pyc b/test/bytecode_3.7_run/01_conditional.pyc new file mode 100644 index 00000000..71af35bd Binary files /dev/null and b/test/bytecode_3.7_run/01_conditional.pyc differ diff --git a/test/bytecode_3.7_run/04_importlist.pyc b/test/bytecode_3.7_run/04_importlist.pyc index 9f0bc568..3d9dd109 100644 Binary files a/test/bytecode_3.7_run/04_importlist.pyc and b/test/bytecode_3.7_run/04_importlist.pyc differ diff --git a/test/bytecode_3.8_run/01_conditional.pyc b/test/bytecode_3.8_run/01_conditional.pyc new file mode 100644 index 00000000..1076f1b4 Binary files /dev/null and b/test/bytecode_3.8_run/01_conditional.pyc differ diff --git a/test/bytecode_3.8_run/04_importlist.pyc b/test/bytecode_3.8_run/04_importlist.pyc index 2b22411a..1b22d3e5 100644 Binary files a/test/bytecode_3.8_run/04_importlist.pyc and b/test/bytecode_3.8_run/04_importlist.pyc differ diff --git a/test/simple_source/bug35/04_importlist.py b/test/simple_source/bug35/04_importlist.py index ad51f661..5afc8a45 100644 --- a/test/simple_source/bug35/04_importlist.py +++ b/test/simple_source/bug35/04_importlist.py @@ -5,12 +5,15 @@ # RUNNABLE! import os.path as osp -from sys import path +from sys import platform from os import sep, name import collections.abc assert osp.basename("a") == "a" -assert path + +assert isinstance(platform, str) assert sep assert name assert collections.abc +import os.path as path +assert path diff --git a/test/simple_source/bug36/01_conditional.py b/test/simple_source/bug36/01_conditional.py index a521c98b..b643af49 100644 --- a/test/simple_source/bug36/01_conditional.py +++ b/test/simple_source/bug36/01_conditional.py @@ -8,3 +8,14 @@ def foo(n): assert foo(95) assert not foo(94) assert not foo(96) + +# from test_buffer.py +# Bug was handling "or" inside a conditional +def rslice(a, b): + minlen = 0 if a or b else 1 + return minlen + +assert rslice(False, False) == 1 +assert rslice(False, True) == 0 +assert rslice(True, False) == 0 +assert rslice(True, True) == 0 diff --git a/test/stdlib/runtests.sh b/test/stdlib/runtests.sh index 36526205..1e86cfe1 100755 --- a/test/stdlib/runtests.sh +++ b/test/stdlib/runtests.sh @@ -454,7 +454,6 @@ case $PYVERSION in [test_compare.py]=1 # test assert fail - investigate [test_compile.py]=1 [test_configparser.py]=1 - [test_contextlib_async.py]=1 # Investigate [test_context.py]=1 [test_coroutines.py]=1 # Parse error [test_crypt.py]=1 # Parse error diff --git a/uncompyle6/parsers/parse37.py b/uncompyle6/parsers/parse37.py index 5184d7bf..49e4d20d 100644 --- a/uncompyle6/parsers/parse37.py +++ b/uncompyle6/parsers/parse37.py @@ -913,6 +913,7 @@ class Python37Parser(Python37BaseParser): or ::= and jitop_come_from expr COME_FROM or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM or ::= expr JUMP_IF_TRUE expr COME_FROM + or ::= expr POP_JUMP_IF_TRUE expr POP_JUMP_IF_FALSE COME_FROM testfalse_not_or ::= expr jmp_false expr jmp_false COME_FROM testfalse_not_and ::= and jmp_true come_froms diff --git a/uncompyle6/parsers/reducecheck/or_check.py b/uncompyle6/parsers/reducecheck/or_check.py index ed12a798..218812b5 100644 --- a/uncompyle6/parsers/reducecheck/or_check.py +++ b/uncompyle6/parsers/reducecheck/or_check.py @@ -3,10 +3,7 @@ def or_check(self, lhs, n, rule, ast, tokens, first, last): if rule == ("or", ("expr", "jmp_true", "expr")): - if tokens[last] in ( - "LOAD_ASSERT", - "RAISE_VARARGS_1", - ): + if tokens[last] in ("LOAD_ASSERT", "RAISE_VARARGS_1",): return True # The following test is be the most accurate. It prevents "or" from being @@ -16,7 +13,7 @@ def or_check(self, lhs, n, rule, ast, tokens, first, last): # The below then is useful until we get better control-flow analysis. # Note it is too hard in the scanner right nowto turn the LOAD_GLOBAL into # int LOAD_ASSERT, however in 3.9ish code generation does this by default. - load_global = tokens[last-1] + load_global = tokens[last - 1] if load_global == "LOAD_GLOBAL" and load_global.attr == "AssertionError": return True @@ -24,11 +21,14 @@ def or_check(self, lhs, n, rule, ast, tokens, first, last): jmp_false = tokens[last] # If the jmp is backwards if jmp_false == "POP_JUMP_IF_FALSE": - if jmp_false.attr < jmp_false.off2int(): + jmp_false_offset = jmp_false.off2int() + if jmp_false.attr < jmp_false_offset: # For a backwards loop, well compare to the instruction *after* # then POP_JUMP... - jmp_false = tokens[last+1] - return not (jmp_true_target == jmp_false.off2int() or - jmp_true_target < tokens[first].off2int()) + jmp_false = tokens[last + 1] + return not ( + (jmp_false_offset <= jmp_true_target <= jmp_false_offset + 2) + or jmp_true_target < tokens[first].off2int() + ) return False diff --git a/uncompyle6/semantics/transform.py b/uncompyle6/semantics/transform.py index 07ac9c2a..c61353ec 100644 --- a/uncompyle6/semantics/transform.py +++ b/uncompyle6/semantics/transform.py @@ -287,6 +287,32 @@ class TreeTransform(GenericASTTraversal, object): n_ifelsestmtc = n_ifelsestmtl = n_ifelsestmt + def n_import_from37(self, node): + importlist37 = node[3] + assert importlist37 == "importlist37" + if len(importlist37) == 1: + alias37 = importlist37[0] + store = alias37[1] + assert store == "store" + alias_name = store[0].attr + import_name_attr = node[2] + assert import_name_attr == "IMPORT_NAME_ATTR" + dotted_names = import_name_attr.attr.split(".") + if len(dotted_names) > 1: + # Simulate: + # Instead of + # import_from37 ::= LOAD_CONST LOAD_CONST IMPORT_NAME_ATTR importlist37 POP_TOP + # import_as37 ::= LOAD_CONST LOAD_CONST importlist37 store POP_TOP + # 'import_as37': ( '%|import %c as %c\n', 2, -2), + assert dotted_names[-1] == alias_name + node = SyntaxTree("import_as37", + [node[0], node[1], import_name_attr, store, node[-1]]) + node.transformed_by="n_import_from37" + pass + pass + return node + + def n_list_for(self, list_for_node): expr = list_for_node[0] if expr == "expr" and expr[0] == "get_iter":