gh-137814: Fix `__qualname__` of `__annotate__` (#137842) · python/cpython@5b8cd31 · GitHub
Skip to content

Commit 5b8cd31

Browse files
gh-137814: Fix __qualname__ of __annotate__ (#137842)
1 parent 54607ee commit 5b8cd31

6 files changed

Lines changed: 38 additions & 1 deletion

File tree

Include/internal/pycore_magic_number.h

Lines changed: 2 additions & 1 deletion

Include/internal/pycore_symtable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ typedef struct _symtable_entry {
9090
PyObject *ste_id; /* int: key in ste_table->st_blocks */
9191
PyObject *ste_symbols; /* dict: variable names to flags */
9292
PyObject *ste_name; /* string: name of current block */
93+
PyObject *ste_function_name; /* string or NULL: for annotation blocks: name of the corresponding functions */
9394
PyObject *ste_varnames; /* list of function parameters */
9495
PyObject *ste_children; /* list of child blocks */
9596
PyObject *ste_directives;/* locations of global and nonlocal statements */

Lib/test/test_type_annotations.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,23 @@ def test_complex_comprehension_inlining_exec(self):
836836
lamb = list(genexp)[0]
837837
self.assertEqual(lamb(), 42)
838838

839+
def test_annotate_qualname(self):
840+
code = """
841+
def f() -> None:
842+
def nested() -> None: pass
843+
return nested
844+
class Outer:
845+
x: int
846+
def method(self, x: int):
847+
pass
848+
"""
849+
ns = run_code(code)
850+
method = ns["Outer"].method
851+
self.assertEqual(method.__annotate__.__qualname__, "Outer.method.__annotate__")
852+
self.assertEqual(ns["f"].__annotate__.__qualname__, "f.__annotate__")
853+
self.assertEqual(ns["f"]().__annotate__.__qualname__, "f.<locals>.nested.__annotate__")
854+
self.assertEqual(ns["Outer"].__annotate__.__qualname__, "Outer.__annotate__")
855+
839856
# gh-138349
840857
def test_module_level_annotation_plus_listcomp(self):
841858
cases = [
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix the ``__qualname__`` attribute of ``__annotate__`` functions on
2+
functions.

Python/compile.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,19 @@ compiler_set_qualname(compiler *c)
297297
base = Py_NewRef(parent->u_metadata.u_qualname);
298298
}
299299
}
300+
if (u->u_ste->ste_function_name != NULL) {
301+
PyObject *tmp = base;
302+
base = PyUnicode_FromFormat("%U.%U",
303+
base,
304+
u->u_ste->ste_function_name);
305+
Py_DECREF(tmp);
306+
if (base == NULL) {
307+
return ERROR;
308+
}
309+
}
310+
}
311+
else if (u->u_ste->ste_function_name != NULL) {
312+
base = Py_NewRef(u->u_ste->ste_function_name);
300313
}
301314

302315
if (base != NULL) {

Python/symtable.c

Lines changed: 3 additions & 0 deletions

0 commit comments

Comments
 (0)