Skip to content

Commit 1bc0ac4

Browse files
authored
Merge branch 'main' into pth2toml
2 parents 1804f68 + 5b8cd31 commit 1bc0ac4

File tree

6 files changed

+38
-1
lines changed

6 files changed

+38
-1
lines changed

Include/internal/pycore_magic_number.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ Known values:
294294
Python 3.15a4 3661 (Lazy imports IMPORT_NAME opcode changes)
295295
Python 3.15a8 3662 (Add counter to RESUME)
296296
Python 3.15a8 3663 (Merge GET_ITER and GET_YIELD_FROM_ITER. Modify SEND to make it a bit more like FOR_ITER)
297+
Python 3.15a8 3664 (Fix __qualname__ for __annotate__ functions)
297298
298299
299300
Python 3.16 will start with 3700
@@ -307,7 +308,7 @@ PC/launcher.c must also be updated.
307308
308309
*/
309310

310-
#define PYC_MAGIC_NUMBER 3663
311+
#define PYC_MAGIC_NUMBER 3664
311312
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
312313
(little-endian) and then appending b'\r\n'. */
313314
#define PYC_MAGIC_NUMBER_TOKEN \

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
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,
108108
ste->ste_id = k; /* ste owns reference to k */
109109

110110
ste->ste_name = Py_NewRef(name);
111+
ste->ste_function_name = NULL;
111112

112113
ste->ste_symbols = NULL;
113114
ste->ste_varnames = NULL;
@@ -186,6 +187,7 @@ ste_dealloc(PyObject *op)
186187
ste->ste_table = NULL;
187188
Py_XDECREF(ste->ste_id);
188189
Py_XDECREF(ste->ste_name);
190+
Py_XDECREF(ste->ste_function_name);
189191
Py_XDECREF(ste->ste_symbols);
190192
Py_XDECREF(ste->ste_varnames);
191193
Py_XDECREF(ste->ste_children);
@@ -2918,6 +2920,7 @@ symtable_visit_annotations(struct symtable *st, stmt_ty o, arguments_ty a, expr_
29182920
(void *)a, LOCATION(o))) {
29192921
return 0;
29202922
}
2923+
Py_XSETREF(st->st_cur->ste_function_name, Py_NewRef(function_ste->ste_name));
29212924
if (is_in_class || current_type == ClassBlock) {
29222925
st->st_cur->ste_can_see_class_scope = 1;
29232926
if (!symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(o))) {

0 commit comments

Comments
 (0)