You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 09:22:40 +08:00
Merge branch 'master' into python-3.3-to-3.5
This commit is contained in:
Binary file not shown.
BIN
test/bytecode_2.5_run/05_long_literals24.pyc
Normal file
BIN
test/bytecode_2.5_run/05_long_literals24.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_2.7_run/07_for_if_else-continue.pyc
Normal file
BIN
test/bytecode_2.7_run/07_for_if_else-continue.pyc
Normal file
Binary file not shown.
33
test/simple_source/bug27+/07_for_if_else-continue.py
Normal file
33
test/simple_source/bug27+/07_for_if_else-continue.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Issue #413 on 2.7
|
||||||
|
# Bug in handling CONTINUE in else block of if-then-else in a for loop
|
||||||
|
|
||||||
|
"""This program is self-checking!"""
|
||||||
|
def test1(a, r = None):
|
||||||
|
for b in a:
|
||||||
|
if b:
|
||||||
|
r = b
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
raise AssertionError("CONTINUE not followed")
|
||||||
|
if b:
|
||||||
|
pass
|
||||||
|
return r
|
||||||
|
|
||||||
|
def test2(a, r = None):
|
||||||
|
for b in a:
|
||||||
|
if b:
|
||||||
|
#pass # No payload
|
||||||
|
continue
|
||||||
|
raise AssertionError("CONTINUE not followed")
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
raise AssertionError("CONTINUE not followed")
|
||||||
|
if b:
|
||||||
|
r = b
|
||||||
|
raise AssertionError("CONTINUE not followed")
|
||||||
|
return r
|
||||||
|
|
||||||
|
assert test1([True]) == True, "Incorrect flow"
|
||||||
|
assert test2([True]) is None, "Incorrect flow"
|
||||||
|
assert test1([False]) is None, "Incorrect flow"
|
||||||
|
assert test2([False]) is None, "Incorrect flow"
|
@@ -1,34 +1,43 @@
|
|||||||
SKIP_TESTS=(
|
SKIP_TESTS=(
|
||||||
[test_cgi.py]=1 # FIXME: Works on c90ff51
|
# raise ValueError("str arguments must be keys in sys.modules")
|
||||||
|
# ValueError: str arguments must be keys in sys.modules
|
||||||
|
[test_collections.py]=1
|
||||||
|
|
||||||
|
[test_asyncore.py]=1
|
||||||
|
[test_bdb.py]=1
|
||||||
|
[test_bisect.py]=1
|
||||||
[test_bsddb3.py]=1 # test takes too long to run: 110 seconds
|
[test_bsddb3.py]=1 # test takes too long to run: 110 seconds
|
||||||
|
[test_coercion.py]=1 # Code introspects on co_consts in a non-decompilable way
|
||||||
[test_compile.py]=1 # Code introspects on co_consts in a non-decompilable way
|
[test_compile.py]=1 # Code introspects on co_consts in a non-decompilable way
|
||||||
|
[test_complex.py]=1
|
||||||
[test_curses.py]=1 # Possibly fails on its own but not detected
|
[test_curses.py]=1 # Possibly fails on its own but not detected
|
||||||
[test_cmd_line.py]=1 # Takes too long, maybe hangs, or looking for interactive input?
|
[test_cmd_line.py]=1 # Takes too long, maybe hangs, or looking for interactive input?
|
||||||
|
[test_datetime.py]=1
|
||||||
|
[test_decimal.py]=1
|
||||||
|
[test_deque.py]=1
|
||||||
|
[test_descr.py]=1
|
||||||
|
[test_dictcomps.py]=1
|
||||||
[test_dis.py]=1 # We change line numbers - duh!
|
[test_dis.py]=1 # We change line numbers - duh!
|
||||||
[test_doctest.py]=1 # Fails on its own
|
[test_doctest.py]=1 # Fails on its own
|
||||||
[test_exceptions.py]=1
|
[test_doctest2.py]=1 # Fails on its own
|
||||||
|
|
||||||
[test_format.py]=1 # Control flow "and" vs nested "if"
|
[test_format.py]=1 # Control flow "and" vs nested "if"
|
||||||
|
[test_float.py]=1
|
||||||
[test_grp.py]=1 # test takes to long, works interactively though
|
[test_grp.py]=1 # test takes to long, works interactively though
|
||||||
[test_io.py]=1 # Test takes too long to run
|
[test_io.py]=1 # Test takes too long to run
|
||||||
[test_ioctl.py]=1 # Test takes too long to run
|
[test_ioctl.py]=1 # Test takes too long to run
|
||||||
[test_lib2to3.py]=1 # test takes too long to run: 28 seconds
|
[test_lib2to3.py]=1 # test takes too long to run: 28 seconds
|
||||||
[test_math.py]=1
|
|
||||||
[test_memoryio.py]=1 # FIX
|
[test_memoryio.py]=1 # FIX
|
||||||
[test_modulefinder.py]=1 # FIX
|
|
||||||
[test_multiprocessing.py]=1 # On uncompyle2, takes 24 secs
|
[test_multiprocessing.py]=1 # On uncompyle2, takes 24 secs
|
||||||
[test_poll.py]=1 # test takes too long to run: 11 seconds
|
[test_poll.py]=1 # test takes too long to run: 11 seconds
|
||||||
[test_regrtest.py]=1 #
|
[test_regrtest.py]=1 #
|
||||||
[test_runpy.py]=1 # Long and fails on its own
|
[test_runpy.py]=1 # Long and fails on its own
|
||||||
[test_select.py]=1 # Runs okay but takes 11 seconds
|
|
||||||
[test_socket.py]=1 # Runs ok but takes 22 seconds
|
[test_socket.py]=1 # Runs ok but takes 22 seconds
|
||||||
[test_ssl.py]=1 #
|
[test_ssl.py]=1 #
|
||||||
[test_subprocess.py]=1 # Runs ok but takes 22 seconds
|
[test_subprocess.py]=1 # Runs ok but takes 22 seconds
|
||||||
[test_sys_settrace.py]=1 # Line numbers are expected to be different
|
[test_sys_settrace.py]=1 # Line numbers are expected to be different
|
||||||
|
|
||||||
[test_tokenize.py]=1 # test takes too long to run: 19 seconds
|
|
||||||
[test_traceback.py]=1 # Line numbers change - duh.
|
[test_traceback.py]=1 # Line numbers change - duh.
|
||||||
[test_unicode.py]=1 # Too long to run 11 seconds
|
|
||||||
[test_xpickle.py]=1 # Runs ok but takes 72 seconds
|
[test_xpickle.py]=1 # Runs ok but takes 72 seconds
|
||||||
[test_zipfile64.py]=1 # Runs ok but takes 204 seconds
|
[test_zipfile64.py]=1 # Runs ok but takes 204 seconds
|
||||||
[test_zipimport.py]=1 #
|
[test_zipimport.py]=1 #
|
||||||
|
@@ -142,6 +142,7 @@ class Python27Parser(Python2Parser):
|
|||||||
def p_stmt27(self, args):
|
def p_stmt27(self, args):
|
||||||
"""
|
"""
|
||||||
stmt ::= ifelsestmtr
|
stmt ::= ifelsestmtr
|
||||||
|
stmt ::= ifelsestmtc
|
||||||
|
|
||||||
# assert condition
|
# assert condition
|
||||||
assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1
|
assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1
|
||||||
@@ -194,6 +195,7 @@ class Python27Parser(Python2Parser):
|
|||||||
ifstmt ::= testexpr return_if_stmts COME_FROM
|
ifstmt ::= testexpr return_if_stmts COME_FROM
|
||||||
ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite come_froms
|
ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite come_froms
|
||||||
ifelsestmtc ::= testexpr c_stmts_opt JUMP_ABSOLUTE else_suitec
|
ifelsestmtc ::= testexpr c_stmts_opt JUMP_ABSOLUTE else_suitec
|
||||||
|
ifelsestmtc ::= testexpr c_stmts_opt JUMP_FORWARD else_suite come_froms
|
||||||
ifelsestmtl ::= testexpr c_stmts_opt JUMP_BACK else_suitel
|
ifelsestmtl ::= testexpr c_stmts_opt JUMP_BACK else_suitel
|
||||||
ifelsestmtl ::= testexpr c_stmts_opt CONTINUE else_suitel
|
ifelsestmtl ::= testexpr c_stmts_opt CONTINUE else_suitel
|
||||||
|
|
||||||
@@ -242,6 +244,7 @@ class Python27Parser(Python2Parser):
|
|||||||
"except_handler": except_handler,
|
"except_handler": except_handler,
|
||||||
"for_block": for_block_check.for_block_invalid,
|
"for_block": for_block_check.for_block_invalid,
|
||||||
"ifelsestmt": ifelsestmt,
|
"ifelsestmt": ifelsestmt,
|
||||||
|
"ifelsestmtc": ifelsestmt,
|
||||||
"or": or_check,
|
"or": or_check,
|
||||||
"tryelsestmt": tryelsestmt,
|
"tryelsestmt": tryelsestmt,
|
||||||
"tryelsestmtl": tryelsestmt,
|
"tryelsestmtl": tryelsestmt,
|
||||||
@@ -258,8 +261,9 @@ class Python27Parser(Python2Parser):
|
|||||||
|
|
||||||
self.check_reduce["or"] = "AST"
|
self.check_reduce["or"] = "AST"
|
||||||
self.check_reduce["raise_stmt1"] = "AST"
|
self.check_reduce["raise_stmt1"] = "AST"
|
||||||
self.check_reduce["iflaststmtl"] = "AST"
|
|
||||||
self.check_reduce["ifelsestmt"] = "AST"
|
self.check_reduce["ifelsestmt"] = "AST"
|
||||||
|
self.check_reduce["ifelsestmtc"] = "AST"
|
||||||
|
self.check_reduce["iflaststmtl"] = "AST"
|
||||||
self.check_reduce["list_if_not"] = "AST"
|
self.check_reduce["list_if_not"] = "AST"
|
||||||
self.check_reduce["list_if"] = "AST"
|
self.check_reduce["list_if"] = "AST"
|
||||||
self.check_reduce["comp_if"] = "AST"
|
self.check_reduce["comp_if"] = "AST"
|
||||||
|
@@ -52,6 +52,15 @@ IFELSE_STMT_RULES = frozenset(
|
|||||||
"else_suitec",
|
"else_suitec",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"ifelsestmtc",
|
||||||
|
(
|
||||||
|
"testexpr",
|
||||||
|
"c_stmts_opt",
|
||||||
|
"JUMP_ABSOLUTE",
|
||||||
|
"else_suitec",
|
||||||
|
),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"ifelsestmt",
|
"ifelsestmt",
|
||||||
(
|
(
|
||||||
@@ -74,7 +83,13 @@ IFELSE_STMT_RULES = frozenset(
|
|||||||
),
|
),
|
||||||
(
|
(
|
||||||
"ifelsestmt",
|
"ifelsestmt",
|
||||||
("testexpr", "c_stmts", "come_froms", "else_suite", "come_froms",),
|
(
|
||||||
|
"testexpr",
|
||||||
|
"c_stmts",
|
||||||
|
"come_froms",
|
||||||
|
"else_suite",
|
||||||
|
"come_froms",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"ifelsestmt",
|
"ifelsestmt",
|
||||||
@@ -112,7 +127,8 @@ IFELSE_STMT_RULES = frozenset(
|
|||||||
"stmts",
|
"stmts",
|
||||||
"jf_cfs",
|
"jf_cfs",
|
||||||
"\\e_else_suite_opt",
|
"\\e_else_suite_opt",
|
||||||
"\\e_opt_come_from_except")
|
"\\e_opt_come_from_except",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"ifelsestmt",
|
"ifelsestmt",
|
||||||
@@ -121,9 +137,12 @@ IFELSE_STMT_RULES = frozenset(
|
|||||||
"stmts",
|
"stmts",
|
||||||
"jf_cfs",
|
"jf_cfs",
|
||||||
"\\e_else_suite_opt",
|
"\\e_else_suite_opt",
|
||||||
"opt_come_from_except")
|
"opt_come_from_except",
|
||||||
),
|
),
|
||||||
])
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def ifelsestmt(self, lhs, n, rule, tree, tokens, first, last):
|
def ifelsestmt(self, lhs, n, rule, tree, tokens, first, last):
|
||||||
|
|
||||||
@@ -176,7 +195,11 @@ def ifelsestmt(self, lhs, n, rule, tree, tokens, first, last):
|
|||||||
else:
|
else:
|
||||||
last_token = tokens[last]
|
last_token = tokens[last]
|
||||||
if last_token == "COME_FROM" and first_offset > last_token.attr:
|
if last_token == "COME_FROM" and first_offset > last_token.attr:
|
||||||
if self.version < (3, 0) and self.insts[self.offset2inst_index[last_token.attr]].opname != "SETUP_LOOP":
|
if (
|
||||||
|
self.version < (3, 0)
|
||||||
|
and self.insts[self.offset2inst_index[last_token.attr]].opname
|
||||||
|
!= "SETUP_LOOP"
|
||||||
|
):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
testexpr = tree[0]
|
testexpr = tree[0]
|
||||||
@@ -198,7 +221,6 @@ def ifelsestmt(self, lhs, n, rule, tree, tokens, first, last):
|
|||||||
else:
|
else:
|
||||||
jmp_target = int(jmp[0].pattr)
|
jmp_target = int(jmp[0].pattr)
|
||||||
|
|
||||||
|
|
||||||
# Below we check that jmp_target is jumping to a feasible
|
# Below we check that jmp_target is jumping to a feasible
|
||||||
# location. It should be to the transition after the "then"
|
# location. It should be to the transition after the "then"
|
||||||
# block and to the beginning of the "else" block.
|
# block and to the beginning of the "else" block.
|
||||||
@@ -240,6 +262,32 @@ def ifelsestmt(self, lhs, n, rule, tree, tokens, first, last):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
if first_offset > jmp_target:
|
if first_offset > jmp_target:
|
||||||
|
# A backward or loop jump from the end of an "else"
|
||||||
|
# clause before the beginning of the "if" test is okay
|
||||||
|
# only if we are trying to match or reduce an "if"
|
||||||
|
# statement of the kind that can occur only inside a
|
||||||
|
# loop construct.
|
||||||
|
if lhs in ("ifelsestmtl", "ifelsestmtc"):
|
||||||
|
jump_false = jmp
|
||||||
|
if (
|
||||||
|
tree[2].kind == "JUMP_FORWARD"
|
||||||
|
and jump_false == "jmp_false"
|
||||||
|
and len(else_suite) == 1
|
||||||
|
):
|
||||||
|
suite_stmts = else_suite[0]
|
||||||
|
continue_stmt = suite_stmts[0]
|
||||||
|
if (
|
||||||
|
suite_stmts == "suite_stmts"
|
||||||
|
and len(suite_stmts) == 1
|
||||||
|
and continue_stmt == "continue"
|
||||||
|
and jump_false[0].attr == continue_stmt[0].attr
|
||||||
|
):
|
||||||
|
# for ...:
|
||||||
|
# if ...:
|
||||||
|
# ...
|
||||||
|
# else:
|
||||||
|
# continue
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return (jmp_target > last_offset) and tokens[last] != "JUMP_FORWARD"
|
return (jmp_target > last_offset) and tokens[last] != "JUMP_FORWARD"
|
||||||
|
Reference in New Issue
Block a user