From d18f73ae1349ed005fa05ea2d852e1ab51dbc087 Mon Sep 17 00:00:00 2001 From: Xuanteng Huang <44627253+xuantengh@users.noreply.github.com> Date: Thu, 31 Jul 2025 21:22:22 +0800 Subject: [PATCH] gh-137200: support frame lineno setter with `BRANCH_LEFT` and `BRANCH_RIGHT` events (GH-137229) --- Lib/test/test_monitoring.py | 22 ++++++++++++++++++++++ Objects/frameobject.c | 2 ++ 2 files changed, 24 insertions(+) diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py index a932ac80117d..4122f786a9af 100644 --- a/Lib/test/test_monitoring.py +++ b/Lib/test/test_monitoring.py @@ -3,6 +3,7 @@ import collections import dis import functools +import inspect import math import operator import sys @@ -1709,6 +1710,27 @@ class TestBranchAndJumpEvents(CheckEvents): ('branch right', 'func', 6, 8), ('branch right', 'func', 2, 10)]) + def test_callback_set_frame_lineno(self): + def func(s: str) -> int: + if s.startswith("t"): + return 1 + else: + return 0 + + def callback(code, from_, to): + # try set frame.f_lineno + frame = inspect.currentframe() + while frame and frame.f_code is not code: + frame = frame.f_back + + self.assertIsNotNone(frame) + frame.f_lineno = frame.f_lineno + 1 # run next instruction + + sys.monitoring.set_local_events(TEST_TOOL, func.__code__, E.BRANCH_LEFT) + sys.monitoring.register_callback(TEST_TOOL, E.BRANCH_LEFT, callback) + + self.assertEqual(func("true"), 1) + class TestBranchConsistency(MonitoringTestBase, unittest.TestCase): diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 97de1e06efe1..72c0ab0666e9 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -1685,6 +1685,8 @@ frame_lineno_set_impl(PyFrameObject *self, PyObject *value) case PY_MONITORING_EVENT_PY_RESUME: case PY_MONITORING_EVENT_JUMP: case PY_MONITORING_EVENT_BRANCH: + case PY_MONITORING_EVENT_BRANCH_LEFT: + case PY_MONITORING_EVENT_BRANCH_RIGHT: case PY_MONITORING_EVENT_LINE: case PY_MONITORING_EVENT_PY_YIELD: /* Setting f_lineno is allowed for the above events */ -- 2.47.3