diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2021-08-04 18:07:01 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-04 18:07:01 (GMT) |
commit | 3875a6954741065b136650db67ac533bc70a3eac (patch) | |
tree | 14347458795f0017b39dad3c686b4459c6e6a904 /Lib/test/test_typing.py | |
parent | 10faada709561663d6b1f623d308ff45e3808cca (diff) | |
download | cpython-3875a6954741065b136650db67ac533bc70a3eac.zip cpython-3875a6954741065b136650db67ac533bc70a3eac.tar.gz cpython-3875a6954741065b136650db67ac533bc70a3eac.tar.bz2 |
bpo-44801: Check arguments in substitution of ParamSpec in Callable (GH-27585)
Diffstat (limited to 'Lib/test/test_typing.py')
-rw-r--r-- | Lib/test/test_typing.py | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 1a172a0..439d963 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -581,17 +581,33 @@ class BaseCallableTests: Callable = self.Callable fullname = f"{Callable.__module__}.Callable" P = ParamSpec('P') + P2 = ParamSpec('P2') C1 = Callable[P, T] # substitution - self.assertEqual(C1[int, str], Callable[[int], str]) + self.assertEqual(C1[[int], str], Callable[[int], str]) self.assertEqual(C1[[int, str], str], Callable[[int, str], str]) + self.assertEqual(C1[[], str], Callable[[], str]) + self.assertEqual(C1[..., str], Callable[..., str]) + self.assertEqual(C1[P2, str], Callable[P2, str]) + self.assertEqual(C1[Concatenate[int, P2], str], + Callable[Concatenate[int, P2], str]) self.assertEqual(repr(C1), f"{fullname}[~P, ~T]") - self.assertEqual(repr(C1[int, str]), f"{fullname}[[int], str]") + self.assertEqual(repr(C1[[int, str], str]), f"{fullname}[[int, str], str]") + with self.assertRaises(TypeError): + C1[int, str] C2 = Callable[P, int] + self.assertEqual(C2[[int]], Callable[[int], int]) + self.assertEqual(C2[[int, str]], Callable[[int, str], int]) + self.assertEqual(C2[[]], Callable[[], int]) + self.assertEqual(C2[...], Callable[..., int]) + self.assertEqual(C2[P2], Callable[P2, int]) + self.assertEqual(C2[Concatenate[int, P2]], + Callable[Concatenate[int, P2], int]) # special case in PEP 612 where # X[int, str, float] == X[[int, str, float]] - self.assertEqual(C2[int, str, float], C2[[int, str, float]]) + self.assertEqual(C2[int], Callable[[int], int]) + self.assertEqual(C2[int, str], Callable[[int, str], int]) self.assertEqual(repr(C2), f"{fullname}[~P, int]") self.assertEqual(repr(C2[int, str]), f"{fullname}[[int, str], int]") @@ -4656,6 +4672,29 @@ class ParamSpecTests(BaseTestCase): self.assertEqual(G5.__parameters__, G6.__parameters__) self.assertEqual(G5, G6) + G7 = Z[int] + self.assertEqual(G7.__args__, ((int,),)) + self.assertEqual(G7.__parameters__, ()) + + with self.assertRaisesRegex(TypeError, "many arguments for"): + Z[[int, str], bool] + with self.assertRaisesRegex(TypeError, "many arguments for"): + Z[P_2, bool] + + def test_multiple_paramspecs_in_user_generics(self): + P = ParamSpec("P") + P2 = ParamSpec("P2") + + class X(Generic[P, P2]): + f: Callable[P, int] + g: Callable[P2, str] + + G1 = X[[int, str], [bytes]] + G2 = X[[int], [str, bytes]] + self.assertNotEqual(G1, G2) + self.assertEqual(G1.__args__, ((int, str), (bytes,))) + self.assertEqual(G2.__args__, ((int,), (str, bytes))) + def test_no_paramspec_in__parameters__(self): # ParamSpec should not be found in __parameters__ # of generics. Usages outside Callable, Concatenate |