Skip to content

Commit ff88f7e

Browse files
gh-87390: Add __unpacked__ attribute to types.GenericAlias (#92059)
1 parent 56f9844 commit ff88f7e

File tree

4 files changed

+19
-0
lines changed

4 files changed

+19
-0
lines changed

Doc/library/stdtypes.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5055,6 +5055,15 @@ All parameterized generics implement special read-only attributes.
50555055
have correct ``__parameters__`` after substitution because
50565056
:class:`typing.ParamSpec` is intended primarily for static type checking.
50575057

5058+
5059+
.. attribute:: genericalias.__unpacked__
5060+
5061+
A boolean that is true if the alias has been unpacked using the
5062+
``*`` operator (see :data:`~typing.TypeVarTuple`).
5063+
5064+
.. versionadded:: 3.11
5065+
5066+
50585067
.. seealso::
50595068

50605069
:pep:`484` - Type Hints

Lib/test/test_genericalias.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,12 @@ def __deepcopy__(self, memo):
418418
self.assertEqual(copied.__args__, alias.__args__)
419419
self.assertEqual(copied.__parameters__, alias.__parameters__)
420420

421+
def test_unpack(self):
422+
alias = tuple[str, ...]
423+
self.assertIs(alias.__unpacked__, False)
424+
unpacked = (*alias,)[0]
425+
self.assertIs(unpacked.__unpacked__, True)
426+
421427
def test_union(self):
422428
a = typing.Union[list[int], list[str]]
423429
self.assertEqual(a.__args__, (list[int], list[str]))
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add an ``__unpacked__`` attribute to :class:`types.GenericAlias`. Patch by
2+
Jelle Zijlstra.

Objects/genericaliasobject.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ ga_vectorcall(PyObject *self, PyObject *const *args,
516516
static const char* const attr_exceptions[] = {
517517
"__origin__",
518518
"__args__",
519+
"__unpacked__",
519520
"__parameters__",
520521
"__mro_entries__",
521522
"__reduce_ex__", // needed so we don't look up object.__reduce_ex__
@@ -657,6 +658,7 @@ static PyMethodDef ga_methods[] = {
657658
static PyMemberDef ga_members[] = {
658659
{"__origin__", T_OBJECT, offsetof(gaobject, origin), READONLY},
659660
{"__args__", T_OBJECT, offsetof(gaobject, args), READONLY},
661+
{"__unpacked__", T_BOOL, offsetof(gaobject, starred), READONLY},
660662
{0}
661663
};
662664

0 commit comments

Comments
 (0)