Python 3.15a4 3661 (Lazy imports IMPORT_NAME opcode changes)
Python 3.15a8 3662 (Add counter to RESUME)
Python 3.15a8 3663 (Merge GET_ITER and GET_YIELD_FROM_ITER. Modify SEND to make it a bit more like FOR_ITER)
+ Python 3.15a8 3664 (Fix __qualname__ for __annotate__ functions)
Python 3.16 will start with 3700
*/
-#define PYC_MAGIC_NUMBER 3663
+#define PYC_MAGIC_NUMBER 3664
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
(little-endian) and then appending b'\r\n'. */
#define PYC_MAGIC_NUMBER_TOKEN \
PyObject *ste_id; /* int: key in ste_table->st_blocks */
PyObject *ste_symbols; /* dict: variable names to flags */
PyObject *ste_name; /* string: name of current block */
+ PyObject *ste_function_name; /* string or NULL: for annotation blocks: name of the corresponding functions */
PyObject *ste_varnames; /* list of function parameters */
PyObject *ste_children; /* list of child blocks */
PyObject *ste_directives;/* locations of global and nonlocal statements */
lamb = list(genexp)[0]
self.assertEqual(lamb(), 42)
+ def test_annotate_qualname(self):
+ code = """
+ def f() -> None:
+ def nested() -> None: pass
+ return nested
+ class Outer:
+ x: int
+ def method(self, x: int):
+ pass
+ """
+ ns = run_code(code)
+ method = ns["Outer"].method
+ self.assertEqual(method.__annotate__.__qualname__, "Outer.method.__annotate__")
+ self.assertEqual(ns["f"].__annotate__.__qualname__, "f.__annotate__")
+ self.assertEqual(ns["f"]().__annotate__.__qualname__, "f.<locals>.nested.__annotate__")
+ self.assertEqual(ns["Outer"].__annotate__.__qualname__, "Outer.__annotate__")
+
# gh-138349
def test_module_level_annotation_plus_listcomp(self):
cases = [
--- /dev/null
+Fix the ``__qualname__`` attribute of ``__annotate__`` functions on
+functions.
base = Py_NewRef(parent->u_metadata.u_qualname);
}
}
+ if (u->u_ste->ste_function_name != NULL) {
+ PyObject *tmp = base;
+ base = PyUnicode_FromFormat("%U.%U",
+ base,
+ u->u_ste->ste_function_name);
+ Py_DECREF(tmp);
+ if (base == NULL) {
+ return ERROR;
+ }
+ }
+ }
+ else if (u->u_ste->ste_function_name != NULL) {
+ base = Py_NewRef(u->u_ste->ste_function_name);
}
if (base != NULL) {
ste->ste_id = k; /* ste owns reference to k */
ste->ste_name = Py_NewRef(name);
+ ste->ste_function_name = NULL;
ste->ste_symbols = NULL;
ste->ste_varnames = NULL;
ste->ste_table = NULL;
Py_XDECREF(ste->ste_id);
Py_XDECREF(ste->ste_name);
+ Py_XDECREF(ste->ste_function_name);
Py_XDECREF(ste->ste_symbols);
Py_XDECREF(ste->ste_varnames);
Py_XDECREF(ste->ste_children);
(void *)a, LOCATION(o))) {
return 0;
}
+ Py_XSETREF(st->st_cur->ste_function_name, Py_NewRef(function_ste->ste_name));
if (is_in_class || current_type == ClassBlock) {
st->st_cur->ste_can_see_class_scope = 1;
if (!symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(o))) {