Correct assert{,2} transforms

Fixes #289
This commit is contained in:
rocky
2019-09-23 08:23:31 -04:00
parent c6e3168c31
commit 9bd85fe5a0
5 changed files with 52 additions and 35 deletions

View File

@@ -2,22 +2,23 @@
""" Trivial helper program to bytecompile and run an uncompile """ Trivial helper program to bytecompile and run an uncompile
""" """
import os, sys, py_compile import os, sys, py_compile
assert len(sys.argv) >= 2 assert len(sys.argv) >= 2
version = sys.version[0:3] version = sys.version[0:3]
if sys.argv[1] == '--run': if sys.argv[1] in ("--run", "-r"):
suffix = '_run' suffix = "_run"
py_source = sys.argv[2:] py_source = sys.argv[2:]
else: else:
suffix = '' suffix = ""
py_source = sys.argv[1:] py_source = sys.argv[1:]
for path in py_source: for path in py_source:
short = os.path.basename(path) short = os.path.basename(path)
if hasattr(sys, 'pypy_version_info'): if hasattr(sys, "pypy_version_info"):
cfile = "bytecode_pypy%s%s/%s" % (version, suffix, short) + 'c' cfile = "bytecode_pypy%s%s/%s" % (version, suffix, short) + "c"
else: 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)) print("byte-compiling %s to %s" % (path, cfile))
py_compile.compile(path, cfile) py_compile.compile(path, cfile)
if isinstance(version, str) or version >= (2, 6, 0): 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)

Binary file not shown.

View File

@@ -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)

View File

@@ -16,7 +16,7 @@
"""Isolate Python version-specific semantic actions here. """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.parsers.treenode import SyntaxTree
from uncompyle6.scanners.tok import Token from uncompyle6.scanners.tok import Token
@@ -27,29 +27,27 @@ def customize_for_version(self, is_pypy, version):
######################## ########################
# PyPy changes # PyPy changes
####################### #######################
TABLE_DIRECT.update( TABLE_DIRECT.update({
{ 'assert_pypy': ( '%|assert %c\n' , 1 ),
"assert2_pypy": ("%|assert %c, %c\n", (1, "assert_expr"), 4), 'assert2_pypy': ( '%|assert %c, %c\n' , 1, 4 ),
"assert_pypy": ("%|assert %c\n", (1, "assert_expr")), 'try_except_pypy': ( '%|try:\n%+%c%-%c\n\n', 1, 2 ),
"assign2_pypy": ("%|%c, %c = %c, %c\n", 3, 2, 0, 1), '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), '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), 'assign2_pypy': ( '%|%c, %c = %c, %c\n', 3, 2, 0, 1),
"tryfinallystmt_pypy": ("%|try:\n%+%c%-%|finally:\n%+%c%-\n\n", 1, 3), })
}
)
else: else:
######################## ########################
# Without PyPy # Without PyPy
####################### #######################
TABLE_DIRECT.update( TABLE_DIRECT.update({
{ "assert": ("%|assert %c\n", (0, "assert_expr")),
"assert": ("%|assert %c\n", (0, "assert_expr")), "assert2not": ( "%|assert not %p, %c\n" ,
"assert2": ("%|assert %c, %c\n", (0, "assert_expr"), 3), (0, PRECEDENCE['unary_not']), 3 ),
"assign2": ("%|%c, %c = %c, %c\n", 3, 4, 0, 1), "assert2": ("%|assert %c, %c\n", (0, "assert_expr"), 3),
"assign3": ("%|%c, %c, %c = %c, %c, %c\n", 5, 6, 7, 0, 1, 2), "assign2": ("%|%c, %c = %c, %c\n", 3, 4, 0, 1),
"try_except": ("%|try:\n%+%c%-%c\n\n", 1, 3), "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.0:
if version >= 3.2: if version >= 3.2:
TABLE_DIRECT.update( TABLE_DIRECT.update(

View File

@@ -88,7 +88,7 @@ class TreeTransform(GenericASTTraversal, object):
if raise_stmt == "raise_stmt1" and len(testexpr[0]) == 2: if raise_stmt == "raise_stmt1" and len(testexpr[0]) == 2:
assert_expr = testexpr[0][0] assert_expr = testexpr[0][0]
assert_expr.kind = "assert_expr" assert_expr.kind = "assert_expr"
jmp_true = testexpr[0][1] jump_cond = testexpr[0][1]
expr = raise_stmt[0] expr = raise_stmt[0]
RAISE_VARARGS_1 = raise_stmt[1] RAISE_VARARGS_1 = raise_stmt[1]
if expr[0] == "call": if expr[0] == "call":
@@ -105,15 +105,19 @@ class TreeTransform(GenericASTTraversal, object):
# 1. RAISE_VARARGS_1 # 1. RAISE_VARARGS_1
# becomes: # becomes:
# assert2 ::= assert_expr jmp_true LOAD_ASSERT expr RAISE_VARARGS_1 COME_FROM # 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] call = expr[0]
LOAD_ASSERT = call[0] LOAD_ASSERT = call[0]
expr = call[1][0] expr = call[1][0]
node = SyntaxTree( node = SyntaxTree(
"assert2", kind,
[assert_expr, jmp_true, LOAD_ASSERT, expr, RAISE_VARARGS_1] [assert_expr, jump_cond, LOAD_ASSERT, expr, RAISE_VARARGS_1]
) )
node.transformed_by="n_ifstmt",
else: else:
# ifstmt # ifstmt
# 0. testexpr (2) # 0. testexpr (2)
@@ -128,12 +132,18 @@ class TreeTransform(GenericASTTraversal, object):
# 1. RAISE_VARARGS_1 # 1. RAISE_VARARGS_1
# becomes: # becomes:
# assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1 COME_FROM # 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] LOAD_ASSERT = expr[0]
node = SyntaxTree( node = SyntaxTree(
"assert", kind,
[assert_expr, jmp_true, LOAD_ASSERT, RAISE_VARARGS_1] [assert_expr, jump_cond, LOAD_ASSERT, RAISE_VARARGS_1]
) )
node.transformed_by="n_ifstmt", node.transformed_by="n_ifstmt",
pass pass
pass pass
return node return node