From 207a21fa11bac9a035c7df28abe5d2da0927528f Mon Sep 17 00:00:00 2001 From: Dino Viehland Date: Fri, 10 Oct 2025 13:54:26 -0700 Subject: [PATCH 1/2] Add PyFunction_PYFUNC_EVENT_MODIFY_QUALNAME event for function watchers --- Doc/c-api/function.rst | 3 +++ Include/cpython/funcobject.h | 3 ++- Lib/test/test_capi/test_watchers.py | 4 ++++ Objects/funcobject.c | 2 ++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Doc/c-api/function.rst b/Doc/c-api/function.rst index 5fb8567ef8c95f..764b2ac610be4d 100644 --- a/Doc/c-api/function.rst +++ b/Doc/c-api/function.rst @@ -175,6 +175,9 @@ There are a few functions specific to Python functions. .. versionadded:: 3.12 + - ``PyFunction_PYFUNC_EVENT_MODIFY_QUALNAME`` + + .. versionadded:: 3.15 .. c:type:: int (*PyFunction_WatchCallback)(PyFunction_WatchEvent event, PyFunctionObject *func, PyObject *new_value) diff --git a/Include/cpython/funcobject.h b/Include/cpython/funcobject.h index 598cd330bc9ca9..9e1599a7648564 100644 --- a/Include/cpython/funcobject.h +++ b/Include/cpython/funcobject.h @@ -134,7 +134,8 @@ PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *); V(DESTROY) \ V(MODIFY_CODE) \ V(MODIFY_DEFAULTS) \ - V(MODIFY_KWDEFAULTS) + V(MODIFY_KWDEFAULTS) \ + V(MODIFY_QUALNAME) typedef enum { #define PY_DEF_EVENT(EVENT) PyFunction_EVENT_##EVENT, diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py index 8644479d83d5ed..bef72032513da5 100644 --- a/Lib/test/test_capi/test_watchers.py +++ b/Lib/test/test_capi/test_watchers.py @@ -514,6 +514,10 @@ def myfunc(): _testcapi.set_func_kwdefaults_via_capi(myfunc, new_kwdefaults) self.assertIn((_testcapi.PYFUNC_EVENT_MODIFY_KWDEFAULTS, myfunc, new_kwdefaults), events) + new_qualname = "foo.bar" + myfunc.__qualname__ = new_qualname + self.assertIn((_testcapi.PYFUNC_EVENT_MODIFY_QUALNAME, myfunc, new_qualname), events) + # Clear events reference to func events = [] del myfunc diff --git a/Objects/funcobject.c b/Objects/funcobject.c index d8a10075578087..43198aaf8a7048 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -62,6 +62,7 @@ handle_func_event(PyFunction_WatchEvent event, PyFunctionObject *func, case PyFunction_EVENT_MODIFY_CODE: case PyFunction_EVENT_MODIFY_DEFAULTS: case PyFunction_EVENT_MODIFY_KWDEFAULTS: + case PyFunction_EVENT_MODIFY_QUALNAME: RARE_EVENT_INTERP_INC(interp, func_modification); break; default: @@ -747,6 +748,7 @@ func_set_qualname(PyObject *self, PyObject *value, void *Py_UNUSED(ignored)) "__qualname__ must be set to a string object"); return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_QUALNAME, (PyFunctionObject *) op, value); Py_XSETREF(op->func_qualname, Py_NewRef(value)); return 0; } From 459727defba9e17b357a86a0fc7ee3e8ca805269 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 10 Oct 2025 20:59:17 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/C_API/2025-10-10-20-59-07.gh-issue-139924.ALByCb.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/C_API/2025-10-10-20-59-07.gh-issue-139924.ALByCb.rst diff --git a/Misc/NEWS.d/next/C_API/2025-10-10-20-59-07.gh-issue-139924.ALByCb.rst b/Misc/NEWS.d/next/C_API/2025-10-10-20-59-07.gh-issue-139924.ALByCb.rst new file mode 100644 index 00000000000000..a53d5d068d7d86 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2025-10-10-20-59-07.gh-issue-139924.ALByCb.rst @@ -0,0 +1 @@ +Function watchers can now receive a PyFunction_PYFUNC_EVENT_MODIFY_QUALNAME event when a watched functions qualname is changed.