Skip to content

Commit 127dde5

Browse files
authored
bpo-42810: Mark jumps at end of if and try statements as artificial. (GH-24091)
* Mark jumps at end of if and try statements as artificial. * Update importlib * Add comment explaining the purpose of ADDOP_JUMP_NOLINE.
1 parent de833b6 commit 127dde5

File tree

5 files changed

+2244
-2185
lines changed

5 files changed

+2244
-2185
lines changed

Lib/test/test_sys_settrace.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,48 @@ def func():
874874
(5, 'line'),
875875
(5, 'return')])
876876

877+
def test_nested_ifs(self):
878+
879+
def func():
880+
a = b = 1
881+
if a == 1:
882+
if b == 1:
883+
x = 4
884+
else:
885+
y = 6
886+
else:
887+
z = 8
888+
889+
self.run_and_compare(func,
890+
[(0, 'call'),
891+
(1, 'line'),
892+
(2, 'line'),
893+
(3, 'line'),
894+
(4, 'line'),
895+
(4, 'return')])
896+
897+
def test_nested_try_if(self):
898+
899+
def func():
900+
x = "hello"
901+
try:
902+
3/0
903+
except ZeroDivisionError:
904+
if x == 'raise':
905+
raise ValueError() # line 6
906+
f = 7
907+
908+
self.run_and_compare(func,
909+
[(0, 'call'),
910+
(1, 'line'),
911+
(2, 'line'),
912+
(3, 'line'),
913+
(3, 'exception'),
914+
(4, 'line'),
915+
(5, 'line'),
916+
(7, 'line'),
917+
(7, 'return')])
918+
877919

878920
class SkipLineEventsTraceTestCase(TraceTestCase):
879921
"""Repeat the trace tests, but with per-line events skipped"""

Python/compile.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ static int compiler_next_instr(basicblock *);
207207
static int compiler_addop(struct compiler *, int);
208208
static int compiler_addop_i(struct compiler *, int, Py_ssize_t);
209209
static int compiler_addop_j(struct compiler *, int, basicblock *);
210+
static int compiler_addop_j_noline(struct compiler *, int, basicblock *);
210211
static int compiler_error(struct compiler *, const char *);
211212
static int compiler_warn(struct compiler *, const char *, ...);
212213
static int compiler_nameop(struct compiler *, identifier, expr_context_ty);
@@ -1425,6 +1426,12 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b)
14251426
return add_jump_to_block(c->u->u_curblock, opcode, c->u->u_lineno, b);
14261427
}
14271428

1429+
static int
1430+
compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b)
1431+
{
1432+
return add_jump_to_block(c->u->u_curblock, opcode, -1, b);
1433+
}
1434+
14281435
/* NEXT_BLOCK() creates an implicit jump from the current block
14291436
to the new block.
14301437
@@ -1495,6 +1502,14 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b)
14951502
return 0; \
14961503
}
14971504

1505+
/* Add a jump with no line number.
1506+
* Used for artificial jumps that have no corresponding
1507+
* token in the source code. */
1508+
#define ADDOP_JUMP_NOLINE(C, OP, O) { \
1509+
if (!compiler_addop_j_noline((C), (OP), (O))) \
1510+
return 0; \
1511+
}
1512+
14981513
#define ADDOP_COMPARE(C, CMP) { \
14991514
if (!compiler_addcompare((C), (cmpop_ty)(CMP))) \
15001515
return 0; \
@@ -2527,7 +2542,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond)
25272542
return 0;
25282543
if (!compiler_jump_if(c, e->v.IfExp.body, next, cond))
25292544
return 0;
2530-
ADDOP_JUMP(c, JUMP_FORWARD, end);
2545+
ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end);
25312546
compiler_use_next_block(c, next2);
25322547
if (!compiler_jump_if(c, e->v.IfExp.orelse, next, cond))
25332548
return 0;
@@ -2560,11 +2575,11 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond)
25602575
basicblock *end = compiler_new_block(c);
25612576
if (end == NULL)
25622577
return 0;
2563-
ADDOP_JUMP(c, JUMP_FORWARD, end);
2578+
ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end);
25642579
compiler_use_next_block(c, cleanup);
25652580
ADDOP(c, POP_TOP);
25662581
if (!cond) {
2567-
ADDOP_JUMP(c, JUMP_FORWARD, next);
2582+
ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, next);
25682583
}
25692584
compiler_use_next_block(c, end);
25702585
return 1;
@@ -2599,7 +2614,7 @@ compiler_ifexp(struct compiler *c, expr_ty e)
25992614
if (!compiler_jump_if(c, e->v.IfExp.test, next, 0))
26002615
return 0;
26012616
VISIT(c, expr, e->v.IfExp.body);
2602-
ADDOP_JUMP(c, JUMP_FORWARD, end);
2617+
ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end);
26032618
compiler_use_next_block(c, next);
26042619
VISIT(c, expr, e->v.IfExp.orelse);
26052620
compiler_use_next_block(c, end);
@@ -2686,7 +2701,7 @@ compiler_if(struct compiler *c, stmt_ty s)
26862701
}
26872702
VISIT_SEQ(c, stmt, s->v.If.body);
26882703
if (asdl_seq_LEN(s->v.If.orelse)) {
2689-
ADDOP_JUMP(c, JUMP_FORWARD, end);
2704+
ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end);
26902705
compiler_use_next_block(c, next);
26912706
VISIT_SEQ(c, stmt, s->v.If.orelse);
26922707
}
@@ -2945,7 +2960,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s)
29452960
ADDOP(c, POP_BLOCK);
29462961
compiler_pop_fblock(c, FINALLY_TRY, body);
29472962
VISIT_SEQ(c, stmt, s->v.Try.finalbody);
2948-
ADDOP_JUMP(c, JUMP_FORWARD, exit);
2963+
ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, exit);
29492964
/* `finally` block */
29502965
compiler_use_next_block(c, end);
29512966
if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL))
@@ -3094,6 +3109,8 @@ compiler_try_except(struct compiler *c, stmt_ty s)
30943109
return 0;
30953110
VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
30963111
compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
3112+
/* name = None; del name; # Mark as artificial */
3113+
c->u->u_lineno = -1;
30973114
ADDOP(c, POP_EXCEPT);
30983115
ADDOP_JUMP(c, JUMP_FORWARD, end);
30993116
}
@@ -3907,7 +3924,7 @@ compiler_compare(struct compiler *c, expr_ty e)
39073924
basicblock *end = compiler_new_block(c);
39083925
if (end == NULL)
39093926
return 0;
3910-
ADDOP_JUMP(c, JUMP_FORWARD, end);
3927+
ADDOP_JUMP_NOLINE(c, JUMP_FORWARD, end);
39113928
compiler_use_next_block(c, cleanup);
39123929
ADDOP(c, ROT_TWO);
39133930
ADDOP(c, POP_TOP);

0 commit comments

Comments
 (0)