summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_typing.py
diff options
context:
space:
mode:
authorkj <28750310+Fidget-Spinner@users.noreply.github.com>2020-12-24 04:33:48 (GMT)
committerGitHub <noreply@github.com>2020-12-24 04:33:48 (GMT)
commit73607be68668ab7f4bee53507c8dc7b5a46c9cb4 (patch)
tree4ec6bb3f178e61b7fc61d979ec65519a4ef1d4bc /Lib/test/test_typing.py
parentcc3467a57b61b0e7ef254b36790a1c44b13f2228 (diff)
downloadcpython-73607be68668ab7f4bee53507c8dc7b5a46c9cb4.zip
cpython-73607be68668ab7f4bee53507c8dc7b5a46c9cb4.tar.gz
cpython-73607be68668ab7f4bee53507c8dc7b5a46c9cb4.tar.bz2
bpo-41559: Implement PEP 612 - Add ParamSpec and Concatenate to typing (#23702)
Diffstat (limited to 'Lib/test/test_typing.py')
-rw-r--r--Lib/test/test_typing.py120
1 files changed, 106 insertions, 14 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 8e86e76..c340c8a 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -25,6 +25,7 @@ from typing import IO, TextIO, BinaryIO
from typing import Pattern, Match
from typing import Annotated, ForwardRef
from typing import TypeAlias
+from typing import ParamSpec, Concatenate
import abc
import typing
import weakref
@@ -1130,10 +1131,6 @@ class ProtocolTests(BaseTestCase):
PR[int]
with self.assertRaises(TypeError):
P[int, str]
- with self.assertRaises(TypeError):
- PR[int, 1]
- with self.assertRaises(TypeError):
- PR[int, ClassVar]
class C(PR[int, T]): pass
@@ -1155,8 +1152,6 @@ class ProtocolTests(BaseTestCase):
self.assertIsSubclass(P, PR)
with self.assertRaises(TypeError):
PR[int]
- with self.assertRaises(TypeError):
- PR[int, 1]
class P1(Protocol, Generic[T]):
def bar(self, x: T) -> str: ...
@@ -1175,8 +1170,6 @@ class ProtocolTests(BaseTestCase):
return x
self.assertIsInstance(Test(), PSub)
- with self.assertRaises(TypeError):
- PR[int, ClassVar]
def test_init_called(self):
T = TypeVar('T')
@@ -1746,8 +1739,6 @@ class GenericTests(BaseTestCase):
self.assertEqual(typing.Iterable[Tuple[T, T]][T], typing.Iterable[Tuple[T, T]])
with self.assertRaises(TypeError):
Tuple[T, int][()]
- with self.assertRaises(TypeError):
- Tuple[T, U][T, ...]
self.assertEqual(Union[T, int][int], int)
self.assertEqual(Union[T, U][int, Union[int, str]], Union[int, str])
@@ -1759,10 +1750,6 @@ class GenericTests(BaseTestCase):
self.assertEqual(Callable[[T], T][KT], Callable[[KT], KT])
self.assertEqual(Callable[..., List[T]][int], Callable[..., List[int]])
- with self.assertRaises(TypeError):
- Callable[[T], U][..., int]
- with self.assertRaises(TypeError):
- Callable[[T], U][[], int]
def test_extended_generic_rules_repr(self):
T = TypeVar('T')
@@ -4243,6 +4230,111 @@ class TypeAliasTests(BaseTestCase):
TypeAlias[int]
+class ParamSpecTests(BaseTestCase):
+
+ def test_basic_plain(self):
+ P = ParamSpec('P')
+ self.assertEqual(P, P)
+ self.assertIsInstance(P, ParamSpec)
+
+ def test_valid_uses(self):
+ P = ParamSpec('P')
+ T = TypeVar('T')
+ C1 = Callable[P, int]
+ self.assertEqual(C1.__args__, (P, int))
+ self.assertEqual(C1.__parameters__, (P,))
+ C2 = Callable[P, T]
+ self.assertEqual(C2.__args__, (P, T))
+ self.assertEqual(C2.__parameters__, (P, T))
+ # Test collections.abc.Callable too.
+ C3 = collections.abc.Callable[P, int]
+ self.assertEqual(C3.__args__, (P, int))
+ self.assertEqual(C3.__parameters__, (P,))
+ C4 = collections.abc.Callable[P, T]
+ self.assertEqual(C4.__args__, (P, T))
+ self.assertEqual(C4.__parameters__, (P, T))
+
+ # ParamSpec instances should also have args and kwargs attributes.
+ self.assertIn('args', dir(P))
+ self.assertIn('kwargs', dir(P))
+ P.args
+ P.kwargs
+
+ def test_user_generics(self):
+ T = TypeVar("T")
+ P = ParamSpec("P")
+ P_2 = ParamSpec("P_2")
+
+ class X(Generic[T, P]):
+ f: Callable[P, int]
+ x: T
+ G1 = X[int, P_2]
+ self.assertEqual(G1.__args__, (int, P_2))
+ self.assertEqual(G1.__parameters__, (P_2,))
+
+ G2 = X[int, Concatenate[int, P_2]]
+ self.assertEqual(G2.__args__, (int, Concatenate[int, P_2]))
+ self.assertEqual(G2.__parameters__, (P_2,))
+
+ G3 = X[int, [int, bool]]
+ self.assertEqual(G3.__args__, (int, (int, bool)))
+ self.assertEqual(G3.__parameters__, ())
+
+ G4 = X[int, ...]
+ self.assertEqual(G4.__args__, (int, Ellipsis))
+ self.assertEqual(G4.__parameters__, ())
+
+ class Z(Generic[P]):
+ f: Callable[P, int]
+
+ G5 = Z[[int, str, bool]]
+ self.assertEqual(G5.__args__, ((int, str, bool),))
+ self.assertEqual(G5.__parameters__, ())
+
+ G6 = Z[int, str, bool]
+ self.assertEqual(G6.__args__, ((int, str, bool),))
+ self.assertEqual(G6.__parameters__, ())
+
+ # G5 and G6 should be equivalent according to the PEP
+ self.assertEqual(G5.__args__, G6.__args__)
+ self.assertEqual(G5.__origin__, G6.__origin__)
+ self.assertEqual(G5.__parameters__, G6.__parameters__)
+ self.assertEqual(G5, G6)
+
+ def test_var_substitution(self):
+ T = TypeVar("T")
+ P = ParamSpec("P")
+ C1 = Callable[P, T]
+ self.assertEqual(C1[int, str], Callable[[int], str])
+ self.assertEqual(C1[[int, str, dict], float], Callable[[int, str, dict], float])
+
+
+class ConcatenateTests(BaseTestCase):
+ def test_basics(self):
+ P = ParamSpec('P')
+ class MyClass: ...
+ c = Concatenate[MyClass, P]
+ self.assertNotEqual(c, Concatenate)
+
+ def test_valid_uses(self):
+ P = ParamSpec('P')
+ T = TypeVar('T')
+ C1 = Callable[Concatenate[int, P], int]
+ self.assertEqual(C1.__args__, (Concatenate[int, P], int))
+ self.assertEqual(C1.__parameters__, (P,))
+ C2 = Callable[Concatenate[int, T, P], T]
+ self.assertEqual(C2.__args__, (Concatenate[int, T, P], T))
+ self.assertEqual(C2.__parameters__, (T, P))
+
+ # Test collections.abc.Callable too.
+ C3 = collections.abc.Callable[Concatenate[int, P], int]
+ self.assertEqual(C3.__args__, (Concatenate[int, P], int))
+ self.assertEqual(C3.__parameters__, (P,))
+ C4 = collections.abc.Callable[Concatenate[int, T, P], T]
+ self.assertEqual(C4.__args__, (Concatenate[int, T, P], T))
+ self.assertEqual(C4.__parameters__, (T, P))
+
+
class AllTests(BaseTestCase):
"""Tests for __all__."""