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 02d126a

Browse filesBrowse files
authored
bpo-39934: Account for control blocks in 'except' in compiler. (GH-22395)
* Account for control blocks in 'except' in compiler. Fixes #39934.
1 parent 05cc881 commit 02d126a
Copy full SHA for 02d126a

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
@@ -950,6 +950,15 @@ def test_empty_line_after_linecont(self):
950950
except SyntaxError:
951951
self.fail("Empty line after a line continuation character is valid.")
952952

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

954963
def test_main():
955964
support.run_unittest(SyntaxTestCase)
+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
@@ -108,8 +108,8 @@ It's called a frame block to distinguish it from a basic block in the
108108
compiler IR.
109109
*/
110110

111-
enum fblocktype { WHILE_LOOP, FOR_LOOP, EXCEPT, FINALLY_TRY, FINALLY_END,
112-
WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE };
111+
enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END,
112+
WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER };
113113

114114
struct fblockinfo {
115115
enum fblocktype fb_type;
@@ -1623,9 +1623,7 @@ compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b,
16231623
{
16241624
struct fblockinfo *f;
16251625
if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
1626-
PyErr_SetString(PyExc_SyntaxError,
1627-
"too many statically nested blocks");
1628-
return 0;
1626+
return compiler_error(c, "too many statically nested blocks");
16291627
}
16301628
f = &c->u->u_fblock[c->u->u_nfblocks++];
16311629
f->fb_type = t;
@@ -1665,6 +1663,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info,
16651663
{
16661664
switch (info->fb_type) {
16671665
case WHILE_LOOP:
1666+
case EXCEPTION_HANDLER:
16681667
return 1;
16691668

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

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

@@ -3060,14 +3059,17 @@ compiler_try_except(struct compiler *c, stmt_ty s)
30603059
return 0;
30613060
ADDOP_JUMP(c, SETUP_FINALLY, except);
30623061
compiler_use_next_block(c, body);
3063-
if (!compiler_push_fblock(c, EXCEPT, body, NULL, NULL))
3062+
if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL))
30643063
return 0;
30653064
VISIT_SEQ(c, stmt, s->v.Try.body);
30663065
ADDOP(c, POP_BLOCK);
3067-
compiler_pop_fblock(c, EXCEPT, body);
3066+
compiler_pop_fblock(c, TRY_EXCEPT, body);
30683067
ADDOP_JUMP(c, JUMP_FORWARD, orelse);
30693068
n = asdl_seq_LEN(s->v.Try.handlers);
30703069
compiler_use_next_block(c, except);
3070+
/* Runtime will push a block here, so we need to account for that */
3071+
if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NULL, NULL, NULL))
3072+
return 0;
30713073
for (i = 0; i < n; i++) {
30723074
excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
30733075
s->v.Try.handlers, i);
@@ -3152,6 +3154,7 @@ compiler_try_except(struct compiler *c, stmt_ty s)
31523154
}
31533155
compiler_use_next_block(c, except);
31543156
}
3157+
compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL);
31553158
ADDOP(c, RERAISE);
31563159
compiler_use_next_block(c, orelse);
31573160
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.