Skip to content

Commit 63d2d80

Browse files
committed
pythongh-87390: Add __unpacked__ attribute to types.GenericAlias
1 parent 81120b6 commit 63d2d80

File tree

4 files changed

+29
-0
lines changed

4 files changed

+29
-0
lines changed

Doc/library/types.rst

+19
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,25 @@ Standard names are defined for the following types:
311311
.. versionchanged:: 3.9.2
312312
This type can now be subclassed.
313313

314+
.. attribute:: __origin__
315+
316+
The non-parameterized generic class.
317+
318+
.. attribute:: __args__
319+
320+
The :class:`tuple` of types which parameterize the generic class.
321+
322+
.. attribute:: __parameters__
323+
324+
The :data:`~typing.TypeVar`\ s which serve as type parameters for
325+
the generic class.
326+
327+
.. attribute:: __unpacked__
328+
329+
A boolean that is true if the alias has been unpacked using the
330+
``*`` operator (see :data:`~typing.TypeVarTuple`).
331+
332+
.. versionadded:: 3.11
314333

315334
.. class:: UnionType
316335

Lib/test/test_genericalias.py

+6
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,12 @@ def __deepcopy__(self, memo):
416416
self.assertEqual(copied.__args__, alias.__args__)
417417
self.assertEqual(copied.__parameters__, alias.__parameters__)
418418

419+
def test_unpack(self):
420+
alias = tuple[str, ...]
421+
self.assertIs(alias.__unpacked__, False)
422+
unpacked = (*alias,)[0]
423+
self.assertIs(unpacked.__unpacked__, True)
424+
419425
def test_union(self):
420426
a = typing.Union[list[int], list[str]]
421427
self.assertEqual(a.__args__, (list[int], list[str]))
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

+2
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ ga_vectorcall(PyObject *self, PyObject *const *args,
426426
static const char* const attr_exceptions[] = {
427427
"__origin__",
428428
"__args__",
429+
"__unpacked__",
429430
"__parameters__",
430431
"__mro_entries__",
431432
"__reduce_ex__", // needed so we don't look up object.__reduce_ex__
@@ -567,6 +568,7 @@ static PyMethodDef ga_methods[] = {
567568
static PyMemberDef ga_members[] = {
568569
{"__origin__", T_OBJECT, offsetof(gaobject, origin), READONLY},
569570
{"__args__", T_OBJECT, offsetof(gaobject, args), READONLY},
571+
{"__unpacked__", T_BOOL, offsetof(gaobject, starred), READONLY},
570572
{0}
571573
};
572574

0 commit comments

Comments
 (0)