Skip to content

Commit e091520

Browse files
authored
gh-126085: Add tp_iter to TypeAliasType to allow star unpacking (#127981)
1 parent d8a1cf4 commit e091520

File tree

5 files changed

+37
-8
lines changed

5 files changed

+37
-8
lines changed

Doc/library/typing.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,6 +2292,20 @@ without the dedicated syntax, as documented below.
22922292

22932293
.. versionadded:: 3.14
22942294

2295+
.. rubric:: Unpacking
2296+
2297+
Type aliases support star unpacking using the ``*Alias`` syntax.
2298+
This is equivalent to using ``Unpack[Alias]`` directly:
2299+
2300+
.. doctest::
2301+
2302+
>>> type Alias = tuple[int, str]
2303+
>>> type Unpacked = tuple[bool, *Alias]
2304+
>>> Unpacked.__value__
2305+
tuple[bool, typing.Unpack[Alias]]
2306+
2307+
.. versionadded:: next
2308+
22952309

22962310
Other special directives
22972311
""""""""""""""""""""""""

Doc/whatsnew/3.14.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,6 +1326,8 @@ typing
13261326
* Remove :class:`!typing.ByteString`. It had previously raised a
13271327
:exc:`DeprecationWarning` since Python 3.12.
13281328

1329+
* :class:`typing.TypeAliasType` now supports star unpacking.
1330+
13291331
urllib
13301332
------
13311333

Lib/test/test_type_aliases.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from test.typinganndata import mod_generics_cache
66

77
from typing import (
8-
Callable, TypeAliasType, TypeVar, TypeVarTuple, ParamSpec, get_args,
8+
Callable, TypeAliasType, TypeVar, TypeVarTuple, ParamSpec, Unpack, get_args,
99
)
1010

1111

@@ -317,6 +317,17 @@ def test_module(self):
317317
self.assertEqual(mod_generics_cache.OldStyle.__module__,
318318
mod_generics_cache.__name__)
319319

320+
def test_unpack(self):
321+
type Alias = tuple[int, int]
322+
unpacked = (*Alias,)[0]
323+
self.assertEqual(unpacked, Unpack[Alias])
324+
325+
class Foo[*Ts]:
326+
pass
327+
328+
x = Foo[str, *Alias]
329+
self.assertEqual(x.__args__, (str, Unpack[Alias]))
330+
320331

321332
# All these type aliases are used for pickling tests:
322333
T = TypeVar('T')
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:class:`typing.TypeAliasType` now supports star unpacking.

Objects/typevarobject.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// TypeVar, TypeVarTuple, and ParamSpec
1+
// TypeVar, TypeVarTuple, ParamSpec, and TypeAlias
22
#include "Python.h"
33
#include "pycore_object.h" // _PyObject_GC_TRACK/UNTRACK, PyAnnotateFormat
44
#include "pycore_typevarobject.h"
@@ -394,7 +394,7 @@ caller(void)
394394
}
395395

396396
static PyObject *
397-
typevartuple_unpack(PyObject *tvt)
397+
unpack(PyObject *self)
398398
{
399399
PyObject *typing = PyImport_ImportModule("typing");
400400
if (typing == NULL) {
@@ -405,7 +405,7 @@ typevartuple_unpack(PyObject *tvt)
405405
Py_DECREF(typing);
406406
return NULL;
407407
}
408-
PyObject *unpacked = PyObject_GetItem(unpack, tvt);
408+
PyObject *unpacked = PyObject_GetItem(unpack, self);
409409
Py_DECREF(typing);
410410
Py_DECREF(unpack);
411411
return unpacked;
@@ -440,7 +440,7 @@ unpack_typevartuples(PyObject *params)
440440
for (Py_ssize_t i = 0; i < n; i++) {
441441
PyObject *param = PyTuple_GET_ITEM(params, i);
442442
if (Py_IS_TYPE(param, tp)) {
443-
PyObject *unpacked = typevartuple_unpack(param);
443+
PyObject *unpacked = unpack(param);
444444
if (unpacked == NULL) {
445445
Py_DECREF(new_params);
446446
return NULL;
@@ -1524,9 +1524,9 @@ typevartuple_dealloc(PyObject *self)
15241524
}
15251525

15261526
static PyObject *
1527-
typevartuple_iter(PyObject *self)
1527+
unpack_iter(PyObject *self)
15281528
{
1529-
PyObject *unpacked = typevartuple_unpack(self);
1529+
PyObject *unpacked = unpack(self);
15301530
if (unpacked == NULL) {
15311531
return NULL;
15321532
}
@@ -1782,7 +1782,7 @@ PyType_Slot typevartuple_slots[] = {
17821782
{Py_tp_methods, typevartuple_methods},
17831783
{Py_tp_getset, typevartuple_getset},
17841784
{Py_tp_new, typevartuple},
1785-
{Py_tp_iter, typevartuple_iter},
1785+
{Py_tp_iter, unpack_iter},
17861786
{Py_tp_repr, typevartuple_repr},
17871787
{Py_tp_dealloc, typevartuple_dealloc},
17881788
{Py_tp_alloc, PyType_GenericAlloc},
@@ -2158,6 +2158,7 @@ PyTypeObject _PyTypeAlias_Type = {
21582158
.tp_dealloc = typealias_dealloc,
21592159
.tp_new = typealias_new,
21602160
.tp_free = PyObject_GC_Del,
2161+
.tp_iter = unpack_iter,
21612162
.tp_traverse = typealias_traverse,
21622163
.tp_clear = typealias_clear,
21632164
.tp_repr = typealias_repr,

0 commit comments

Comments
 (0)