|
51 | 51 | c_typing = import_helper.import_fresh_module('typing', fresh=['_typing'])
|
52 | 52 |
|
53 | 53 |
|
| 54 | +CANNOT_SUBCLASS_TYPE = 'Cannot subclass special typing classes' |
| 55 | +CANNOT_SUBCLASS_INSTANCE = 'Cannot subclass an instance of %s' |
| 56 | + |
| 57 | + |
54 | 58 | class BaseTestCase(TestCase):
|
55 | 59 |
|
56 | 60 | def assertIsSubclass(self, cls, class_or_tuple, msg=None):
|
@@ -170,10 +174,11 @@ def test_not_generic(self):
|
170 | 174 | self.bottom_type[int]
|
171 | 175 |
|
172 | 176 | def test_cannot_subclass(self):
|
173 |
| - with self.assertRaises(TypeError): |
| 177 | + with self.assertRaisesRegex(TypeError, |
| 178 | + 'Cannot subclass ' + re.escape(str(self.bottom_type))): |
174 | 179 | class A(self.bottom_type):
|
175 | 180 | pass
|
176 |
| - with self.assertRaises(TypeError): |
| 181 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
177 | 182 | class A(type(self.bottom_type)):
|
178 | 183 | pass
|
179 | 184 |
|
@@ -266,10 +271,11 @@ def test_cannot_subscript(self):
|
266 | 271 | Self[int]
|
267 | 272 |
|
268 | 273 | def test_cannot_subclass(self):
|
269 |
| - with self.assertRaises(TypeError): |
| 274 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
270 | 275 | class C(type(Self)):
|
271 | 276 | pass
|
272 |
| - with self.assertRaises(TypeError): |
| 277 | + with self.assertRaisesRegex(TypeError, |
| 278 | + r'Cannot subclass typing\.Self'): |
273 | 279 | class C(Self):
|
274 | 280 | pass
|
275 | 281 |
|
@@ -322,10 +328,11 @@ def test_cannot_subscript(self):
|
322 | 328 | LiteralString[int]
|
323 | 329 |
|
324 | 330 | def test_cannot_subclass(self):
|
325 |
| - with self.assertRaises(TypeError): |
| 331 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
326 | 332 | class C(type(LiteralString)):
|
327 | 333 | pass
|
328 |
| - with self.assertRaises(TypeError): |
| 334 | + with self.assertRaisesRegex(TypeError, |
| 335 | + r'Cannot subclass typing\.LiteralString'): |
329 | 336 | class C(LiteralString):
|
330 | 337 | pass
|
331 | 338 |
|
@@ -415,15 +422,13 @@ def test_no_redefinition(self):
|
415 | 422 | self.assertNotEqual(TypeVar('T'), TypeVar('T'))
|
416 | 423 | self.assertNotEqual(TypeVar('T', int, str), TypeVar('T', int, str))
|
417 | 424 |
|
418 |
| - def test_cannot_subclass_vars(self): |
419 |
| - with self.assertRaises(TypeError): |
420 |
| - class V(TypeVar('T')): |
421 |
| - pass |
422 |
| - |
423 |
| - def test_cannot_subclass_var_itself(self): |
424 |
| - with self.assertRaises(TypeError): |
425 |
| - class V(TypeVar): |
426 |
| - pass |
| 425 | + def test_cannot_subclass(self): |
| 426 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
| 427 | + class V(TypeVar): pass |
| 428 | + T = TypeVar("T") |
| 429 | + with self.assertRaisesRegex(TypeError, |
| 430 | + CANNOT_SUBCLASS_INSTANCE % 'TypeVar'): |
| 431 | + class V(T): pass |
427 | 432 |
|
428 | 433 | def test_cannot_instantiate_vars(self):
|
429 | 434 | with self.assertRaises(TypeError):
|
@@ -1016,15 +1021,14 @@ class A(Generic[Unpack[Ts]]): pass
|
1016 | 1021 | self.assertEndsWith(repr(F[float]), 'A[float, *tuple[str, ...]]')
|
1017 | 1022 | self.assertEndsWith(repr(F[float, str]), 'A[float, str, *tuple[str, ...]]')
|
1018 | 1023 |
|
1019 |
| - def test_cannot_subclass_class(self): |
1020 |
| - with self.assertRaises(TypeError): |
| 1024 | + def test_cannot_subclass(self): |
| 1025 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
1021 | 1026 | class C(TypeVarTuple): pass
|
1022 |
| - |
1023 |
| - def test_cannot_subclass_instance(self): |
1024 | 1027 | Ts = TypeVarTuple('Ts')
|
1025 |
| - with self.assertRaises(TypeError): |
| 1028 | + with self.assertRaisesRegex(TypeError, |
| 1029 | + CANNOT_SUBCLASS_INSTANCE % 'TypeVarTuple'): |
1026 | 1030 | class C(Ts): pass
|
1027 |
| - with self.assertRaises(TypeError): |
| 1031 | + with self.assertRaisesRegex(TypeError, r'Cannot subclass \*Ts'): |
1028 | 1032 | class C(Unpack[Ts]): pass
|
1029 | 1033 |
|
1030 | 1034 | def test_variadic_class_args_are_correct(self):
|
@@ -1411,13 +1415,15 @@ def test_repr(self):
|
1411 | 1415 | self.assertEqual(repr(u), 'typing.Optional[str]')
|
1412 | 1416 |
|
1413 | 1417 | def test_cannot_subclass(self):
|
1414 |
| - with self.assertRaises(TypeError): |
| 1418 | + with self.assertRaisesRegex(TypeError, |
| 1419 | + r'Cannot subclass typing\.Union'): |
1415 | 1420 | class C(Union):
|
1416 | 1421 | pass
|
1417 |
| - with self.assertRaises(TypeError): |
| 1422 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
1418 | 1423 | class C(type(Union)):
|
1419 | 1424 | pass
|
1420 |
| - with self.assertRaises(TypeError): |
| 1425 | + with self.assertRaisesRegex(TypeError, |
| 1426 | + r'Cannot subclass typing\.Union\[int, str\]'): |
1421 | 1427 | class C(Union[int, str]):
|
1422 | 1428 | pass
|
1423 | 1429 |
|
@@ -3658,10 +3664,10 @@ def test_repr(self):
|
3658 | 3664 | self.assertEqual(repr(cv), 'typing.ClassVar[%s.Employee]' % __name__)
|
3659 | 3665 |
|
3660 | 3666 | def test_cannot_subclass(self):
|
3661 |
| - with self.assertRaises(TypeError): |
| 3667 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
3662 | 3668 | class C(type(ClassVar)):
|
3663 | 3669 | pass
|
3664 |
| - with self.assertRaises(TypeError): |
| 3670 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
3665 | 3671 | class C(type(ClassVar[int])):
|
3666 | 3672 | pass
|
3667 | 3673 |
|
@@ -3700,10 +3706,10 @@ def test_repr(self):
|
3700 | 3706 | self.assertEqual(repr(cv), 'typing.Final[tuple[int]]')
|
3701 | 3707 |
|
3702 | 3708 | def test_cannot_subclass(self):
|
3703 |
| - with self.assertRaises(TypeError): |
| 3709 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
3704 | 3710 | class C(type(Final)):
|
3705 | 3711 | pass
|
3706 |
| - with self.assertRaises(TypeError): |
| 3712 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
3707 | 3713 | class C(type(Final[int])):
|
3708 | 3714 | pass
|
3709 | 3715 |
|
@@ -6206,16 +6212,18 @@ def test_repr(self):
|
6206 | 6212 | self.assertEqual(repr(cv), f'typing.Required[{__name__}.Employee]')
|
6207 | 6213 |
|
6208 | 6214 | def test_cannot_subclass(self):
|
6209 |
| - with self.assertRaises(TypeError): |
| 6215 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
6210 | 6216 | class C(type(Required)):
|
6211 | 6217 | pass
|
6212 |
| - with self.assertRaises(TypeError): |
| 6218 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
6213 | 6219 | class C(type(Required[int])):
|
6214 | 6220 | pass
|
6215 |
| - with self.assertRaises(TypeError): |
| 6221 | + with self.assertRaisesRegex(TypeError, |
| 6222 | + r'Cannot subclass typing\.Required'): |
6216 | 6223 | class C(Required):
|
6217 | 6224 | pass
|
6218 |
| - with self.assertRaises(TypeError): |
| 6225 | + with self.assertRaisesRegex(TypeError, |
| 6226 | + r'Cannot subclass typing\.Required\[int\]'): |
6219 | 6227 | class C(Required[int]):
|
6220 | 6228 | pass
|
6221 | 6229 |
|
@@ -6252,16 +6260,18 @@ def test_repr(self):
|
6252 | 6260 | self.assertEqual(repr(cv), f'typing.NotRequired[{__name__}.Employee]')
|
6253 | 6261 |
|
6254 | 6262 | def test_cannot_subclass(self):
|
6255 |
| - with self.assertRaises(TypeError): |
| 6263 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
6256 | 6264 | class C(type(NotRequired)):
|
6257 | 6265 | pass
|
6258 |
| - with self.assertRaises(TypeError): |
| 6266 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
6259 | 6267 | class C(type(NotRequired[int])):
|
6260 | 6268 | pass
|
6261 |
| - with self.assertRaises(TypeError): |
| 6269 | + with self.assertRaisesRegex(TypeError, |
| 6270 | + r'Cannot subclass typing\.NotRequired'): |
6262 | 6271 | class C(NotRequired):
|
6263 | 6272 | pass
|
6264 |
| - with self.assertRaises(TypeError): |
| 6273 | + with self.assertRaisesRegex(TypeError, |
| 6274 | + r'Cannot subclass typing\.NotRequired\[int\]'): |
6265 | 6275 | class C(NotRequired[int]):
|
6266 | 6276 | pass
|
6267 | 6277 |
|
@@ -6677,7 +6687,8 @@ def test_no_issubclass(self):
|
6677 | 6687 | issubclass(TypeAlias, Employee)
|
6678 | 6688 |
|
6679 | 6689 | def test_cannot_subclass(self):
|
6680 |
| - with self.assertRaises(TypeError): |
| 6690 | + with self.assertRaisesRegex(TypeError, |
| 6691 | + r'Cannot subclass typing\.TypeAlias'): |
6681 | 6692 | class C(TypeAlias):
|
6682 | 6693 | pass
|
6683 | 6694 |
|
@@ -6879,6 +6890,24 @@ def test_paramspec_gets_copied(self):
|
6879 | 6890 | self.assertEqual(C2[Concatenate[str, P2]].__parameters__, (P2,))
|
6880 | 6891 | self.assertEqual(C2[Concatenate[T, P2]].__parameters__, (T, P2))
|
6881 | 6892 |
|
| 6893 | + def test_cannot_subclass(self): |
| 6894 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
| 6895 | + class C(ParamSpec): pass |
| 6896 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
| 6897 | + class C(ParamSpecArgs): pass |
| 6898 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
| 6899 | + class C(ParamSpecKwargs): pass |
| 6900 | + P = ParamSpec('P') |
| 6901 | + with self.assertRaisesRegex(TypeError, |
| 6902 | + CANNOT_SUBCLASS_INSTANCE % 'ParamSpec'): |
| 6903 | + class C(P): pass |
| 6904 | + with self.assertRaisesRegex(TypeError, |
| 6905 | + CANNOT_SUBCLASS_INSTANCE % 'ParamSpecArgs'): |
| 6906 | + class C(P.args): pass |
| 6907 | + with self.assertRaisesRegex(TypeError, |
| 6908 | + CANNOT_SUBCLASS_INSTANCE % 'ParamSpecKwargs'): |
| 6909 | + class C(P.kwargs): pass |
| 6910 | + |
6882 | 6911 |
|
6883 | 6912 | class ConcatenateTests(BaseTestCase):
|
6884 | 6913 | def test_basics(self):
|
@@ -6945,10 +6974,10 @@ def test_repr(self):
|
6945 | 6974 | self.assertEqual(repr(cv), 'typing.TypeGuard[tuple[int]]')
|
6946 | 6975 |
|
6947 | 6976 | def test_cannot_subclass(self):
|
6948 |
| - with self.assertRaises(TypeError): |
| 6977 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
6949 | 6978 | class C(type(TypeGuard)):
|
6950 | 6979 | pass
|
6951 |
| - with self.assertRaises(TypeError): |
| 6980 | + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): |
6952 | 6981 | class C(type(TypeGuard[int])):
|
6953 | 6982 | pass
|
6954 | 6983 |
|
|
0 commit comments