mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
bpo-44791: Accept ellipsis as the last argument of typing.Concatenate (#30969)
This commit is contained in:
parent
f6656163de
commit
81120b6754
4 changed files with 9 additions and 14 deletions
|
@ -852,7 +852,8 @@ These can be used as types in annotations using ``[]``, each having a unique syn
|
|||
callable. Usage is in the form
|
||||
``Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]``. ``Concatenate``
|
||||
is currently only valid when used as the first argument to a :data:`Callable`.
|
||||
The last parameter to ``Concatenate`` must be a :class:`ParamSpec`.
|
||||
The last parameter to ``Concatenate`` must be a :class:`ParamSpec` or
|
||||
ellipsis (``...``).
|
||||
|
||||
For example, to annotate a decorator ``with_lock`` which provides a
|
||||
:class:`threading.Lock` to the decorated function, ``Concatenate`` can be
|
||||
|
|
|
@ -1755,8 +1755,7 @@ class BaseCallableTests:
|
|||
self.assertEqual(C[[], int], Callable[[int], int])
|
||||
self.assertEqual(C[Concatenate[str, P2], int],
|
||||
Callable[Concatenate[int, str, P2], int])
|
||||
with self.assertRaises(TypeError):
|
||||
C[..., int]
|
||||
self.assertEqual(C[..., int], Callable[Concatenate[int, ...], int])
|
||||
|
||||
C = Callable[Concatenate[int, P], int]
|
||||
self.assertEqual(repr(C),
|
||||
|
@ -1767,8 +1766,7 @@ class BaseCallableTests:
|
|||
self.assertEqual(C[[]], Callable[[int], int])
|
||||
self.assertEqual(C[Concatenate[str, P2]],
|
||||
Callable[Concatenate[int, str, P2], int])
|
||||
with self.assertRaises(TypeError):
|
||||
C[...]
|
||||
self.assertEqual(C[...], Callable[Concatenate[int, ...], int])
|
||||
|
||||
def test_errors(self):
|
||||
Callable = self.Callable
|
||||
|
@ -6739,8 +6737,7 @@ class ConcatenateTests(BaseTestCase):
|
|||
self.assertEqual(C[int, []], (int,))
|
||||
self.assertEqual(C[int, Concatenate[str, P2]],
|
||||
Concatenate[int, str, P2])
|
||||
with self.assertRaises(TypeError):
|
||||
C[int, ...]
|
||||
self.assertEqual(C[int, ...], Concatenate[int, ...])
|
||||
|
||||
C = Concatenate[int, P]
|
||||
self.assertEqual(C[P2], Concatenate[int, P2])
|
||||
|
@ -6748,8 +6745,7 @@ class ConcatenateTests(BaseTestCase):
|
|||
self.assertEqual(C[str, float], (int, str, float))
|
||||
self.assertEqual(C[[]], (int,))
|
||||
self.assertEqual(C[Concatenate[str, P2]], Concatenate[int, str, P2])
|
||||
with self.assertRaises(TypeError):
|
||||
C[...]
|
||||
self.assertEqual(C[...], Concatenate[int, ...])
|
||||
|
||||
class TypeGuardTests(BaseTestCase):
|
||||
def test_basics(self):
|
||||
|
|
|
@ -714,9 +714,9 @@ def Concatenate(self, parameters):
|
|||
raise TypeError("Cannot take a Concatenate of no types.")
|
||||
if not isinstance(parameters, tuple):
|
||||
parameters = (parameters,)
|
||||
if not isinstance(parameters[-1], ParamSpec):
|
||||
if not (parameters[-1] is ... or isinstance(parameters[-1], ParamSpec)):
|
||||
raise TypeError("The last parameter to Concatenate should be a "
|
||||
"ParamSpec variable.")
|
||||
"ParamSpec variable or ellipsis.")
|
||||
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,
|
||||
|
@ -1641,9 +1641,6 @@ class _ConcatenateGenericAlias(_GenericAlias, _root=True):
|
|||
return (*params[:-1], *params[-1])
|
||||
if isinstance(params[-1], _ConcatenateGenericAlias):
|
||||
params = (*params[:-1], *params[-1].__args__)
|
||||
elif not isinstance(params[-1], ParamSpec):
|
||||
raise TypeError("The last parameter to Concatenate should be a "
|
||||
"ParamSpec variable.")
|
||||
return super().copy_with(params)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Accept ellipsis as the last argument of :data:`typing.Concatenate`.
|
Loading…
Add table
Add a link
Reference in a new issue