gh-87390: Add __unpacked__ attribute to types.GenericAlias (#92059)

This commit is contained in:
Jelle Zijlstra
2022-05-02 13:21:59 -06:00
committed by GitHub
parent 56f9844014
commit ff88f7e007
4 changed files with 19 additions and 0 deletions

View File

@@ -5055,6 +5055,15 @@ All parameterized generics implement special read-only attributes.
have correct ``__parameters__`` after substitution because have correct ``__parameters__`` after substitution because
:class:`typing.ParamSpec` is intended primarily for static type checking. :class:`typing.ParamSpec` is intended primarily for static type checking.
.. attribute:: genericalias.__unpacked__
A boolean that is true if the alias has been unpacked using the
``*`` operator (see :data:`~typing.TypeVarTuple`).
.. versionadded:: 3.11
.. seealso:: .. seealso::
:pep:`484` - Type Hints :pep:`484` - Type Hints

View File

@@ -418,6 +418,12 @@ class BaseTest(unittest.TestCase):
self.assertEqual(copied.__args__, alias.__args__) self.assertEqual(copied.__args__, alias.__args__)
self.assertEqual(copied.__parameters__, alias.__parameters__) self.assertEqual(copied.__parameters__, alias.__parameters__)
def test_unpack(self):
alias = tuple[str, ...]
self.assertIs(alias.__unpacked__, False)
unpacked = (*alias,)[0]
self.assertIs(unpacked.__unpacked__, True)
def test_union(self): def test_union(self):
a = typing.Union[list[int], list[str]] a = typing.Union[list[int], list[str]]
self.assertEqual(a.__args__, (list[int], list[str])) self.assertEqual(a.__args__, (list[int], list[str]))

View File

@@ -0,0 +1,2 @@
Add an ``__unpacked__`` attribute to :class:`types.GenericAlias`. Patch by
Jelle Zijlstra.

View File

@@ -516,6 +516,7 @@ ga_vectorcall(PyObject *self, PyObject *const *args,
static const char* const attr_exceptions[] = { static const char* const attr_exceptions[] = {
"__origin__", "__origin__",
"__args__", "__args__",
"__unpacked__",
"__parameters__", "__parameters__",
"__mro_entries__", "__mro_entries__",
"__reduce_ex__", // needed so we don't look up object.__reduce_ex__ "__reduce_ex__", // needed so we don't look up object.__reduce_ex__
@@ -657,6 +658,7 @@ static PyMethodDef ga_methods[] = {
static PyMemberDef ga_members[] = { static PyMemberDef ga_members[] = {
{"__origin__", T_OBJECT, offsetof(gaobject, origin), READONLY}, {"__origin__", T_OBJECT, offsetof(gaobject, origin), READONLY},
{"__args__", T_OBJECT, offsetof(gaobject, args), READONLY}, {"__args__", T_OBJECT, offsetof(gaobject, args), READONLY},
{"__unpacked__", T_BOOL, offsetof(gaobject, starred), READONLY},
{0} {0}
}; };