Merge pull request #413 from Berbe/for-loop

Fix: CONTINUE in else block in a for loop
This commit is contained in:
R. Bernstein
2022-10-16 17:46:26 -04:00
committed by GitHub
4 changed files with 62 additions and 6 deletions

Binary file not shown.

View 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"

View File

@@ -142,6 +142,7 @@ class Python27Parser(Python2Parser):
def p_stmt27(self, args):
"""
stmt ::= ifelsestmtr
stmt ::= ifelsestmtc
# assert condition
assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1
@@ -194,6 +195,7 @@ class Python27Parser(Python2Parser):
ifstmt ::= testexpr return_if_stmts COME_FROM
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_FORWARD else_suite come_froms
ifelsestmtl ::= testexpr c_stmts_opt JUMP_BACK else_suitel
ifelsestmtl ::= testexpr c_stmts_opt CONTINUE else_suitel
@@ -242,6 +244,7 @@ class Python27Parser(Python2Parser):
"except_handler": except_handler,
"for_block": for_block_check.for_block_invalid,
"ifelsestmt": ifelsestmt,
"ifelsestmtc": ifelsestmt,
"or": or_check,
"tryelsestmt": tryelsestmt,
"tryelsestmtl": tryelsestmt,
@@ -258,8 +261,9 @@ class Python27Parser(Python2Parser):
self.check_reduce["or"] = "AST"
self.check_reduce["raise_stmt1"] = "AST"
self.check_reduce["iflaststmtl"] = "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"] = "AST"
self.check_reduce["comp_if"] = "AST"

View File

@@ -4,7 +4,7 @@ from uncompyle6.scanners.tok import Token
IFELSE_STMT_RULES = frozenset(
[
(
(
"ifelsestmt",
(
"testexpr",
@@ -52,6 +52,15 @@ IFELSE_STMT_RULES = frozenset(
"else_suitec",
),
),
(
"ifelsestmtc",
(
"testexpr",
"c_stmts_opt",
"JUMP_ABSOLUTE",
"else_suitec",
),
),
(
"ifelsestmt",
(
@@ -74,7 +83,13 @@ IFELSE_STMT_RULES = frozenset(
),
(
"ifelsestmt",
("testexpr", "c_stmts", "come_froms", "else_suite", "come_froms",),
(
"testexpr",
"c_stmts",
"come_froms",
"else_suite",
"come_froms",
),
),
(
"ifelsestmt",
@@ -112,7 +127,8 @@ IFELSE_STMT_RULES = frozenset(
"stmts",
"jf_cfs",
"\\e_else_suite_opt",
"\\e_opt_come_from_except")
"\\e_opt_come_from_except",
),
),
(
"ifelsestmt",
@@ -121,9 +137,12 @@ IFELSE_STMT_RULES = frozenset(
"stmts",
"jf_cfs",
"\\e_else_suite_opt",
"opt_come_from_except")
"opt_come_from_except",
),
),
])
]
)
def ifelsestmt(self, lhs, n, rule, tree, tokens, first, last):