diff options
Diffstat (limited to 'Lib/test/test_typing.py')
-rw-r--r-- | Lib/test/test_typing.py | 96 |
1 files changed, 91 insertions, 5 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index dff737a..9159149 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -548,9 +548,9 @@ class GenericTests(BaseTestCase): def test_repr(self): self.assertEqual(repr(SimpleMapping), - __name__ + '.' + 'SimpleMapping<~XK, ~XV>') + __name__ + '.' + 'SimpleMapping') self.assertEqual(repr(MySimpleMapping), - __name__ + '.' + 'MySimpleMapping<~XK, ~XV>') + __name__ + '.' + 'MySimpleMapping') def test_chain_repr(self): T = TypeVar('T') @@ -574,7 +574,36 @@ class GenericTests(BaseTestCase): self.assertNotEqual(Z, Y[T]) self.assertTrue(str(Z).endswith( - '.C<~T>[typing.Tuple[~S, ~T]]<~S, ~T>[~T, int]<~T>[str]')) + '.C[typing.Tuple[str, int]]')) + + def test_new_repr(self): + T = TypeVar('T') + U = TypeVar('U', covariant=True) + S = TypeVar('S') + + self.assertEqual(repr(List), 'typing.List') + self.assertEqual(repr(List[T]), 'typing.List[~T]') + self.assertEqual(repr(List[U]), 'typing.List[+U]') + self.assertEqual(repr(List[S][T][int]), 'typing.List[int]') + self.assertEqual(repr(List[int]), 'typing.List[int]') + + def test_new_repr_complex(self): + T = TypeVar('T') + TS = TypeVar('TS') + + self.assertEqual(repr(typing.Mapping[T, TS][TS, T]), 'typing.Mapping[~TS, ~T]') + self.assertEqual(repr(List[Tuple[T, TS]][int, T]), + 'typing.List[typing.Tuple[int, ~T]]') + self.assertEqual(repr(List[Tuple[T, T]][List[int]]), + 'typing.List[typing.Tuple[typing.List[int], typing.List[int]]]') + + def test_new_repr_bare(self): + T = TypeVar('T') + self.assertEqual(repr(Generic[T]), 'typing.Generic[~T]') + self.assertEqual(repr(typing._Protocol[T]), 'typing.Protocol[~T]') + class C(typing.Dict[Any, Any]): ... + # this line should just work + repr(C.__mro__) def test_dict(self): T = TypeVar('T') @@ -625,6 +654,63 @@ class GenericTests(BaseTestCase): class MM2(collections_abc.MutableMapping, MutableMapping[str, str]): pass + def test_orig_bases(self): + T = TypeVar('T') + class C(typing.Dict[str, T]): ... + self.assertEqual(C.__orig_bases__, (typing.Dict[str, T],)) + + def test_naive_runtime_checks(self): + def naive_dict_check(obj, tp): + # Check if a dictionary conforms to Dict type + if len(tp.__parameters__) > 0: + raise NotImplementedError + if tp.__args__: + KT, VT = tp.__args__ + return all(isinstance(k, KT) and isinstance(v, VT) + for k, v in obj.items()) + self.assertTrue(naive_dict_check({'x': 1}, typing.Dict[str, int])) + self.assertFalse(naive_dict_check({1: 'x'}, typing.Dict[str, int])) + with self.assertRaises(NotImplementedError): + naive_dict_check({1: 'x'}, typing.Dict[str, T]) + + def naive_generic_check(obj, tp): + # Check if an instance conforms to the generic class + if not hasattr(obj, '__orig_class__'): + raise NotImplementedError + return obj.__orig_class__ == tp + class Node(Generic[T]): ... + self.assertTrue(naive_generic_check(Node[int](), Node[int])) + self.assertFalse(naive_generic_check(Node[str](), Node[int])) + self.assertFalse(naive_generic_check(Node[str](), List)) + with self.assertRaises(NotImplementedError): + naive_generic_check([1,2,3], Node[int]) + + def naive_list_base_check(obj, tp): + # Check if list conforms to a List subclass + return all(isinstance(x, tp.__orig_bases__[0].__args__[0]) + for x in obj) + class C(List[int]): ... + self.assertTrue(naive_list_base_check([1, 2, 3], C)) + self.assertFalse(naive_list_base_check(['a', 'b'], C)) + + def test_multi_subscr_base(self): + T = TypeVar('T') + U = TypeVar('U') + V = TypeVar('V') + class C(List[T][U][V]): ... + class D(C, List[T][U][V]): ... + self.assertEqual(C.__parameters__, (V,)) + self.assertEqual(D.__parameters__, (V,)) + self.assertEqual(C[int].__parameters__, ()) + self.assertEqual(D[int].__parameters__, ()) + self.assertEqual(C[int].__args__, (int,)) + self.assertEqual(D[int].__args__, (int,)) + self.assertEqual(C.__bases__, (List,)) + self.assertEqual(D.__bases__, (C, List)) + self.assertEqual(C.__orig_bases__, (List[T][U][V],)) + self.assertEqual(D.__orig_bases__, (C, List[T][U][V])) + + def test_pickle(self): global C # pickle wants to reference the class by name T = TypeVar('T') @@ -662,12 +748,12 @@ class GenericTests(BaseTestCase): if not PY32: self.assertEqual(C.__qualname__, 'GenericTests.test_repr_2.<locals>.C') - self.assertEqual(repr(C).split('.')[-1], 'C<~T>') + self.assertEqual(repr(C).split('.')[-1], 'C') X = C[int] self.assertEqual(X.__module__, __name__) if not PY32: self.assertEqual(X.__qualname__, 'C') - self.assertEqual(repr(X).split('.')[-1], 'C<~T>[int]') + self.assertEqual(repr(X).split('.')[-1], 'C[int]') class Y(C[int]): pass |