[Python-checkins] GH-103082: Turn on branch events for FOR_ITER instructions. (#103507)
markshannon
webhook-mailer at python.org
Thu Apr 13 08:56:18 EDT 2023
https://github.com/python/cpython/commit/70e0a28bed1354ec450989271152ae697e1f0993
commit: 70e0a28bed1354ec450989271152ae697e1f0993
branch: main
author: Mark Shannon <mark at hotpy.org>
committer: markshannon <mark at hotpy.org>
date: 2023-04-13T13:56:09+01:00
summary:
GH-103082: Turn on branch events for FOR_ITER instructions. (#103507)
Turn on branch events for FOR_ITER instructions.
files:
M Lib/test/test_monitoring.py
M Python/instrumentation.c
diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py
index 4aad3da61b6b..738ace923cc5 100644
--- a/Lib/test/test_monitoring.py
+++ b/Lib/test/test_monitoring.py
@@ -1011,6 +1011,77 @@ def func3():
('line', 'func3', 6)])
+def line_from_offset(code, offset):
+ for start, end, line in code.co_lines():
+ if start <= offset < end:
+ return line - code.co_firstlineno
+ return -1
+
+class JumpRecorder:
+
+ event_type = E.JUMP
+ name = "jump"
+
+ def __init__(self, events):
+ self.events = events
+
+ def __call__(self, code, from_, to):
+ from_line = line_from_offset(code, from_)
+ to_line = line_from_offset(code, to)
+ self.events.append((self.name, code.co_name, from_line, to_line))
+
+
+class BranchRecorder(JumpRecorder):
+
+ event_type = E.BRANCH
+ name = "branch"
+
+
+JUMP_AND_BRANCH_RECORDERS = JumpRecorder, BranchRecorder
+JUMP_BRANCH_AND_LINE_RECORDERS = JumpRecorder, BranchRecorder, LineRecorder
+
+class TestBranchAndJumpEvents(CheckEvents):
+ maxDiff = None
+
+ def test_loop(self):
+
+ def func():
+ x = 1
+ for a in range(2):
+ if a:
+ x = 4
+ else:
+ x = 6
+
+ self.check_events(func, recorders = JUMP_AND_BRANCH_RECORDERS, expected = [
+ ('branch', 'func', 2, 2),
+ ('branch', 'func', 3, 6),
+ ('jump', 'func', 6, 2),
+ ('branch', 'func', 2, 2),
+ ('branch', 'func', 3, 4),
+ ('jump', 'func', 4, 2),
+ ('branch', 'func', 2, 2)])
+
+
+ self.check_events(func, recorders = JUMP_BRANCH_AND_LINE_RECORDERS, expected = [
+ ('line', 'check_events', 10),
+ ('line', 'func', 1),
+ ('line', 'func', 2),
+ ('branch', 'func', 2, 2),
+ ('line', 'func', 3),
+ ('branch', 'func', 3, 6),
+ ('line', 'func', 6),
+ ('jump', 'func', 6, 2),
+ ('branch', 'func', 2, 2),
+ ('line', 'func', 3),
+ ('branch', 'func', 3, 4),
+ ('line', 'func', 4),
+ ('jump', 'func', 4, 2),
+ ('branch', 'func', 2, 2),
+ ('line', 'func', 2),
+ ('line', 'check_events', 11)])
+
+
class TestSetGetEvents(MonitoringTestBase, unittest.TestCase):
def test_global(self):
diff --git a/Python/instrumentation.c b/Python/instrumentation.c
index 39a7eaa3bd2d..8dc8b01fcb04 100644
--- a/Python/instrumentation.c
+++ b/Python/instrumentation.c
@@ -105,6 +105,8 @@ static const uint8_t INSTRUMENTED_OPCODES[256] = {
[INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR,
[END_SEND] = INSTRUMENTED_END_SEND,
[INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND,
+ [FOR_ITER] = INSTRUMENTED_FOR_ITER,
+ [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER,
[INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
[INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION,
More information about the Python-checkins
mailing list