Skip to content
Merged
29 changes: 29 additions & 0 deletions Lib/test/test_monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -1681,6 +1681,35 @@ async def foo():
('branch left', 'func', 12, 12)])


def test_match(self):

def func(v=1):
x = 0
for v in range(4):
match v:
case 1:
x += 1
case 2:
x += 2
case _:
x += 3
return x

self.check_events(func, recorders = BRANCHES_RECORDERS, expected = [
('branch left', 'func', 2, 2),
('branch right', 'func', 4, 6),
('branch right', 'func', 6, 8),
('branch left', 'func', 2, 2),
('branch left', 'func', 4, 5),
('branch left', 'func', 2, 2),
('branch right', 'func', 4, 6),
('branch left', 'func', 6, 7),
('branch left', 'func', 2, 2),
('branch right', 'func', 4, 6),
('branch right', 'func', 6, 8),
('branch right', 'func', 2, 10)])


class TestBranchConsistency(MonitoringTestBase, unittest.TestCase):

def check_branches(self, func, tool=TEST_TOOL, recorders=BRANCH_OFFSET_RECORDERS):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Make sure that the location of branch targets in ``match`` cases is in the
body, not the pattern.
4 changes: 3 additions & 1 deletion Python/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -6121,7 +6121,9 @@ codegen_match_inner(compiler *c, stmt_ty s, pattern_context *pc)
}
// Success! Pop the subject off, we're done with it:
if (i != cases - has_default - 1) {
ADDOP(c, LOC(m->pattern), POP_TOP);
/* Use the body location to give better locations for branch events */
assert(asdl_seq_LEN(m->body) > 0);
ADDOP(c, LOC(asdl_seq_GET(m->body, 0)), POP_TOP);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be the location of the last instruction in the block? Line tracing might look like we executed that line more than once if we "return" to it after running another line.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a NEXT_LOCATION pseudo location so that the POP_TOP gets the location of whatever follows it.

}
VISIT_SEQ(c, stmt, m->body);
ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
Expand Down
Loading