Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 48a9c0e

Browse filesBrowse files
authored
[3.9] bpo-39934: Account for control blocks in 'except' in compiler. (GH-22395) (GH-23303)
* bpo-39934: backport PR 22395 to 3.9
1 parent 05a5d69 commit 48a9c0e
Copy full SHA for 48a9c0e

File tree

3 files changed

+23
-8
lines changed
Filter options

3 files changed

+23
-8
lines changed

‎Lib/test/test_syntax.py

Copy file name to clipboardExpand all lines: Lib/test/test_syntax.py
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,15 @@ def test_empty_line_after_linecont(self):
946946
except SyntaxError:
947947
self.fail("Empty line after a line continuation character is valid.")
948948

949+
@support.cpython_only
950+
def test_nested_named_except_blocks(self):
951+
code = ""
952+
for i in range(12):
953+
code += f"{' '*i}try:\n"
954+
code += f"{' '*(i+1)}raise Exception\n"
955+
code += f"{' '*i}except Exception as e:\n"
956+
code += f"{' '*4*12}pass"
957+
self._check_error(code, "too many statically nested blocks")
949958

950959
def test_barry_as_flufl_with_syntax_errors(self):
951960
# The "barry_as_flufl" rule can produce some "bugs-at-a-distance" if
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Correctly count control blocks in 'except' in compiler. Ensures that a
2+
syntax error, rather a fatal error, occurs for deeply nested, named
3+
exception handlers.

‎Python/compile.c

Copy file name to clipboardExpand all lines: Python/compile.c
+11-8Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ It's called a frame block to distinguish it from a basic block in the
8484
compiler IR.
8585
*/
8686

87-
enum fblocktype { WHILE_LOOP, FOR_LOOP, EXCEPT, FINALLY_TRY, FINALLY_END,
88-
WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE };
87+
enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END,
88+
WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER };
8989

9090
struct fblockinfo {
9191
enum fblocktype fb_type;
@@ -1624,9 +1624,7 @@ compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b,
16241624
{
16251625
struct fblockinfo *f;
16261626
if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
1627-
PyErr_SetString(PyExc_SyntaxError,
1628-
"too many statically nested blocks");
1629-
return 0;
1627+
return compiler_error(c, "too many statically nested blocks");
16301628
}
16311629
f = &c->u->u_fblock[c->u->u_nfblocks++];
16321630
f->fb_type = t;
@@ -1666,6 +1664,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info,
16661664
{
16671665
switch (info->fb_type) {
16681666
case WHILE_LOOP:
1667+
case EXCEPTION_HANDLER:
16691668
return 1;
16701669

16711670
case FOR_LOOP:
@@ -1676,7 +1675,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info,
16761675
ADDOP(c, POP_TOP);
16771676
return 1;
16781677

1679-
case EXCEPT:
1678+
case TRY_EXCEPT:
16801679
ADDOP(c, POP_BLOCK);
16811680
return 1;
16821681

@@ -3064,14 +3063,17 @@ compiler_try_except(struct compiler *c, stmt_ty s)
30643063
return 0;
30653064
ADDOP_JREL(c, SETUP_FINALLY, except);
30663065
compiler_use_next_block(c, body);
3067-
if (!compiler_push_fblock(c, EXCEPT, body, NULL, NULL))
3066+
if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL))
30683067
return 0;
30693068
VISIT_SEQ(c, stmt, s->v.Try.body);
30703069
ADDOP(c, POP_BLOCK);
3071-
compiler_pop_fblock(c, EXCEPT, body);
3070+
compiler_pop_fblock(c, TRY_EXCEPT, body);
30723071
ADDOP_JREL(c, JUMP_FORWARD, orelse);
30733072
n = asdl_seq_LEN(s->v.Try.handlers);
30743073
compiler_use_next_block(c, except);
3074+
/* Runtime will push a block here, so we need to account for that */
3075+
if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NULL, NULL, NULL))
3076+
return 0;
30753077
for (i = 0; i < n; i++) {
30763078
excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
30773079
s->v.Try.handlers, i);
@@ -3156,6 +3158,7 @@ compiler_try_except(struct compiler *c, stmt_ty s)
31563158
}
31573159
compiler_use_next_block(c, except);
31583160
}
3161+
compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL);
31593162
ADDOP(c, RERAISE);
31603163
compiler_use_next_block(c, orelse);
31613164
VISIT_SEQ(c, stmt, s->v.Try.orelse);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.