]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-126085: Add `tp_iter` to TypeAliasType to allow star unpacking (#127981)
authorTomas R. <tomas.roun8@gmail.com>
Tue, 4 Mar 2025 19:34:59 +0000 (20:34 +0100)
committerGitHub <noreply@github.com>
Tue, 4 Mar 2025 19:34:59 +0000 (11:34 -0800)
Doc/library/typing.rst
Doc/whatsnew/3.14.rst
Lib/test/test_type_aliases.py
Misc/NEWS.d/next/Core_and_Builtins/2024-12-15-16-56-26.gh-issue-126085.BvyEXk.rst [new file with mode: 0644]
Objects/typevarobject.c

index 19b4081c993e4498c9dffff8a5de1ac0a9151a16..13108abdeaf267a5f76f009a7f23d01f2490abef 100644 (file)
@@ -2292,6 +2292,20 @@ without the dedicated syntax, as documented below.
 
       .. versionadded:: 3.14
 
+   .. rubric:: Unpacking
+
+   Type aliases support star unpacking using the ``*Alias`` syntax.
+   This is equivalent to using ``Unpack[Alias]`` directly:
+
+   .. doctest::
+
+      >>> type Alias = tuple[int, str]
+      >>> type Unpacked = tuple[bool, *Alias]
+      >>> Unpacked.__value__
+      tuple[bool, typing.Unpack[Alias]]
+
+   .. versionadded:: next
+
 
 Other special directives
 """"""""""""""""""""""""
index 7b1a30d5a873aee02dcf3c262543aa6eda513fbf..8dfe25ad99abe38f46987e9e4b6128ba7fa6ec7f 100644 (file)
@@ -1326,6 +1326,8 @@ typing
 * Remove :class:`!typing.ByteString`. It had previously raised a
   :exc:`DeprecationWarning` since Python 3.12.
 
+* :class:`typing.TypeAliasType` now supports star unpacking.
+
 urllib
 ------
 
index 230bbe646baf2818043c84968a2f0de080a9547f..ee1791bc1d0b9d54ad6e5c0220488740c1527dba 100644 (file)
@@ -5,7 +5,7 @@ from test.support import check_syntax_error, run_code
 from test.typinganndata import mod_generics_cache
 
 from typing import (
-    Callable, TypeAliasType, TypeVar, TypeVarTuple, ParamSpec, get_args,
+    Callable, TypeAliasType, TypeVar, TypeVarTuple, ParamSpec, Unpack, get_args,
 )
 
 
@@ -317,6 +317,17 @@ class TypeAliasTypeTest(unittest.TestCase):
         self.assertEqual(mod_generics_cache.OldStyle.__module__,
                          mod_generics_cache.__name__)
 
+    def test_unpack(self):
+        type Alias = tuple[int, int]
+        unpacked = (*Alias,)[0]
+        self.assertEqual(unpacked, Unpack[Alias])
+
+        class Foo[*Ts]:
+            pass
+
+        x = Foo[str, *Alias]
+        self.assertEqual(x.__args__, (str, Unpack[Alias]))
+
 
 # All these type aliases are used for pickling tests:
 T = TypeVar('T')
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-15-16-56-26.gh-issue-126085.BvyEXk.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-15-16-56-26.gh-issue-126085.BvyEXk.rst
new file mode 100644 (file)
index 0000000..25b23fd
--- /dev/null
@@ -0,0 +1 @@
+:class:`typing.TypeAliasType` now supports star unpacking.
index d8158293acaabd5d2caf552680f7b5dd46e70057..3ab8cb14686e842ee99eb50c133ed1d1741dde12 100644 (file)
@@ -1,4 +1,4 @@
-// TypeVar, TypeVarTuple, and ParamSpec
+// TypeVar, TypeVarTuple, ParamSpec, and TypeAlias
 #include "Python.h"
 #include "pycore_object.h"        // _PyObject_GC_TRACK/UNTRACK, PyAnnotateFormat
 #include "pycore_typevarobject.h"
@@ -394,7 +394,7 @@ caller(void)
 }
 
 static PyObject *
-typevartuple_unpack(PyObject *tvt)
+unpack(PyObject *self)
 {
     PyObject *typing = PyImport_ImportModule("typing");
     if (typing == NULL) {
@@ -405,7 +405,7 @@ typevartuple_unpack(PyObject *tvt)
         Py_DECREF(typing);
         return NULL;
     }
-    PyObject *unpacked = PyObject_GetItem(unpack, tvt);
+    PyObject *unpacked = PyObject_GetItem(unpack, self);
     Py_DECREF(typing);
     Py_DECREF(unpack);
     return unpacked;
@@ -440,7 +440,7 @@ unpack_typevartuples(PyObject *params)
         for (Py_ssize_t i = 0; i < n; i++) {
             PyObject *param = PyTuple_GET_ITEM(params, i);
             if (Py_IS_TYPE(param, tp)) {
-                PyObject *unpacked = typevartuple_unpack(param);
+                PyObject *unpacked = unpack(param);
                 if (unpacked == NULL) {
                     Py_DECREF(new_params);
                     return NULL;
@@ -1524,9 +1524,9 @@ typevartuple_dealloc(PyObject *self)
 }
 
 static PyObject *
-typevartuple_iter(PyObject *self)
+unpack_iter(PyObject *self)
 {
-    PyObject *unpacked = typevartuple_unpack(self);
+    PyObject *unpacked = unpack(self);
     if (unpacked == NULL) {
         return NULL;
     }
@@ -1782,7 +1782,7 @@ PyType_Slot typevartuple_slots[] = {
     {Py_tp_methods, typevartuple_methods},
     {Py_tp_getset, typevartuple_getset},
     {Py_tp_new, typevartuple},
-    {Py_tp_iter, typevartuple_iter},
+    {Py_tp_iter, unpack_iter},
     {Py_tp_repr, typevartuple_repr},
     {Py_tp_dealloc, typevartuple_dealloc},
     {Py_tp_alloc, PyType_GenericAlloc},
@@ -2158,6 +2158,7 @@ PyTypeObject _PyTypeAlias_Type = {
     .tp_dealloc = typealias_dealloc,
     .tp_new = typealias_new,
     .tp_free = PyObject_GC_Del,
+    .tp_iter = unpack_iter,
     .tp_traverse = typealias_traverse,
     .tp_clear = typealias_clear,
     .tp_repr = typealias_repr,