[3.14] gh-137814: Fix __qualname__ of __annotate__ functions in the interpreter (#148221)

gh-137814: [3.14] Fix __qualname__ of __annotate__ functions in the interpreter

I'd still like to do #137842 on 3.15+, but that requires changing bytecode and we can't
really afford to do that in 3.14. So to fix this in 3.14, let's patch things up in the
ceval loop instead.

This is safe because the compiler only sets __annotate__ to just-created dedicated
annotate functions.
This commit is contained in:
Jelle Zijlstra 2026-04-15 21:52:43 -07:00 committed by GitHub
parent 0a6bc082b7
commit 1c9de6bbaa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 60 additions and 2 deletions

View file

@ -4970,6 +4970,13 @@ dummy_func(
PyObject **ptr = (PyObject **)(((char *)func) + offset);
assert(*ptr == NULL);
*ptr = attr;
if (oparg == MAKE_FUNCTION_ANNOTATE && PyFunction_Check(attr)) {
// gh-137814: Fix the qualname of __annotate__ functions
PyFunctionObject *func_obj = (PyFunctionObject *)attr;
PyObject *fixed_qualname = PyUnicode_FromFormat("%U.__annotate__", ((PyFunctionObject *)func)->func_qualname);
ERROR_IF(fixed_qualname == NULL);
Py_SETREF(func_obj->func_qualname, fixed_qualname);
}
}
inst(RETURN_GENERATOR, (-- res)) {

View file

@ -6615,6 +6615,22 @@
PyObject **ptr = (PyObject **)(((char *)func) + offset);
assert(*ptr == NULL);
*ptr = attr;
if (oparg == MAKE_FUNCTION_ANNOTATE && PyFunction_Check(attr)) {
PyFunctionObject *func_obj = (PyFunctionObject *)attr;
stack_pointer[-2] = func_out;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *fixed_qualname = PyUnicode_FromFormat("%U.__annotate__", ((PyFunctionObject *)func)->func_qualname);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (fixed_qualname == NULL) {
JUMP_TO_ERROR();
}
_PyFrame_SetStackPointer(frame, stack_pointer);
Py_SETREF(func_obj->func_qualname, fixed_qualname);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += 1;
}
stack_pointer[-2] = func_out;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());

View file

@ -10893,6 +10893,22 @@
PyObject **ptr = (PyObject **)(((char *)func) + offset);
assert(*ptr == NULL);
*ptr = attr;
if (oparg == MAKE_FUNCTION_ANNOTATE && PyFunction_Check(attr)) {
PyFunctionObject *func_obj = (PyFunctionObject *)attr;
stack_pointer[-2] = func_out;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer);
PyObject *fixed_qualname = PyUnicode_FromFormat("%U.__annotate__", ((PyFunctionObject *)func)->func_qualname);
stack_pointer = _PyFrame_GetStackPointer(frame);
if (fixed_qualname == NULL) {
JUMP_TO_LABEL(error);
}
_PyFrame_SetStackPointer(frame, stack_pointer);
Py_SETREF(func_obj->func_qualname, fixed_qualname);
stack_pointer = _PyFrame_GetStackPointer(frame);
stack_pointer += 1;
}
stack_pointer[-2] = func_out;
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());