From 9bd85fe5a09eda6ac413cd665d64a0f430c54540 Mon Sep 17 00:00:00 2001 From: rocky Date: Mon, 23 Sep 2019 08:23:31 -0400 Subject: [PATCH] Correct assert{,2} transforms Fixes #289 --- test/add-test.py | 15 +++++----- test/bytecode_3.7_run/01_assert2.pyc | Bin 0 -> 272 bytes test/simple_source/bug37/01_assert2.py | 8 ++++++ uncompyle6/semantics/customize.py | 38 ++++++++++++------------- uncompyle6/semantics/transform.py | 26 +++++++++++------ 5 files changed, 52 insertions(+), 35 deletions(-) create mode 100644 test/bytecode_3.7_run/01_assert2.pyc create mode 100644 test/simple_source/bug37/01_assert2.py diff --git a/test/add-test.py b/test/add-test.py index a5ea9ac6..758fe934 100755 --- a/test/add-test.py +++ b/test/add-test.py @@ -2,22 +2,23 @@ """ Trivial helper program to bytecompile and run an uncompile """ import os, sys, py_compile + assert len(sys.argv) >= 2 version = sys.version[0:3] -if sys.argv[1] == '--run': - suffix = '_run' +if sys.argv[1] in ("--run", "-r"): + suffix = "_run" py_source = sys.argv[2:] else: - suffix = '' + suffix = "" py_source = sys.argv[1:] for path in py_source: short = os.path.basename(path) - if hasattr(sys, 'pypy_version_info'): - cfile = "bytecode_pypy%s%s/%s" % (version, suffix, short) + 'c' + if hasattr(sys, "pypy_version_info"): + cfile = "bytecode_pypy%s%s/%s" % (version, suffix, short) + "c" else: - cfile = "bytecode_%s%s/%s" % (version, suffix, short) + 'c' + cfile = "bytecode_%s%s/%s" % (version, suffix, short) + "c" print("byte-compiling %s to %s" % (path, cfile)) py_compile.compile(path, cfile) if isinstance(version, str) or version >= (2, 6, 0): - os.system("../bin/uncompyle6 -a -t %s" % cfile) + os.system("../bin/uncompyle6 -a -T %s" % cfile) diff --git a/test/bytecode_3.7_run/01_assert2.pyc b/test/bytecode_3.7_run/01_assert2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..87af4c3913edc36fee80d7746847808dd6bd6b75 GIT binary patch literal 272 zcmZ?b<>g`kg2eS5u{(hDV-N=hn1BoiATAaG5-AKRj4cdN45j;Fn@?W^O@FYJ72iX;E^jeo|?=vAMp1VSHk7acWVCkzPUNEuNCp y;u4quNK-M0U|{56EMf!FFIjku}-? literal 0 HcmV?d00001 diff --git a/test/simple_source/bug37/01_assert2.py b/test/simple_source/bug37/01_assert2.py new file mode 100644 index 00000000..2973bb3f --- /dev/null +++ b/test/simple_source/bug37/01_assert2.py @@ -0,0 +1,8 @@ +# Self-checking test. +# Bug was in if transform not inverting expression +# This file is RUNNABLE! +def test_assert2(c): + if c < 2: + raise SyntaxError('Oops') + +test_assert2(5) diff --git a/uncompyle6/semantics/customize.py b/uncompyle6/semantics/customize.py index 1cfc2b5b..41c1346e 100644 --- a/uncompyle6/semantics/customize.py +++ b/uncompyle6/semantics/customize.py @@ -16,7 +16,7 @@ """Isolate Python version-specific semantic actions here. """ -from uncompyle6.semantics.consts import TABLE_R, TABLE_DIRECT +from uncompyle6.semantics.consts import PRECEDENCE, TABLE_R, TABLE_DIRECT from uncompyle6.parsers.treenode import SyntaxTree from uncompyle6.scanners.tok import Token @@ -27,29 +27,27 @@ def customize_for_version(self, is_pypy, version): ######################## # PyPy changes ####################### - TABLE_DIRECT.update( - { - "assert2_pypy": ("%|assert %c, %c\n", (1, "assert_expr"), 4), - "assert_pypy": ("%|assert %c\n", (1, "assert_expr")), - "assign2_pypy": ("%|%c, %c = %c, %c\n", 3, 2, 0, 1), - "assign3_pypy": ("%|%c, %c, %c = %c, %c, %c\n", 5, 4, 3, 0, 1, 2), - "try_except_pypy": ("%|try:\n%+%c%-%c\n\n", 1, 2), - "tryfinallystmt_pypy": ("%|try:\n%+%c%-%|finally:\n%+%c%-\n\n", 1, 3), - } - ) + TABLE_DIRECT.update({ + 'assert_pypy': ( '%|assert %c\n' , 1 ), + 'assert2_pypy': ( '%|assert %c, %c\n' , 1, 4 ), + 'try_except_pypy': ( '%|try:\n%+%c%-%c\n\n', 1, 2 ), + 'tryfinallystmt_pypy': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n', 1, 3 ), + 'assign3_pypy': ( '%|%c, %c, %c = %c, %c, %c\n', 5, 4, 3, 0, 1, 2 ), + 'assign2_pypy': ( '%|%c, %c = %c, %c\n', 3, 2, 0, 1), + }) else: ######################## # Without PyPy ####################### - TABLE_DIRECT.update( - { - "assert": ("%|assert %c\n", (0, "assert_expr")), - "assert2": ("%|assert %c, %c\n", (0, "assert_expr"), 3), - "assign2": ("%|%c, %c = %c, %c\n", 3, 4, 0, 1), - "assign3": ("%|%c, %c, %c = %c, %c, %c\n", 5, 6, 7, 0, 1, 2), - "try_except": ("%|try:\n%+%c%-%c\n\n", 1, 3), - } - ) + TABLE_DIRECT.update({ + "assert": ("%|assert %c\n", (0, "assert_expr")), + "assert2not": ( "%|assert not %p, %c\n" , + (0, PRECEDENCE['unary_not']), 3 ), + "assert2": ("%|assert %c, %c\n", (0, "assert_expr"), 3), + "assign2": ("%|%c, %c = %c, %c\n", 3, 4, 0, 1), + "assign3": ("%|%c, %c, %c = %c, %c, %c\n", 5, 6, 7, 0, 1, 2), + "try_except": ("%|try:\n%+%c%-%c\n\n", 1, 3), + }) if version >= 3.0: if version >= 3.2: TABLE_DIRECT.update( diff --git a/uncompyle6/semantics/transform.py b/uncompyle6/semantics/transform.py index 6d9e6d86..a194c964 100644 --- a/uncompyle6/semantics/transform.py +++ b/uncompyle6/semantics/transform.py @@ -88,7 +88,7 @@ class TreeTransform(GenericASTTraversal, object): if raise_stmt == "raise_stmt1" and len(testexpr[0]) == 2: assert_expr = testexpr[0][0] assert_expr.kind = "assert_expr" - jmp_true = testexpr[0][1] + jump_cond = testexpr[0][1] expr = raise_stmt[0] RAISE_VARARGS_1 = raise_stmt[1] if expr[0] == "call": @@ -105,15 +105,19 @@ class TreeTransform(GenericASTTraversal, object): # 1. RAISE_VARARGS_1 # becomes: # assert2 ::= assert_expr jmp_true LOAD_ASSERT expr RAISE_VARARGS_1 COME_FROM + if jump_cond == "jmp_true": + kind = "assert2" + else: + assert jump_cond == "jmp_false" + kind = "assert2not" + call = expr[0] LOAD_ASSERT = call[0] expr = call[1][0] node = SyntaxTree( - "assert2", - [assert_expr, jmp_true, LOAD_ASSERT, expr, RAISE_VARARGS_1] + kind, + [assert_expr, jump_cond, LOAD_ASSERT, expr, RAISE_VARARGS_1] ) - node.transformed_by="n_ifstmt", - else: # ifstmt # 0. testexpr (2) @@ -128,12 +132,18 @@ class TreeTransform(GenericASTTraversal, object): # 1. RAISE_VARARGS_1 # becomes: # assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1 COME_FROM + if jump_cond == "jmp_true": + kind = "assert" + else: + assert jump_cond == "jmp_false" + kind = "assertnot" + LOAD_ASSERT = expr[0] node = SyntaxTree( - "assert", - [assert_expr, jmp_true, LOAD_ASSERT, RAISE_VARARGS_1] + kind, + [assert_expr, jump_cond, LOAD_ASSERT, RAISE_VARARGS_1] ) - node.transformed_by="n_ifstmt", + node.transformed_by="n_ifstmt", pass pass return node