Skip to content
/ cpython Public
forked from python/cpython

Commit

Permalink
[3.10] bpo-46581: Propagate private vars via _GenericAlias.copy_with (p…
Browse files Browse the repository at this point in the history
…ythonGH-31061)

(Cherry-picked from 32bf359.)

pythonGH-26091 added the _typevar_types and _paramspec_tvars instance
variables to _GenericAlias. However, they were not propagated
consistently. This commit addresses the most prominent deficiency
identified in bpo-46581 (namely their absence from
_GenericAlias.copy_with), but there could be others.

Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
  • Loading branch information
3 people committed Mar 11, 2022
1 parent 4199b7f commit 4a27b14
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 7 deletions.
21 changes: 21 additions & 0 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4990,6 +4990,27 @@ def test_paramspec_in_nested_generics(self):
self.assertEqual(G2[[int, str], float], list[C])
self.assertEqual(G3[[int, str], float], list[C] | int)

def test_paramspec_gets_copied(self):
# bpo-46581
P = ParamSpec('P')
P2 = ParamSpec('P2')
C1 = Callable[P, int]
self.assertEqual(C1.__parameters__, (P,))
self.assertEqual(C1[P2].__parameters__, (P2,))
self.assertEqual(C1[str].__parameters__, ())
self.assertEqual(C1[str, T].__parameters__, (T,))
self.assertEqual(C1[Concatenate[str, P2]].__parameters__, (P2,))
self.assertEqual(C1[Concatenate[T, P2]].__parameters__, (T, P2))
self.assertEqual(C1[...].__parameters__, ())

C2 = Callable[Concatenate[str, P], int]
self.assertEqual(C2.__parameters__, (P,))
self.assertEqual(C2[P2].__parameters__, (P2,))
self.assertEqual(C2[str].__parameters__, ())
self.assertEqual(C2[str, T].__parameters__, (T,))
self.assertEqual(C2[Concatenate[str, P2]].__parameters__, (P2,))
self.assertEqual(C2[Concatenate[T, P2]].__parameters__, (T, P2))


class ConcatenateTests(BaseTestCase):
def test_basics(self):
Expand Down
13 changes: 6 additions & 7 deletions Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,9 @@ def Concatenate(self, parameters):
"ParamSpec variable.")
msg = "Concatenate[arg, ...]: each arg must be a type."
parameters = (*(_type_check(p, msg) for p in parameters[:-1]), parameters[-1])
return _ConcatenateGenericAlias(self, parameters)
return _ConcatenateGenericAlias(self, parameters,
_typevar_types=(TypeVar, ParamSpec),
_paramspec_tvars=True)


@_SpecialForm
Expand Down Expand Up @@ -1079,7 +1081,9 @@ def __getitem__(self, params):
return self.copy_with(tuple(new_args))

def copy_with(self, params):
return self.__class__(self.__origin__, params, name=self._name, inst=self._inst)
return self.__class__(self.__origin__, params, name=self._name, inst=self._inst,
_typevar_types=self._typevar_types,
_paramspec_tvars=self._paramspec_tvars)

def __repr__(self):
if self._name:
Expand Down Expand Up @@ -1281,11 +1285,6 @@ def __hash__(self):


class _ConcatenateGenericAlias(_GenericAlias, _root=True):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs,
_typevar_types=(TypeVar, ParamSpec),
_paramspec_tvars=True)

def copy_with(self, params):
if isinstance(params[-1], (list, tuple)):
return (*params[:-1], *params[-1])
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ Paul Boddie
Matthew Boedicker
Robin Boerdijk
Andra Bogildea
Matt Bogosian
Nikolay Bogoychev
David Bolen
Wouter Bolsterlee
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Brings :class:`ParamSpec` propagation for :class:`GenericAlias` in line with
:class:`Concatenate` (and others).

0 comments on commit 4a27b14

Please sign in to comment.