mirror of
https://github.com/python/cpython.git
synced 2025-08-01 07:33:08 +00:00
bpo-43224: Add tests for TypeVarTuple substitution in Annotated (GH-31846)
This commit is contained in:
parent
468314cc8b
commit
f2bc12f0d5
2 changed files with 85 additions and 0 deletions
|
@ -5873,6 +5873,77 @@ class AnnotatedTests(BaseTestCase):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
LI[None]
|
LI[None]
|
||||||
|
|
||||||
|
def test_typevar_subst(self):
|
||||||
|
dec = "a decoration"
|
||||||
|
Ts = TypeVarTuple('Ts')
|
||||||
|
T = TypeVar('T')
|
||||||
|
T1 = TypeVar('T1')
|
||||||
|
T2 = TypeVar('T2')
|
||||||
|
|
||||||
|
A = Annotated[Tuple[Unpack[Ts]], dec]
|
||||||
|
self.assertEqual(A[int], Annotated[Tuple[int], dec])
|
||||||
|
self.assertEqual(A[str, int], Annotated[Tuple[str, int], dec])
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
Annotated[Unpack[Ts], dec]
|
||||||
|
|
||||||
|
B = Annotated[Tuple[T, Unpack[Ts]], dec]
|
||||||
|
self.assertEqual(B[int], Annotated[Tuple[int], dec])
|
||||||
|
self.assertEqual(B[int, str], Annotated[Tuple[int, str], dec])
|
||||||
|
self.assertEqual(
|
||||||
|
B[int, str, float],
|
||||||
|
Annotated[Tuple[int, str, float], dec]
|
||||||
|
)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
B[()]
|
||||||
|
|
||||||
|
C = Annotated[Tuple[Unpack[Ts], T], dec]
|
||||||
|
self.assertEqual(C[int], Annotated[Tuple[int], dec])
|
||||||
|
self.assertEqual(C[int, str], Annotated[Tuple[int, str], dec])
|
||||||
|
self.assertEqual(
|
||||||
|
C[int, str, float],
|
||||||
|
Annotated[Tuple[int, str, float], dec]
|
||||||
|
)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
C[()]
|
||||||
|
|
||||||
|
D = Annotated[Tuple[T1, Unpack[Ts], T2], dec]
|
||||||
|
self.assertEqual(D[int, str], Annotated[Tuple[int, str], dec])
|
||||||
|
self.assertEqual(
|
||||||
|
D[int, str, float],
|
||||||
|
Annotated[Tuple[int, str, float], dec]
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
D[int, str, bool, float],
|
||||||
|
Annotated[Tuple[int, str, bool, float], dec]
|
||||||
|
)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
D[int]
|
||||||
|
|
||||||
|
# Now let's try creating an alias from an alias.
|
||||||
|
|
||||||
|
Ts2 = TypeVarTuple('Ts2')
|
||||||
|
T3 = TypeVar('T3')
|
||||||
|
T4 = TypeVar('T4')
|
||||||
|
|
||||||
|
E = D[T3, Unpack[Ts2], T4]
|
||||||
|
self.assertEqual(
|
||||||
|
E,
|
||||||
|
Annotated[Tuple[T3, Unpack[Ts2], T4], dec]
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
E[int, str], Annotated[Tuple[int, str], dec]
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
E[int, str, float],
|
||||||
|
Annotated[Tuple[int, str, float], dec]
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
E[int, str, bool, float],
|
||||||
|
Annotated[Tuple[int, str, bool, float], dec]
|
||||||
|
)
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
E[int]
|
||||||
|
|
||||||
def test_annotated_in_other_types(self):
|
def test_annotated_in_other_types(self):
|
||||||
X = List[Annotated[T, 5]]
|
X = List[Annotated[T, 5]]
|
||||||
self.assertEqual(X[int], List[Annotated[int, 5]])
|
self.assertEqual(X[int], List[Annotated[int, 5]])
|
||||||
|
|
|
@ -2080,6 +2080,17 @@ class Annotated:
|
||||||
|
|
||||||
OptimizedList = Annotated[List[T], runtime.Optimize()]
|
OptimizedList = Annotated[List[T], runtime.Optimize()]
|
||||||
OptimizedList[int] == Annotated[List[int], runtime.Optimize()]
|
OptimizedList[int] == Annotated[List[int], runtime.Optimize()]
|
||||||
|
|
||||||
|
- Annotated cannot be used with an unpacked TypeVarTuple::
|
||||||
|
|
||||||
|
Annotated[*Ts, Ann1] # NOT valid
|
||||||
|
|
||||||
|
This would be equivalent to
|
||||||
|
|
||||||
|
Annotated[T1, T2, T3, ..., Ann1]
|
||||||
|
|
||||||
|
where T1, T2 etc. are TypeVars, which would be invalid, because
|
||||||
|
only one type should be passed to Annotated.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
@ -2093,6 +2104,9 @@ class Annotated:
|
||||||
raise TypeError("Annotated[...] should be used "
|
raise TypeError("Annotated[...] should be used "
|
||||||
"with at least two arguments (a type and an "
|
"with at least two arguments (a type and an "
|
||||||
"annotation).")
|
"annotation).")
|
||||||
|
if _is_unpacked_typevartuple(params[0]):
|
||||||
|
raise TypeError("Annotated[...] should not be used with an "
|
||||||
|
"unpacked TypeVarTuple")
|
||||||
msg = "Annotated[t, ...]: t must be a type."
|
msg = "Annotated[t, ...]: t must be a type."
|
||||||
origin = _type_check(params[0], msg, allow_special_forms=True)
|
origin = _type_check(params[0], msg, allow_special_forms=True)
|
||||||
metadata = tuple(params[1:])
|
metadata = tuple(params[1:])
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue