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')
|
raise SyntaxError('Oops')
|
||||||
|
|
||||||
test_assert2(5)
|
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
|
stmt ::= classdefdeco
|
||||||
classdefdeco ::= classdefdeco1 store
|
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
|
expr ::= LOAD_ASSERT
|
||||||
|
|
||||||
ifstmt ::= testexpr _ifstmts_jump
|
ifstmt ::= testexpr _ifstmts_jump
|
||||||
|
@@ -3,6 +3,23 @@
|
|||||||
|
|
||||||
def or_check(self, lhs, n, rule, ast, tokens, first, last):
|
def or_check(self, lhs, n, rule, ast, tokens, first, last):
|
||||||
if rule == ("or", ("expr", "jmp_true", "expr")):
|
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_true_target = ast[1][0].attr
|
||||||
jmp_false = tokens[last]
|
jmp_false = tokens[last]
|
||||||
# If the jmp is backwards
|
# 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]
|
jmp_false = tokens[last+1]
|
||||||
return not (jmp_true_target == jmp_false.off2int() or
|
return not (jmp_true_target == jmp_false.off2int() or
|
||||||
jmp_true_target < tokens[first].off2int())
|
jmp_true_target < tokens[first].off2int())
|
||||||
return tokens[last] in (
|
|
||||||
"LOAD_ASSERT",
|
|
||||||
"RAISE_VARARGS_1",
|
|
||||||
)
|
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
@@ -48,8 +48,8 @@ def customize_for_version(self, is_pypy, version):
|
|||||||
#######################
|
#######################
|
||||||
TABLE_DIRECT.update({
|
TABLE_DIRECT.update({
|
||||||
# "assert" and "assert_expr" are added via transform rules.
|
# "assert" and "assert_expr" are added via transform rules.
|
||||||
"assert": ("%|assert %c\n", (0, "assert_expr")),
|
"assert": ("%|assert %c\n", 0),
|
||||||
"assert2": ("%|assert %c, %c\n", (0, "assert_expr"), 3),
|
"assert2": ("%|assert %c, %c\n", 0, 3),
|
||||||
|
|
||||||
# Created only via transformation
|
# Created only via transformation
|
||||||
"assertnot": ("%|assert not %p\n", (0, PRECEDENCE['unary_not'])),
|
"assertnot": ("%|assert not %p\n", (0, PRECEDENCE['unary_not'])),
|
||||||
|
Reference in New Issue
Block a user