You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
3.7+ "or" disambiguation and assert2 handling
This commit is contained in:
Binary file not shown.
@@ -6,3 +6,13 @@ def test_assert2(c):
|
||||
raise SyntaxError('Oops')
|
||||
|
||||
test_assert2(5)
|
||||
|
||||
# Bug is handling "assert" and confusing it with "or".
|
||||
# It is important that the assert be at the end of the loop.
|
||||
for x in (2, 4, 6):
|
||||
assert x == x
|
||||
|
||||
# Bug in 3.7 was not having a rule for 2-arg assert.
|
||||
# 2-arg assert code doesn't match "if not ... raise "
|
||||
for x in (1, 3, 5):
|
||||
assert x == x, "foo"
|
||||
|
@@ -760,6 +760,10 @@ class Python37Parser(Python37BaseParser):
|
||||
stmt ::= classdefdeco
|
||||
classdefdeco ::= classdefdeco1 store
|
||||
|
||||
# In 3.7 there are some LOAD_GLOBALs we don't convert to LOAD_ASSERT
|
||||
stmt ::= assert2
|
||||
assert2 ::= expr jmp_true LOAD_GLOBAL expr CALL_FUNCTION_1 RAISE_VARARGS_1
|
||||
|
||||
expr ::= LOAD_ASSERT
|
||||
|
||||
ifstmt ::= testexpr _ifstmts_jump
|
||||
|
@@ -3,6 +3,23 @@
|
||||
|
||||
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",
|
||||
):
|
||||
return True
|
||||
|
||||
# The following test is be the most accurate. It prevents "or" from being
|
||||
# mistake for part of an "assert".
|
||||
# There one might conceivably be "expr or AssertionError" code, but the
|
||||
# likelihood of that is vanishingly small.
|
||||
# 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]
|
||||
if load_global == "LOAD_GLOBAL" and load_global.attr == "AssertionError":
|
||||
return True
|
||||
|
||||
jmp_true_target = ast[1][0].attr
|
||||
jmp_false = tokens[last]
|
||||
# If the jmp is backwards
|
||||
@@ -13,9 +30,5 @@ def or_check(self, lhs, n, rule, ast, tokens, first, last):
|
||||
jmp_false = tokens[last+1]
|
||||
return not (jmp_true_target == jmp_false.off2int() or
|
||||
jmp_true_target < tokens[first].off2int())
|
||||
return tokens[last] in (
|
||||
"LOAD_ASSERT",
|
||||
"RAISE_VARARGS_1",
|
||||
)
|
||||
|
||||
return False
|
||||
|
@@ -48,8 +48,8 @@ def customize_for_version(self, is_pypy, version):
|
||||
#######################
|
||||
TABLE_DIRECT.update({
|
||||
# "assert" and "assert_expr" are added via transform rules.
|
||||
"assert": ("%|assert %c\n", (0, "assert_expr")),
|
||||
"assert2": ("%|assert %c, %c\n", (0, "assert_expr"), 3),
|
||||
"assert": ("%|assert %c\n", 0),
|
||||
"assert2": ("%|assert %c, %c\n", 0, 3),
|
||||
|
||||
# Created only via transformation
|
||||
"assertnot": ("%|assert not %p\n", (0, PRECEDENCE['unary_not'])),
|
||||
|
Reference in New Issue
Block a user