diff options
Diffstat (limited to 'Lib/test/test_typing.py')
| -rw-r--r-- | Lib/test/test_typing.py | 105 |
1 files changed, 104 insertions, 1 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index eb61893..088db9c 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -18,7 +18,7 @@ from typing import get_type_hints from typing import no_type_check, no_type_check_decorator from typing import Type from typing import NewType -from typing import NamedTuple +from typing import NamedTuple, TypedDict from typing import IO, TextIO, BinaryIO from typing import Pattern, Match import abc @@ -1883,6 +1883,18 @@ class XRepr(NamedTuple): def __add__(self, other): return 0 +Label = TypedDict('Label', [('label', str)]) + +class Point2D(TypedDict): + x: int + y: int + +class LabelPoint2D(Point2D, Label): ... + +class Options(TypedDict, total=False): + log_level: int + log_path: str + class HasForeignBaseClass(mod_generics_cache.A): some_xrepr: 'XRepr' other_a: 'mod_generics_cache.A' @@ -2658,6 +2670,97 @@ class XMethBad2(NamedTuple): self.assertEqual(jane2, jane) +class TypedDictTests(BaseTestCase): + def test_basics_functional_syntax(self): + Emp = TypedDict('Emp', {'name': str, 'id': int}) + self.assertIsSubclass(Emp, dict) + self.assertIsSubclass(Emp, typing.MutableMapping) + self.assertNotIsSubclass(Emp, collections.abc.Sequence) + jim = Emp(name='Jim', id=1) + self.assertIs(type(jim), dict) + self.assertEqual(jim['name'], 'Jim') + self.assertEqual(jim['id'], 1) + self.assertEqual(Emp.__name__, 'Emp') + self.assertEqual(Emp.__module__, __name__) + self.assertEqual(Emp.__bases__, (dict,)) + self.assertEqual(Emp.__annotations__, {'name': str, 'id': int}) + self.assertEqual(Emp.__total__, True) + + def test_basics_keywords_syntax(self): + Emp = TypedDict('Emp', name=str, id=int) + self.assertIsSubclass(Emp, dict) + self.assertIsSubclass(Emp, typing.MutableMapping) + self.assertNotIsSubclass(Emp, collections.abc.Sequence) + jim = Emp(name='Jim', id=1) + self.assertIs(type(jim), dict) + self.assertEqual(jim['name'], 'Jim') + self.assertEqual(jim['id'], 1) + self.assertEqual(Emp.__name__, 'Emp') + self.assertEqual(Emp.__module__, __name__) + self.assertEqual(Emp.__bases__, (dict,)) + self.assertEqual(Emp.__annotations__, {'name': str, 'id': int}) + self.assertEqual(Emp.__total__, True) + + def test_typeddict_errors(self): + Emp = TypedDict('Emp', {'name': str, 'id': int}) + self.assertEqual(TypedDict.__module__, 'typing') + jim = Emp(name='Jim', id=1) + with self.assertRaises(TypeError): + isinstance({}, Emp) + with self.assertRaises(TypeError): + isinstance(jim, Emp) + with self.assertRaises(TypeError): + issubclass(dict, Emp) + with self.assertRaises(TypeError): + TypedDict('Hi', x=1) + with self.assertRaises(TypeError): + TypedDict('Hi', [('x', int), ('y', 1)]) + with self.assertRaises(TypeError): + TypedDict('Hi', [('x', int)], y=int) + + def test_py36_class_syntax_usage(self): + self.assertEqual(LabelPoint2D.__name__, 'LabelPoint2D') + self.assertEqual(LabelPoint2D.__module__, __name__) + self.assertEqual(LabelPoint2D.__annotations__, {'x': int, 'y': int, 'label': str}) + self.assertEqual(LabelPoint2D.__bases__, (dict,)) + self.assertEqual(LabelPoint2D.__total__, True) + self.assertNotIsSubclass(LabelPoint2D, typing.Sequence) + not_origin = Point2D(x=0, y=1) + self.assertEqual(not_origin['x'], 0) + self.assertEqual(not_origin['y'], 1) + other = LabelPoint2D(x=0, y=1, label='hi') + self.assertEqual(other['label'], 'hi') + + def test_pickle(self): + global EmpD # pickle wants to reference the class by name + EmpD = TypedDict('EmpD', name=str, id=int) + jane = EmpD({'name': 'jane', 'id': 37}) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z = pickle.dumps(jane, proto) + jane2 = pickle.loads(z) + self.assertEqual(jane2, jane) + self.assertEqual(jane2, {'name': 'jane', 'id': 37}) + ZZ = pickle.dumps(EmpD, proto) + EmpDnew = pickle.loads(ZZ) + self.assertEqual(EmpDnew({'name': 'jane', 'id': 37}), jane) + + def test_optional(self): + EmpD = TypedDict('EmpD', name=str, id=int) + + self.assertEqual(typing.Optional[EmpD], typing.Union[None, EmpD]) + self.assertNotEqual(typing.List[EmpD], typing.Tuple[EmpD]) + + def test_total(self): + D = TypedDict('D', {'x': int}, total=False) + self.assertEqual(D(), {}) + self.assertEqual(D(x=1), {'x': 1}) + self.assertEqual(D.__total__, False) + + self.assertEqual(Options(), {}) + self.assertEqual(Options(log_level=2), {'log_level': 2}) + self.assertEqual(Options.__total__, False) + + class IOTests(BaseTestCase): def test_io(self): |
