| 
									
										
										
										
											2016-04-17 17:52:05 -07:00
										 |  |  | import contextlib | 
					
						
							| 
									
										
										
										
											2016-05-18 08:35:00 -07:00
										 |  |  | import collections | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  | import pickle | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | import re | 
					
						
							|  |  |  | import sys | 
					
						
							| 
									
										
										
										
											2019-06-11 09:18:31 -07:00
										 |  |  | from unittest import TestCase, main, skipUnless, SkipTest, skip | 
					
						
							| 
									
										
										
										
											2016-10-29 12:44:29 -07:00
										 |  |  | from copy import copy, deepcopy | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  | from typing import Any, NoReturn | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | from typing import TypeVar, AnyStr | 
					
						
							|  |  |  | from typing import T, KT, VT  # Not in __all__. | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:48 +01:00
										 |  |  | from typing import Union, Optional, Literal | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  | from typing import Tuple, List, MutableMapping | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | from typing import Callable | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  | from typing import Generic, ClassVar, Final, final, Protocol | 
					
						
							|  |  |  | from typing import cast, runtime_checkable | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | from typing import get_type_hints | 
					
						
							| 
									
										
										
										
											2019-05-31 00:10:07 +01:00
										 |  |  | from typing import get_origin, get_args | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | from typing import no_type_check, no_type_check_decorator | 
					
						
							| 
									
										
										
										
											2016-05-24 16:38:22 -07:00
										 |  |  | from typing import Type | 
					
						
							| 
									
										
										
										
											2016-06-08 11:19:11 -07:00
										 |  |  | from typing import NewType | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  | from typing import NamedTuple, TypedDict | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | from typing import IO, TextIO, BinaryIO | 
					
						
							|  |  |  | from typing import Pattern, Match | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  | from typing import Annotated | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  | import abc | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | import typing | 
					
						
							| 
									
										
										
										
											2017-01-17 20:43:28 -08:00
										 |  |  | import weakref | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  | import types | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  | from test import mod_generics_cache | 
					
						
							| 
									
										
										
										
											2017-12-05 03:43:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class BaseTestCase(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def assertIsSubclass(self, cls, class_or_tuple, msg=None): | 
					
						
							|  |  |  |         if not issubclass(cls, class_or_tuple): | 
					
						
							|  |  |  |             message = '%r is not a subclass of %r' % (cls, class_or_tuple) | 
					
						
							|  |  |  |             if msg is not None: | 
					
						
							|  |  |  |                 message += ' : %s' % msg | 
					
						
							|  |  |  |             raise self.failureException(message) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def assertNotIsSubclass(self, cls, class_or_tuple, msg=None): | 
					
						
							|  |  |  |         if issubclass(cls, class_or_tuple): | 
					
						
							|  |  |  |             message = '%r is a subclass of %r' % (cls, class_or_tuple) | 
					
						
							|  |  |  |             if msg is not None: | 
					
						
							|  |  |  |                 message += ' : %s' % msg | 
					
						
							|  |  |  |             raise self.failureException(message) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-19 10:32:41 -08:00
										 |  |  |     def clear_caches(self): | 
					
						
							|  |  |  |         for f in typing._cleanups: | 
					
						
							|  |  |  |             f() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | class Employee: | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Manager(Employee): | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Founder(Employee): | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ManagingFounder(Manager, Founder): | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class AnyTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |     def test_any_instance_type_error(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(42, Any) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |     def test_any_subclass_type_error(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Employee, Any) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Any, Employee) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(Any), 'typing.Any') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_errors(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(42, Any) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Any[int]  # Any is not a generic type. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class A(Any): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class A(type(Any)): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_instantiate(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Any() | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(Any)() | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |     def test_any_works_with_alias(self): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         # These expressions must simply not fail. | 
					
						
							|  |  |  |         typing.Match[Any] | 
					
						
							|  |  |  |         typing.Pattern[Any] | 
					
						
							|  |  |  |         typing.IO[Any] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  | class NoReturnTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_noreturn_instance_type_error(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(42, NoReturn) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_noreturn_subclass_type_error(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Employee, NoReturn) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(NoReturn, Employee) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(NoReturn), 'typing.NoReturn') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_not_generic(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NoReturn[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class A(NoReturn): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class A(type(NoReturn)): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_instantiate(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NoReturn() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(NoReturn)() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class TypeVarTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_basic_plain(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         # T equals itself. | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(T, T) | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |         # T is an instance of TypeVar | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(T, TypeVar) | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_typevar_instance_type_error(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(42, T) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |     def test_typevar_subclass_type_error(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, T) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(T, int) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_constrained_error(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             X = TypeVar('X', int) | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |             X | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_union_unique(self): | 
					
						
							|  |  |  |         X = TypeVar('X') | 
					
						
							|  |  |  |         Y = TypeVar('Y') | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertNotEqual(X, Y) | 
					
						
							|  |  |  |         self.assertEqual(Union[X], X) | 
					
						
							|  |  |  |         self.assertNotEqual(Union[X], Union[X, Y]) | 
					
						
							|  |  |  |         self.assertEqual(Union[X, X], X) | 
					
						
							|  |  |  |         self.assertNotEqual(Union[X, int], Union[X]) | 
					
						
							|  |  |  |         self.assertNotEqual(Union[X, int], Union[int]) | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |         self.assertEqual(Union[X, int].__args__, (X, int)) | 
					
						
							|  |  |  |         self.assertEqual(Union[X, int].__parameters__, (X,)) | 
					
						
							|  |  |  |         self.assertIs(Union[X, int].__origin__, Union) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_union_constrained(self): | 
					
						
							|  |  |  |         A = TypeVar('A', str, bytes) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertNotEqual(Union[A, str], Union[A]) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(T), '~T') | 
					
						
							|  |  |  |         self.assertEqual(repr(KT), '~KT') | 
					
						
							|  |  |  |         self.assertEqual(repr(VT), '~VT') | 
					
						
							|  |  |  |         self.assertEqual(repr(AnyStr), '~AnyStr') | 
					
						
							|  |  |  |         T_co = TypeVar('T_co', covariant=True) | 
					
						
							|  |  |  |         self.assertEqual(repr(T_co), '+T_co') | 
					
						
							|  |  |  |         T_contra = TypeVar('T_contra', contravariant=True) | 
					
						
							|  |  |  |         self.assertEqual(repr(T_contra), '-T_contra') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_redefinition(self): | 
					
						
							|  |  |  |         self.assertNotEqual(TypeVar('T'), TypeVar('T')) | 
					
						
							|  |  |  |         self.assertNotEqual(TypeVar('T', int, str), TypeVar('T', int, str)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass_vars(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class V(TypeVar('T')): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass_var_itself(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class V(TypeVar): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_instantiate_vars(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypeVar('A')() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_bound_errors(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypeVar('X', bound=42) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypeVar('X', str, float, bound=Employee) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 04:01:53 +08:00
										 |  |  |     def test_missing__name__(self): | 
					
						
							|  |  |  |         # See bpo-39942 | 
					
						
							|  |  |  |         code = ("import typing\n" | 
					
						
							|  |  |  |                 "T = typing.TypeVar('T')\n" | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |         exec(code, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     def test_no_bivariant(self): | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             TypeVar('T', covariant=True, contravariant=True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class UnionTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         u = Union[int, float] | 
					
						
							|  |  |  |         self.assertNotEqual(u, Union) | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_subclass_error(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, Union) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Union, int) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, Union[int, str]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Union[int, str], int) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_union_any(self): | 
					
						
							|  |  |  |         u = Union[Any] | 
					
						
							|  |  |  |         self.assertEqual(u, Any) | 
					
						
							| 
									
										
										
										
											2016-10-03 08:40:50 -07:00
										 |  |  |         u1 = Union[int, Any] | 
					
						
							|  |  |  |         u2 = Union[Any, int] | 
					
						
							|  |  |  |         u3 = Union[Any, object] | 
					
						
							|  |  |  |         self.assertEqual(u1, u2) | 
					
						
							|  |  |  |         self.assertNotEqual(u1, Any) | 
					
						
							|  |  |  |         self.assertNotEqual(u2, Any) | 
					
						
							|  |  |  |         self.assertNotEqual(u3, Any) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_union_object(self): | 
					
						
							|  |  |  |         u = Union[object] | 
					
						
							|  |  |  |         self.assertEqual(u, object) | 
					
						
							| 
									
										
										
										
											2018-05-18 16:00:38 -07:00
										 |  |  |         u1 = Union[int, object] | 
					
						
							|  |  |  |         u2 = Union[object, int] | 
					
						
							|  |  |  |         self.assertEqual(u1, u2) | 
					
						
							|  |  |  |         self.assertNotEqual(u1, object) | 
					
						
							|  |  |  |         self.assertNotEqual(u2, object) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_unordered(self): | 
					
						
							|  |  |  |         u1 = Union[int, float] | 
					
						
							|  |  |  |         u2 = Union[float, int] | 
					
						
							|  |  |  |         self.assertEqual(u1, u2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_single_class_disappears(self): | 
					
						
							|  |  |  |         t = Union[Employee] | 
					
						
							|  |  |  |         self.assertIs(t, Employee) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-18 16:00:38 -07:00
										 |  |  |     def test_base_class_kept(self): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         u = Union[Employee, Manager] | 
					
						
							| 
									
										
										
										
											2018-05-18 16:00:38 -07:00
										 |  |  |         self.assertNotEqual(u, Employee) | 
					
						
							|  |  |  |         self.assertIn(Employee, u.__args__) | 
					
						
							|  |  |  |         self.assertIn(Manager, u.__args__) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_union_union(self): | 
					
						
							|  |  |  |         u = Union[int, float] | 
					
						
							|  |  |  |         v = Union[u, Employee] | 
					
						
							|  |  |  |         self.assertEqual(v, Union[int, float, Employee]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(Union), 'typing.Union') | 
					
						
							|  |  |  |         u = Union[Employee, int] | 
					
						
							|  |  |  |         self.assertEqual(repr(u), 'typing.Union[%s.Employee, int]' % __name__) | 
					
						
							|  |  |  |         u = Union[int, Employee] | 
					
						
							|  |  |  |         self.assertEqual(repr(u), 'typing.Union[int, %s.Employee]' % __name__) | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         u = Union[T, int][int] | 
					
						
							|  |  |  |         self.assertEqual(repr(u), repr(int)) | 
					
						
							|  |  |  |         u = Union[List[int], int] | 
					
						
							|  |  |  |         self.assertEqual(repr(u), 'typing.Union[typing.List[int], int]') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(Union): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(type(Union)): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(Union[int, str]): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_instantiate(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Union() | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(Union)() | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         u = Union[int, float] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             u() | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(u)() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_union_generalization(self): | 
					
						
							|  |  |  |         self.assertFalse(Union[str, typing.Iterable[int]] == str) | 
					
						
							|  |  |  |         self.assertFalse(Union[str, typing.Iterable[int]] == typing.Iterable[int]) | 
					
						
							| 
									
										
										
										
											2018-05-18 16:00:38 -07:00
										 |  |  |         self.assertIn(str, Union[str, typing.Iterable[int]].__args__) | 
					
						
							|  |  |  |         self.assertIn(typing.Iterable[int], Union[str, typing.Iterable[int]].__args__) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-17 20:43:28 -08:00
										 |  |  |     def test_union_compare_other(self): | 
					
						
							|  |  |  |         self.assertNotEqual(Union, object) | 
					
						
							|  |  |  |         self.assertNotEqual(Union, Any) | 
					
						
							|  |  |  |         self.assertNotEqual(ClassVar, Union) | 
					
						
							|  |  |  |         self.assertNotEqual(Optional, Union) | 
					
						
							|  |  |  |         self.assertNotEqual([None], Optional) | 
					
						
							|  |  |  |         self.assertNotEqual(Optional, typing.Mapping) | 
					
						
							|  |  |  |         self.assertNotEqual(Optional[typing.MutableMapping], Union) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_optional(self): | 
					
						
							|  |  |  |         o = Optional[int] | 
					
						
							|  |  |  |         u = Union[int, None] | 
					
						
							|  |  |  |         self.assertEqual(o, u) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_empty(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Union[()] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |     def test_union_instance_type_error(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(42, Union[int, str]) | 
					
						
							| 
									
										
										
										
											2015-10-19 14:55:47 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     def test_no_eval_union(self): | 
					
						
							|  |  |  |         u = Union[int, str] | 
					
						
							|  |  |  |         def f(x: u): ... | 
					
						
							|  |  |  |         self.assertIs(get_type_hints(f)['x'], u) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_function_repr_union(self): | 
					
						
							|  |  |  |         def fun() -> int: ... | 
					
						
							|  |  |  |         self.assertEqual(repr(Union[fun, int]), 'typing.Union[fun, int]') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-19 14:55:47 -07:00
										 |  |  |     def test_union_str_pattern(self): | 
					
						
							|  |  |  |         # Shouldn't crash; see http://bugs.python.org/issue25390 | 
					
						
							|  |  |  |         A = Union[str, Pattern] | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |         A | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 11:19:11 -07:00
										 |  |  |     def test_etree(self): | 
					
						
							|  |  |  |         # See https://github.com/python/typing/issues/229 | 
					
						
							|  |  |  |         # (Only relevant for Python 2.) | 
					
						
							| 
									
										
										
										
											2020-03-28 15:32:36 +03:00
										 |  |  |         from xml.etree.ElementTree import Element | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 11:19:11 -07:00
										 |  |  |         Union[Element, str]  # Shouldn't crash | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def Elem(*args): | 
					
						
							|  |  |  |             return Element(*args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Union[Elem, str]  # Nor should this | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class TupleTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Tuple, Tuple[int, str]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(tuple, Tuple[int, str]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class TP(tuple): ... | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         self.assertTrue(issubclass(tuple, Tuple)) | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         self.assertTrue(issubclass(TP, Tuple)) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 07:37:41 -07:00
										 |  |  |     def test_equality(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(Tuple[int], Tuple[int]) | 
					
						
							|  |  |  |         self.assertEqual(Tuple[int, ...], Tuple[int, ...]) | 
					
						
							|  |  |  |         self.assertNotEqual(Tuple[int], Tuple[int, int]) | 
					
						
							|  |  |  |         self.assertNotEqual(Tuple[int], Tuple[int, ...]) | 
					
						
							| 
									
										
										
										
											2016-04-18 07:37:41 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_tuple_subclass(self): | 
					
						
							|  |  |  |         class MyTuple(tuple): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         self.assertTrue(issubclass(MyTuple, Tuple)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |     def test_tuple_instance_type_error(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance((0, 0), Tuple[int, int]) | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         self.assertIsInstance((0, 0), Tuple) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(Tuple), 'typing.Tuple') | 
					
						
							| 
									
										
										
										
											2016-06-08 11:19:11 -07:00
										 |  |  |         self.assertEqual(repr(Tuple[()]), 'typing.Tuple[()]') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         self.assertEqual(repr(Tuple[int, float]), 'typing.Tuple[int, float]') | 
					
						
							|  |  |  |         self.assertEqual(repr(Tuple[int, ...]), 'typing.Tuple[int, ...]') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_errors(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(42, Tuple) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(42, Tuple[int]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class CallableTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_self_subclass(self): | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             self.assertTrue(issubclass(type(lambda x: x), Callable[[int], int])) | 
					
						
							|  |  |  |         self.assertTrue(issubclass(type(lambda x: x), Callable)) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_eq_hash(self): | 
					
						
							|  |  |  |         self.assertEqual(Callable[[int], int], Callable[[int], int]) | 
					
						
							|  |  |  |         self.assertEqual(len({Callable[[int], int], Callable[[int], int]}), 1) | 
					
						
							|  |  |  |         self.assertNotEqual(Callable[[int], int], Callable[[int], str]) | 
					
						
							|  |  |  |         self.assertNotEqual(Callable[[int], int], Callable[[str], int]) | 
					
						
							|  |  |  |         self.assertNotEqual(Callable[[int], int], Callable[[int, int], int]) | 
					
						
							|  |  |  |         self.assertNotEqual(Callable[[int], int], Callable[[], int]) | 
					
						
							|  |  |  |         self.assertNotEqual(Callable[[int], int], Callable) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_instantiate(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Callable() | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(Callable)() | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         c = Callable[[int], str] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             c() | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(c)() | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-09 13:12:51 -08:00
										 |  |  |     def test_callable_wrong_forms(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Callable[[...], int] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Callable[(), int] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Callable[[()], int] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Callable[[int, 1], 2] | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Callable[int] | 
					
						
							| 
									
										
										
										
											2016-11-09 13:12:51 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |     def test_callable_instance_works(self): | 
					
						
							| 
									
										
										
										
											2015-09-04 12:15:54 -07:00
										 |  |  |         def f(): | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(f, Callable) | 
					
						
							|  |  |  |         self.assertNotIsInstance(None, Callable) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |     def test_callable_instance_type_error(self): | 
					
						
							| 
									
										
										
										
											2015-09-04 12:15:54 -07:00
										 |  |  |         def f(): | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |             self.assertIsInstance(f, Callable[[], None]) | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |             self.assertIsInstance(f, Callable[[], Any]) | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |             self.assertNotIsInstance(None, Callable[[], None]) | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |             self.assertNotIsInstance(None, Callable[[], Any]) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         ct0 = Callable[[], bool] | 
					
						
							|  |  |  |         self.assertEqual(repr(ct0), 'typing.Callable[[], bool]') | 
					
						
							|  |  |  |         ct2 = Callable[[str, float], int] | 
					
						
							|  |  |  |         self.assertEqual(repr(ct2), 'typing.Callable[[str, float], int]') | 
					
						
							|  |  |  |         ctv = Callable[..., str] | 
					
						
							|  |  |  |         self.assertEqual(repr(ctv), 'typing.Callable[..., str]') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |     def test_callable_with_ellipsis(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(a: Callable[..., T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(foo, globals(), locals()), | 
					
						
							|  |  |  |                          {'a': Callable[..., T]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-23 11:01:50 -07:00
										 |  |  |     def test_ellipsis_in_generic(self): | 
					
						
							|  |  |  |         # Shouldn't crash; see https://github.com/python/typing/issues/259 | 
					
						
							|  |  |  |         typing.List[Callable[..., str]] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:48 +01:00
										 |  |  | class LiteralTests(BaseTestCase): | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         # All of these are allowed. | 
					
						
							|  |  |  |         Literal[1] | 
					
						
							|  |  |  |         Literal[1, 2, 3] | 
					
						
							|  |  |  |         Literal["x", "y", "z"] | 
					
						
							|  |  |  |         Literal[None] | 
					
						
							|  |  |  |         Literal[True] | 
					
						
							|  |  |  |         Literal[1, "2", False] | 
					
						
							|  |  |  |         Literal[Literal[1, 2], Literal[4, 5]] | 
					
						
							|  |  |  |         Literal[b"foo", u"bar"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_illegal_parameters_do_not_raise_runtime_errors(self): | 
					
						
							|  |  |  |         # Type checkers should reject these types, but we do not | 
					
						
							|  |  |  |         # raise errors at runtime to maintain maximium flexibility. | 
					
						
							|  |  |  |         Literal[int] | 
					
						
							|  |  |  |         Literal[3j + 2, ..., ()] | 
					
						
							|  |  |  |         Literal[{"foo": 3, "bar": 4}] | 
					
						
							|  |  |  |         Literal[T] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_literals_inside_other_types(self): | 
					
						
							|  |  |  |         List[Literal[1, 2, 3]] | 
					
						
							|  |  |  |         List[Literal[("foo", "bar", "baz")]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(Literal[1]), "typing.Literal[1]") | 
					
						
							|  |  |  |         self.assertEqual(repr(Literal[1, True, "foo"]), "typing.Literal[1, True, 'foo']") | 
					
						
							|  |  |  |         self.assertEqual(repr(Literal[int]), "typing.Literal[int]") | 
					
						
							|  |  |  |         self.assertEqual(repr(Literal), "typing.Literal") | 
					
						
							|  |  |  |         self.assertEqual(repr(Literal[None]), "typing.Literal[None]") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_init(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Literal() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Literal[1]() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(Literal)() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(Literal[1])() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_isinstance_or_issubclass(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(1, Literal[1]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(int, Literal[1]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(1, Literal[1]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, Literal[1]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_subclassing(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class Foo(Literal[1]): pass | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class Bar(Literal): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_multiple_subscripts(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Literal[1][1] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | XK = TypeVar('XK', str, bytes) | 
					
						
							|  |  |  | XV = TypeVar('XV') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SimpleMapping(Generic[XK, XV]): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __getitem__(self, key: XK) -> XV: | 
					
						
							|  |  |  |         ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __setitem__(self, key: XK, value: XV): | 
					
						
							|  |  |  |         ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get(self, key: XK, default: XV = None) -> XV: | 
					
						
							|  |  |  |         ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | class MySimpleMapping(SimpleMapping[XK, XV]): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         self.store = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __getitem__(self, key: str): | 
					
						
							|  |  |  |         return self.store[key] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __setitem__(self, key: str, value): | 
					
						
							|  |  |  |         self.store[key] = value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get(self, key: str, default=None): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             return self.store[key] | 
					
						
							|  |  |  |         except KeyError: | 
					
						
							|  |  |  |             return default | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  | class Coordinate(Protocol): | 
					
						
							|  |  |  |     x: int | 
					
						
							|  |  |  |     y: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @runtime_checkable | 
					
						
							|  |  |  | class Point(Coordinate, Protocol): | 
					
						
							|  |  |  |     label: str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MyPoint: | 
					
						
							|  |  |  |     x: int | 
					
						
							|  |  |  |     y: int | 
					
						
							|  |  |  |     label: str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class XAxis(Protocol): | 
					
						
							|  |  |  |     x: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class YAxis(Protocol): | 
					
						
							|  |  |  |     y: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @runtime_checkable | 
					
						
							|  |  |  | class Position(XAxis, YAxis, Protocol): | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @runtime_checkable | 
					
						
							|  |  |  | class Proto(Protocol): | 
					
						
							|  |  |  |     attr: int | 
					
						
							|  |  |  |     def meth(self, arg: str) -> int: | 
					
						
							|  |  |  |         ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Concrete(Proto): | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Other: | 
					
						
							|  |  |  |     attr: int = 1 | 
					
						
							|  |  |  |     def meth(self, arg: str) -> int: | 
					
						
							|  |  |  |         if arg == 'this': | 
					
						
							|  |  |  |             return 1 | 
					
						
							|  |  |  |         return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NT(NamedTuple): | 
					
						
							|  |  |  |     x: int | 
					
						
							|  |  |  |     y: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @runtime_checkable | 
					
						
							|  |  |  | class HasCallProtocol(Protocol): | 
					
						
							|  |  |  |     __call__: typing.Callable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class ProtocolTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |     def test_basic_protocol(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             def meth(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D: | 
					
						
							|  |  |  |             def meth(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def f(): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsSubclass(D, P) | 
					
						
							|  |  |  |         self.assertIsInstance(D(), P) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(C, P) | 
					
						
							|  |  |  |         self.assertNotIsInstance(C(), P) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(types.FunctionType, P) | 
					
						
							|  |  |  |         self.assertNotIsInstance(f, P) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_everything_implements_empty_protocol(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class Empty(Protocol): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def f(): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for thing in (object, type, tuple, C, types.FunctionType): | 
					
						
							|  |  |  |             self.assertIsSubclass(thing, Empty) | 
					
						
							|  |  |  |         for thing in (object(), 1, (), typing, f): | 
					
						
							|  |  |  |             self.assertIsInstance(thing, Empty) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_function_implements_protocol(self): | 
					
						
							|  |  |  |         def f(): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(f, HasCallProtocol) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_inheritance_from_nominal(self): | 
					
						
							|  |  |  |         class C: pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class BP(Protocol): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class P(C, Protocol): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class P(Protocol, C): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class P(BP, C, Protocol): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D(BP, C): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class E(C, BP): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotIsInstance(D(), E) | 
					
						
							|  |  |  |         self.assertNotIsInstance(E(), D) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_instantiation(self): | 
					
						
							|  |  |  |         class P(Protocol): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             P() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(P): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(C(), C) | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class PG(Protocol[T]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             PG() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             PG[int]() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             PG[T]() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CG(PG[T]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(CG[int](), CG) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_instantiate_abstract(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             @abc.abstractmethod | 
					
						
							|  |  |  |             def ameth(self) -> int: | 
					
						
							|  |  |  |                 raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class B(P): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(B): | 
					
						
							|  |  |  |             def ameth(self) -> int: | 
					
						
							|  |  |  |                 return 26 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             B() | 
					
						
							|  |  |  |         self.assertIsInstance(C(), P) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_subprotocols_extending(self): | 
					
						
							|  |  |  |         class P1(Protocol): | 
					
						
							|  |  |  |             def meth1(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P2(P1, Protocol): | 
					
						
							|  |  |  |             def meth2(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def meth1(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def meth2(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C1: | 
					
						
							|  |  |  |             def meth1(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C2: | 
					
						
							|  |  |  |             def meth2(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotIsInstance(C1(), P2) | 
					
						
							|  |  |  |         self.assertNotIsInstance(C2(), P2) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(C1, P2) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(C2, P2) | 
					
						
							|  |  |  |         self.assertIsInstance(C(), P2) | 
					
						
							|  |  |  |         self.assertIsSubclass(C, P2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_subprotocols_merging(self): | 
					
						
							|  |  |  |         class P1(Protocol): | 
					
						
							|  |  |  |             def meth1(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class P2(Protocol): | 
					
						
							|  |  |  |             def meth2(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(P1, P2, Protocol): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def meth1(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def meth2(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C1: | 
					
						
							|  |  |  |             def meth1(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C2: | 
					
						
							|  |  |  |             def meth2(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotIsInstance(C1(), P) | 
					
						
							|  |  |  |         self.assertNotIsInstance(C2(), P) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(C1, P) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(C2, P) | 
					
						
							|  |  |  |         self.assertIsInstance(C(), P) | 
					
						
							|  |  |  |         self.assertIsSubclass(C, P) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_protocols_issubclass(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             def x(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PG(Protocol[T]): | 
					
						
							|  |  |  |             def x(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class BadP(Protocol): | 
					
						
							|  |  |  |             def x(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class BadPG(Protocol[T]): | 
					
						
							|  |  |  |             def x(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def x(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsSubclass(C, P) | 
					
						
							|  |  |  |         self.assertIsSubclass(C, PG) | 
					
						
							|  |  |  |         self.assertIsSubclass(BadP, PG) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(C, PG[T]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(C, PG[C]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(C, BadP) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(C, BadPG) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(P, PG[T]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(PG, PG[int]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_protocols_issubclass_non_callable(self): | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PNonCall(Protocol): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(C, PNonCall) | 
					
						
							|  |  |  |         self.assertIsInstance(C(), PNonCall) | 
					
						
							|  |  |  |         PNonCall.register(C) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(C, PNonCall) | 
					
						
							|  |  |  |         self.assertIsInstance(C(), PNonCall) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # check that non-protocol subclasses are not affected | 
					
						
							|  |  |  |         class D(PNonCall): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotIsSubclass(C, D) | 
					
						
							|  |  |  |         self.assertNotIsInstance(C(), D) | 
					
						
							|  |  |  |         D.register(C) | 
					
						
							|  |  |  |         self.assertIsSubclass(C, D) | 
					
						
							|  |  |  |         self.assertIsInstance(C(), D) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(D, PNonCall) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_protocols_isinstance(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             def meth(x): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PG(Protocol[T]): | 
					
						
							|  |  |  |             def meth(x): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class BadP(Protocol): | 
					
						
							|  |  |  |             def meth(x): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class BadPG(Protocol[T]): | 
					
						
							|  |  |  |             def meth(x): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def meth(x): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(C(), P) | 
					
						
							|  |  |  |         self.assertIsInstance(C(), PG) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(C(), PG[T]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(C(), PG[C]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(C(), BadP) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(C(), BadPG) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_protocols_isinstance_py36(self): | 
					
						
							|  |  |  |         class APoint: | 
					
						
							|  |  |  |             def __init__(self, x, y, label): | 
					
						
							|  |  |  |                 self.x = x | 
					
						
							|  |  |  |                 self.y = y | 
					
						
							|  |  |  |                 self.label = label | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class BPoint: | 
					
						
							|  |  |  |             label = 'B' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def __init__(self, x, y): | 
					
						
							|  |  |  |                 self.x = x | 
					
						
							|  |  |  |                 self.y = y | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def __init__(self, attr): | 
					
						
							|  |  |  |                 self.attr = attr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def meth(self, arg): | 
					
						
							|  |  |  |                 return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Bad: pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(APoint(1, 2, 'A'), Point) | 
					
						
							|  |  |  |         self.assertIsInstance(BPoint(1, 2), Point) | 
					
						
							|  |  |  |         self.assertNotIsInstance(MyPoint(), Point) | 
					
						
							|  |  |  |         self.assertIsInstance(BPoint(1, 2), Position) | 
					
						
							|  |  |  |         self.assertIsInstance(Other(), Proto) | 
					
						
							|  |  |  |         self.assertIsInstance(Concrete(), Proto) | 
					
						
							|  |  |  |         self.assertIsInstance(C(42), Proto) | 
					
						
							|  |  |  |         self.assertNotIsInstance(Bad(), Proto) | 
					
						
							|  |  |  |         self.assertNotIsInstance(Bad(), Point) | 
					
						
							|  |  |  |         self.assertNotIsInstance(Bad(), Position) | 
					
						
							|  |  |  |         self.assertNotIsInstance(Bad(), Concrete) | 
					
						
							|  |  |  |         self.assertNotIsInstance(Other(), Concrete) | 
					
						
							|  |  |  |         self.assertIsInstance(NT(1, 2), Position) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_protocols_isinstance_init(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PG(Protocol[T]): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def __init__(self, x): | 
					
						
							|  |  |  |                 self.x = x | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(C(1), P) | 
					
						
							|  |  |  |         self.assertIsInstance(C(1), PG) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-22 18:48:01 +01:00
										 |  |  |     def test_protocol_checks_after_subscript(self): | 
					
						
							|  |  |  |         class P(Protocol[T]): pass | 
					
						
							|  |  |  |         class C(P[T]): pass | 
					
						
							|  |  |  |         class Other1: pass | 
					
						
							|  |  |  |         class Other2: pass | 
					
						
							|  |  |  |         CA = C[Any] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotIsInstance(Other1(), C) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(Other2, C) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D1(C[Any]): pass | 
					
						
							|  |  |  |         class D2(C[Any]): pass | 
					
						
							|  |  |  |         CI = C[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(D1(), C) | 
					
						
							|  |  |  |         self.assertIsSubclass(D2, C) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |     def test_protocols_support_register(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class PM(Protocol): | 
					
						
							|  |  |  |             def meth(self): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D(PM): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         D.register(C) | 
					
						
							|  |  |  |         P.register(C) | 
					
						
							|  |  |  |         self.assertIsInstance(C(), P) | 
					
						
							|  |  |  |         self.assertIsInstance(C(), D) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_none_on_non_callable_doesnt_block_implementation(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class A: | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class B(A): | 
					
						
							|  |  |  |             x = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def __init__(self): | 
					
						
							|  |  |  |                 self.x = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(B(), P) | 
					
						
							|  |  |  |         self.assertIsInstance(C(), P) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_none_on_callable_blocks_implementation(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             def x(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class A: | 
					
						
							|  |  |  |             def x(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class B(A): | 
					
						
							|  |  |  |             x = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def __init__(self): | 
					
						
							|  |  |  |                 self.x = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotIsInstance(B(), P) | 
					
						
							|  |  |  |         self.assertNotIsInstance(C(), P) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_non_protocol_subclasses(self): | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PR(Protocol): | 
					
						
							|  |  |  |             def meth(self): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class NonP(P): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class NonPR(PR): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D: | 
					
						
							|  |  |  |             def meth(self): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotIsInstance(C(), NonP) | 
					
						
							|  |  |  |         self.assertNotIsInstance(D(), NonPR) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(C, NonP) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(D, NonPR) | 
					
						
							|  |  |  |         self.assertIsInstance(NonPR(), PR) | 
					
						
							|  |  |  |         self.assertIsSubclass(NonPR, PR) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_custom_subclasshook(self): | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class OKClass: pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class BadClass: | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(P): | 
					
						
							|  |  |  |             @classmethod | 
					
						
							|  |  |  |             def __subclasshook__(cls, other): | 
					
						
							|  |  |  |                 return other.__name__.startswith("OK") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(OKClass(), C) | 
					
						
							|  |  |  |         self.assertNotIsInstance(BadClass(), C) | 
					
						
							|  |  |  |         self.assertIsSubclass(OKClass, C) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(BadClass, C) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_issubclass_fails_correctly(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(C(), P) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_defining_generic_protocols(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         S = TypeVar('S') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PR(Protocol[T, S]): | 
					
						
							|  |  |  |             def meth(self): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class P(PR[int, T], Protocol[T]): | 
					
						
							|  |  |  |             y = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(C[str](), C) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_defining_generic_protocols_old_style(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         S = TypeVar('S') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PR(Protocol, Generic[T, S]): | 
					
						
							|  |  |  |             def meth(self): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class P(PR[int, str], Protocol): | 
					
						
							|  |  |  |             y = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(PR[int, str], PR) | 
					
						
							|  |  |  |         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: ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class P2(Generic[T], Protocol): | 
					
						
							|  |  |  |             def bar(self, x: T) -> str: ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PSub(P1[str], Protocol): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Test: | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def bar(self, x: str) -> str: | 
					
						
							|  |  |  |                 return x | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(Test(), PSub) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             PR[int, ClassVar] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_init_called(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class P(Protocol[T]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(P[T]): | 
					
						
							|  |  |  |             def __init__(self): | 
					
						
							|  |  |  |                 self.test = 'OK' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(C[int]().test, 'OK') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_protocols_bad_subscripts(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         S = TypeVar('S') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class P(Protocol[T, T]): pass | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class P(Protocol[int]): pass | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class P(Protocol[T], Protocol[S]): pass | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class P(typing.Mapping[T, S], Protocol[T]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_generic_protocols_repr(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         S = TypeVar('S') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class P(Protocol[T, S]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertTrue(repr(P[T, S]).endswith('P[~T, ~S]')) | 
					
						
							|  |  |  |         self.assertTrue(repr(P[int, str]).endswith('P[int, str]')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_generic_protocols_eq(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         S = TypeVar('S') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class P(Protocol[T, S]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(P, P) | 
					
						
							|  |  |  |         self.assertEqual(P[int, T], P[int, T]) | 
					
						
							|  |  |  |         self.assertEqual(P[T, T][Tuple[T, S]][int, str], | 
					
						
							|  |  |  |                          P[Tuple[int, str], Tuple[int, str]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_generic_protocols_special_from_generic(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class P(Protocol[T]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(P.__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(P[int].__parameters__, ()) | 
					
						
							|  |  |  |         self.assertEqual(P[int].__args__, (int,)) | 
					
						
							|  |  |  |         self.assertIs(P[int].__origin__, P) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_generic_protocols_special_from_protocol(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PR(Protocol): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             def meth(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class PG(Protocol[T]): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def meth(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertTrue(P._is_protocol) | 
					
						
							|  |  |  |         self.assertTrue(PR._is_protocol) | 
					
						
							|  |  |  |         self.assertTrue(PG._is_protocol) | 
					
						
							|  |  |  |         self.assertFalse(P._is_runtime_protocol) | 
					
						
							|  |  |  |         self.assertTrue(PR._is_runtime_protocol) | 
					
						
							|  |  |  |         self.assertTrue(PG[int]._is_protocol) | 
					
						
							|  |  |  |         self.assertEqual(typing._get_protocol_attrs(P), {'meth'}) | 
					
						
							|  |  |  |         self.assertEqual(typing._get_protocol_attrs(PR), {'x'}) | 
					
						
							|  |  |  |         self.assertEqual(frozenset(typing._get_protocol_attrs(PG)), | 
					
						
							|  |  |  |                          frozenset({'x', 'meth'})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_runtime_deco_on_nominal(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             @runtime_checkable | 
					
						
							|  |  |  |             class C: pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Proto(Protocol): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             @runtime_checkable | 
					
						
							|  |  |  |             class Concrete(Proto): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_none_treated_correctly(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             x = None  # type: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class B(object): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotIsInstance(B(), P) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D: | 
					
						
							|  |  |  |             x = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(C(), P) | 
					
						
							|  |  |  |         self.assertIsInstance(D(), P) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CI: | 
					
						
							|  |  |  |             def __init__(self): | 
					
						
							|  |  |  |                 self.x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class DI: | 
					
						
							|  |  |  |             def __init__(self): | 
					
						
							|  |  |  |                 self.x = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(C(), P) | 
					
						
							|  |  |  |         self.assertIsInstance(D(), P) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_protocols_in_unions(self): | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             x = None  # type: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Alias = typing.Union[typing.Iterable, P] | 
					
						
							|  |  |  |         Alias2 = typing.Union[P, typing.Iterable] | 
					
						
							|  |  |  |         self.assertEqual(Alias, Alias2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_protocols_pickleable(self): | 
					
						
							|  |  |  |         global P, CP  # pickle wants to reference the class by name | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol[T]): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CP(P[int]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         c = CP() | 
					
						
							|  |  |  |         c.foo = 42 | 
					
						
							|  |  |  |         c.bar = 'abc' | 
					
						
							|  |  |  |         for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |             z = pickle.dumps(c, proto) | 
					
						
							|  |  |  |             x = pickle.loads(z) | 
					
						
							|  |  |  |             self.assertEqual(x.foo, 42) | 
					
						
							|  |  |  |             self.assertEqual(x.bar, 'abc') | 
					
						
							|  |  |  |             self.assertEqual(x.x, 1) | 
					
						
							|  |  |  |             self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) | 
					
						
							|  |  |  |             s = pickle.dumps(P) | 
					
						
							|  |  |  |             D = pickle.loads(s) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             class E: | 
					
						
							|  |  |  |                 x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.assertIsInstance(E(), D) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_supports_int(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(int, typing.SupportsInt) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(str, typing.SupportsInt) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_supports_float(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(float, typing.SupportsFloat) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(str, typing.SupportsFloat) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_supports_complex(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Note: complex itself doesn't have __complex__. | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def __complex__(self): | 
					
						
							|  |  |  |                 return 0j | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(C, typing.SupportsComplex) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(str, typing.SupportsComplex) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_supports_bytes(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Note: bytes itself doesn't have __bytes__. | 
					
						
							|  |  |  |         class B: | 
					
						
							|  |  |  |             def __bytes__(self): | 
					
						
							|  |  |  |                 return b'' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(B, typing.SupportsBytes) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(str, typing.SupportsBytes) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_supports_abs(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(float, typing.SupportsAbs) | 
					
						
							|  |  |  |         self.assertIsSubclass(int, typing.SupportsAbs) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(str, typing.SupportsAbs) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_supports_round(self): | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |         issubclass(float, typing.SupportsRound) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(float, typing.SupportsRound) | 
					
						
							|  |  |  |         self.assertIsSubclass(int, typing.SupportsRound) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(str, typing.SupportsRound) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_reversible(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(list, typing.Reversible) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(int, typing.Reversible) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-22 07:23:01 -07:00
										 |  |  |     def test_supports_index(self): | 
					
						
							|  |  |  |         self.assertIsSubclass(int, typing.SupportsIndex) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(str, typing.SupportsIndex) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |     def test_bundled_protocol_instance_works(self): | 
					
						
							|  |  |  |         self.assertIsInstance(0, typing.SupportsAbs) | 
					
						
							| 
									
										
										
										
											2016-11-19 10:32:41 -08:00
										 |  |  |         class C1(typing.SupportsInt): | 
					
						
							|  |  |  |             def __int__(self) -> int: | 
					
						
							|  |  |  |                 return 42 | 
					
						
							|  |  |  |         class C2(C1): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         c = C2() | 
					
						
							|  |  |  |         self.assertIsInstance(c, C1) | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |     def test_collections_protocols_allowed(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class Custom(collections.abc.Iterable, Protocol): | 
					
						
							|  |  |  |             def close(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class A: pass | 
					
						
							|  |  |  |         class B: | 
					
						
							|  |  |  |             def __iter__(self): | 
					
						
							|  |  |  |                 return [] | 
					
						
							|  |  |  |             def close(self): | 
					
						
							|  |  |  |                 return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsSubclass(B, Custom) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(A, Custom) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-12 11:13:51 +01:00
										 |  |  |     def test_builtin_protocol_whitelist(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class CustomProtocol(TestCase, Protocol): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CustomContextManager(typing.ContextManager, Protocol): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class GenericTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         X = SimpleMapping[str, Any] | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(X.__parameters__, ()) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |             X[str] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             X[str, str] | 
					
						
							|  |  |  |         Y = SimpleMapping[XK, str] | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(Y.__parameters__, (XK,)) | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |         Y[str] | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |             Y[str, str] | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         SM1 = SimpleMapping[str, int] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(SM1, SimpleMapping) | 
					
						
							|  |  |  |         self.assertIsInstance(SM1(), SimpleMapping) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |     def test_generic_errors(self): | 
					
						
							| 
									
										
										
										
											2016-10-29 16:05:26 -07:00
										 |  |  |         T = TypeVar('T') | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         S = TypeVar('S') | 
					
						
							| 
									
										
										
										
											2016-10-29 16:05:26 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Generic[T]() | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Generic[T][T] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Generic[T][S] | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(Generic[T], Generic[T]): ... | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance([], List[int]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(list, List[int]) | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class NewGeneric(Generic): ... | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class MyGeneric(Generic[T], Generic[S]): ... | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class MyGeneric(List[T], Generic[S]): ... | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |     def test_init(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         S = TypeVar('S') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Generic[T, T] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Generic[T, S, T] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-05 03:43:58 +01:00
										 |  |  |     def test_init_subclass(self): | 
					
						
							|  |  |  |         class X(typing.Generic[T]): | 
					
						
							|  |  |  |             def __init_subclass__(cls, **kwargs): | 
					
						
							|  |  |  |                 super().__init_subclass__(**kwargs) | 
					
						
							|  |  |  |                 cls.attr = 42 | 
					
						
							|  |  |  |         class Y(X): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         self.assertEqual(Y.attr, 42) | 
					
						
							|  |  |  |         with self.assertRaises(AttributeError): | 
					
						
							|  |  |  |             X.attr | 
					
						
							|  |  |  |         X.attr = 1 | 
					
						
							|  |  |  |         Y.attr = 2 | 
					
						
							|  |  |  |         class Z(Y): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         class W(X[int]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         self.assertEqual(Y.attr, 2) | 
					
						
							|  |  |  |         self.assertEqual(Z.attr, 42) | 
					
						
							|  |  |  |         self.assertEqual(W.attr, 42) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(SimpleMapping), | 
					
						
							| 
									
										
										
										
											2018-07-21 22:46:26 +03:00
										 |  |  |                          f"<class '{__name__}.SimpleMapping'>") | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         self.assertEqual(repr(MySimpleMapping), | 
					
						
							| 
									
										
										
										
											2018-07-21 22:46:26 +03:00
										 |  |  |                          f"<class '{__name__}.MySimpleMapping'>") | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_chain_repr(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         S = TypeVar('S') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(Generic[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         X = C[Tuple[S, T]] | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(X, C[Tuple[S, T]]) | 
					
						
							|  |  |  |         self.assertNotEqual(X, C[Tuple[T, S]]) | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Y = X[T, int] | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(Y, X[T, int]) | 
					
						
							|  |  |  |         self.assertNotEqual(Y, X[S, int]) | 
					
						
							|  |  |  |         self.assertNotEqual(Y, X[T, str]) | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Z = Y[str] | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(Z, Y[str]) | 
					
						
							|  |  |  |         self.assertNotEqual(Z, Y[int]) | 
					
						
							|  |  |  |         self.assertNotEqual(Z, Y[T]) | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertTrue(str(Z).endswith( | 
					
						
							| 
									
										
										
										
											2016-10-21 14:27:58 -07:00
										 |  |  |             '.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]]') | 
					
						
							| 
									
										
										
										
											2017-01-22 17:47:20 -08:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             repr(List[Tuple[T, T]][List[int]]), | 
					
						
							|  |  |  |             'typing.List[typing.Tuple[typing.List[int], typing.List[int]]]' | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2016-10-21 14:27:58 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_new_repr_bare(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         self.assertEqual(repr(Generic[T]), 'typing.Generic[~T]') | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |         self.assertEqual(repr(typing.Protocol[T]), 'typing.Protocol[~T]') | 
					
						
							| 
									
										
										
										
											2016-10-21 14:27:58 -07:00
										 |  |  |         class C(typing.Dict[Any, Any]): ... | 
					
						
							|  |  |  |         # this line should just work | 
					
						
							|  |  |  |         repr(C.__mro__) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  |     def test_dict(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  |         class B(Generic[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  |         b = B() | 
					
						
							|  |  |  |         b.foo = 42 | 
					
						
							|  |  |  |         self.assertEqual(b.__dict__, {'foo': 42}) | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  |         class C(B[int]): | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  |         c = C() | 
					
						
							|  |  |  |         c.bar = 'abc' | 
					
						
							|  |  |  |         self.assertEqual(c.__dict__, {'bar': 'abc'}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-24 04:03:28 +01:00
										 |  |  |     def test_subscripted_generics_as_proxies(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         class C(Generic[T]): | 
					
						
							|  |  |  |             x = 'def' | 
					
						
							|  |  |  |         self.assertEqual(C[int].x, 'def') | 
					
						
							|  |  |  |         self.assertEqual(C[C[int]].x, 'def') | 
					
						
							|  |  |  |         C[C[int]].x = 'changed' | 
					
						
							|  |  |  |         self.assertEqual(C.x, 'changed') | 
					
						
							|  |  |  |         self.assertEqual(C[str].x, 'changed') | 
					
						
							|  |  |  |         C[List[str]].z = 'new' | 
					
						
							|  |  |  |         self.assertEqual(C.z, 'new') | 
					
						
							|  |  |  |         self.assertEqual(C[Tuple[int]].z, 'new') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(C().x, 'changed') | 
					
						
							|  |  |  |         self.assertEqual(C[Tuple[str]]().z, 'new') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D(C[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         self.assertEqual(D[int].x, 'changed') | 
					
						
							|  |  |  |         self.assertEqual(D.z, 'new') | 
					
						
							|  |  |  |         D.z = 'from derived z' | 
					
						
							|  |  |  |         D[int].x = 'from derived x' | 
					
						
							|  |  |  |         self.assertEqual(C.x, 'changed') | 
					
						
							|  |  |  |         self.assertEqual(C[int].z, 'new') | 
					
						
							|  |  |  |         self.assertEqual(D.x, 'from derived x') | 
					
						
							|  |  |  |         self.assertEqual(D[str].z, 'from derived z') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-24 18:28:26 +01:00
										 |  |  |     def test_abc_registry_kept(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         class C(collections.abc.Mapping, Generic[T]): ... | 
					
						
							| 
									
										
										
										
											2017-02-24 18:28:26 +01:00
										 |  |  |         C.register(int) | 
					
						
							|  |  |  |         self.assertIsInstance(1, C) | 
					
						
							|  |  |  |         C[int] | 
					
						
							|  |  |  |         self.assertIsInstance(1, C) | 
					
						
							| 
									
										
										
										
											2018-02-18 12:41:58 +00:00
										 |  |  |         C._abc_registry_clear() | 
					
						
							|  |  |  |         C._abc_caches_clear()  # To keep refleak hunting mode clean | 
					
						
							| 
									
										
										
										
											2017-02-24 18:28:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |     def test_false_subclasses(self): | 
					
						
							|  |  |  |         class MyMapping(MutableMapping[str, str]): pass | 
					
						
							|  |  |  |         self.assertNotIsInstance({}, MyMapping) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(dict, MyMapping) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-03 08:40:50 -07:00
										 |  |  |     def test_abc_bases(self): | 
					
						
							|  |  |  |         class MM(MutableMapping[str, str]): | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |             def __getitem__(self, k): | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  |             def __setitem__(self, k, v): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             def __delitem__(self, k): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             def __iter__(self): | 
					
						
							|  |  |  |                 return iter(()) | 
					
						
							|  |  |  |             def __len__(self): | 
					
						
							|  |  |  |                 return 0 | 
					
						
							| 
									
										
										
										
											2016-10-03 08:40:50 -07:00
										 |  |  |         # this should just work | 
					
						
							|  |  |  |         MM().update() | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         self.assertIsInstance(MM(), collections.abc.MutableMapping) | 
					
						
							| 
									
										
										
										
											2016-10-03 08:40:50 -07:00
										 |  |  |         self.assertIsInstance(MM(), MutableMapping) | 
					
						
							|  |  |  |         self.assertNotIsInstance(MM(), List) | 
					
						
							|  |  |  |         self.assertNotIsInstance({}, MM) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_multiple_bases(self): | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         class MM1(MutableMapping[str, str], collections.abc.MutableMapping): | 
					
						
							| 
									
										
										
										
											2016-10-03 08:40:50 -07:00
										 |  |  |             pass | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         class MM2(collections.abc.MutableMapping, MutableMapping[str, str]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         self.assertEqual(MM2.__bases__, (collections.abc.MutableMapping, Generic)) | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-21 14:27:58 -07:00
										 |  |  |     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__ | 
					
						
							| 
									
										
										
										
											2017-01-22 17:47:20 -08:00
										 |  |  |                 return all( | 
					
						
							|  |  |  |                     isinstance(k, KT) and isinstance(v, VT) | 
					
						
							|  |  |  |                     for k, v in obj.items() | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2016-10-21 14:27:58 -07:00
										 |  |  |         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): | 
					
						
							| 
									
										
										
										
											2017-01-22 17:43:53 -08:00
										 |  |  |             naive_generic_check([1, 2, 3], Node[int]) | 
					
						
							| 
									
										
										
										
											2016-10-21 14:27:58 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         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,)) | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         self.assertEqual(C.__bases__, (list, Generic)) | 
					
						
							|  |  |  |         self.assertEqual(D.__bases__, (C, list, Generic)) | 
					
						
							| 
									
										
										
										
											2016-10-21 14:27:58 -07:00
										 |  |  |         self.assertEqual(C.__orig_bases__, (List[T][U][V],)) | 
					
						
							|  |  |  |         self.assertEqual(D.__orig_bases__, (C, List[T][U][V])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-17 20:43:28 -08:00
										 |  |  |     def test_subscript_meta(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         class Meta(type): ... | 
					
						
							|  |  |  |         self.assertEqual(Type[Meta], Type[Meta]) | 
					
						
							|  |  |  |         self.assertEqual(Union[T, int][Meta], Union[Meta, int]) | 
					
						
							|  |  |  |         self.assertEqual(Callable[..., Meta].__args__, (Ellipsis, Meta)) | 
					
						
							| 
									
										
										
										
											2017-01-17 20:43:28 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     def test_generic_hashes(self): | 
					
						
							|  |  |  |         class A(Generic[T]): | 
					
						
							|  |  |  |             ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class B(Generic[T]): | 
					
						
							|  |  |  |             class A(Generic[T]): | 
					
						
							|  |  |  |                 ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(A, A) | 
					
						
							|  |  |  |         self.assertEqual(mod_generics_cache.A[str], mod_generics_cache.A[str]) | 
					
						
							|  |  |  |         self.assertEqual(B.A, B.A) | 
					
						
							|  |  |  |         self.assertEqual(mod_generics_cache.B.A[B.A[str]], | 
					
						
							|  |  |  |                          mod_generics_cache.B.A[B.A[str]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotEqual(A, B.A) | 
					
						
							|  |  |  |         self.assertNotEqual(A, mod_generics_cache.A) | 
					
						
							|  |  |  |         self.assertNotEqual(A, mod_generics_cache.B.A) | 
					
						
							|  |  |  |         self.assertNotEqual(B.A, mod_generics_cache.A) | 
					
						
							|  |  |  |         self.assertNotEqual(B.A, mod_generics_cache.B.A) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotEqual(A[str], B.A[str]) | 
					
						
							|  |  |  |         self.assertNotEqual(A[List[Any]], B.A[List[Any]]) | 
					
						
							|  |  |  |         self.assertNotEqual(A[str], mod_generics_cache.A[str]) | 
					
						
							|  |  |  |         self.assertNotEqual(A[str], mod_generics_cache.B.A[str]) | 
					
						
							|  |  |  |         self.assertNotEqual(B.A[int], mod_generics_cache.A[int]) | 
					
						
							|  |  |  |         self.assertNotEqual(B.A[List[Any]], mod_generics_cache.B.A[List[Any]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotEqual(Tuple[A[str]], Tuple[B.A[str]]) | 
					
						
							|  |  |  |         self.assertNotEqual(Tuple[A[List[Any]]], Tuple[B.A[List[Any]]]) | 
					
						
							|  |  |  |         self.assertNotEqual(Union[str, A[str]], Union[str, mod_generics_cache.A[str]]) | 
					
						
							|  |  |  |         self.assertNotEqual(Union[A[str], A[str]], | 
					
						
							|  |  |  |                             Union[A[str], mod_generics_cache.A[str]]) | 
					
						
							|  |  |  |         self.assertNotEqual(typing.FrozenSet[A[str]], | 
					
						
							|  |  |  |                             typing.FrozenSet[mod_generics_cache.B.A[str]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if sys.version_info[:2] > (3, 2): | 
					
						
							|  |  |  |             self.assertTrue(repr(Tuple[A[str]]).endswith('<locals>.A[str]]')) | 
					
						
							|  |  |  |             self.assertTrue(repr(Tuple[B.A[str]]).endswith('<locals>.B.A[str]]')) | 
					
						
							|  |  |  |             self.assertTrue(repr(Tuple[mod_generics_cache.A[str]]) | 
					
						
							|  |  |  |                             .endswith('mod_generics_cache.A[str]]')) | 
					
						
							|  |  |  |             self.assertTrue(repr(Tuple[mod_generics_cache.B.A[str]]) | 
					
						
							|  |  |  |                             .endswith('mod_generics_cache.B.A[str]]')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |     def test_extended_generic_rules_eq(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         U = TypeVar('U') | 
					
						
							|  |  |  |         self.assertEqual(Tuple[T, T][int], Tuple[int, int]) | 
					
						
							|  |  |  |         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]) | 
					
						
							|  |  |  |         class Base: ... | 
					
						
							|  |  |  |         class Derived(Base): ... | 
					
						
							| 
									
										
										
										
											2018-05-18 16:00:38 -07:00
										 |  |  |         self.assertEqual(Union[T, Base][Union[Base, Derived]], Union[Base, Derived]) | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Union[T, int][1] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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') | 
					
						
							|  |  |  |         self.assertEqual(repr(Union[Tuple, Callable]).replace('typing.', ''), | 
					
						
							|  |  |  |                          'Union[Tuple, Callable]') | 
					
						
							|  |  |  |         self.assertEqual(repr(Union[Tuple, Tuple[int]]).replace('typing.', ''), | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |                          'Union[Tuple, Tuple[int]]') | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |         self.assertEqual(repr(Callable[..., Optional[T]][int]).replace('typing.', ''), | 
					
						
							|  |  |  |                          'Callable[..., Union[int, NoneType]]') | 
					
						
							|  |  |  |         self.assertEqual(repr(Callable[[], List[T]][int]).replace('typing.', ''), | 
					
						
							|  |  |  |                          'Callable[[], List[int]]') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-09 13:18:59 -08:00
										 |  |  |     def test_generic_forward_ref(self): | 
					
						
							|  |  |  |         def foobar(x: List[List['CC']]): ... | 
					
						
							|  |  |  |         class CC: ... | 
					
						
							| 
									
										
										
										
											2017-01-22 17:43:53 -08:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(foobar, globals(), locals()), | 
					
						
							|  |  |  |             {'x': List[List[CC]]} | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |         T = TypeVar('T') | 
					
						
							| 
									
										
										
										
											2016-11-19 10:32:41 -08:00
										 |  |  |         AT = Tuple[T, ...] | 
					
						
							|  |  |  |         def barfoo(x: AT): ... | 
					
						
							|  |  |  |         self.assertIs(get_type_hints(barfoo, globals(), locals())['x'], AT) | 
					
						
							|  |  |  |         CT = Callable[..., List[T]] | 
					
						
							|  |  |  |         def barfoo2(x: CT): ... | 
					
						
							|  |  |  |         self.assertIs(get_type_hints(barfoo2, globals(), locals())['x'], CT) | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_extended_generic_rules_subclassing(self): | 
					
						
							|  |  |  |         class T1(Tuple[T, KT]): ... | 
					
						
							|  |  |  |         class T2(Tuple[T, ...]): ... | 
					
						
							|  |  |  |         class C1(Callable[[T], T]): ... | 
					
						
							|  |  |  |         class C2(Callable[..., int]): | 
					
						
							|  |  |  |             def __call__(self): | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(T1.__parameters__, (T, KT)) | 
					
						
							|  |  |  |         self.assertEqual(T1[int, str].__args__, (int, str)) | 
					
						
							|  |  |  |         self.assertEqual(T1[int, T].__origin__, T1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(T2.__parameters__, (T,)) | 
					
						
							| 
									
										
										
										
											2020-04-07 09:50:06 -07:00
										 |  |  |         # These don't work because of tuple.__class_item__ | 
					
						
							|  |  |  |         ## with self.assertRaises(TypeError): | 
					
						
							|  |  |  |         ##     T1[int] | 
					
						
							|  |  |  |         ## with self.assertRaises(TypeError): | 
					
						
							|  |  |  |         ##     T2[int, str] | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(repr(C1[int]).split('.')[-1], 'C1[int]') | 
					
						
							|  |  |  |         self.assertEqual(C2.__parameters__, ()) | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         self.assertIsInstance(C2(), collections.abc.Callable) | 
					
						
							|  |  |  |         self.assertIsSubclass(C2, collections.abc.Callable) | 
					
						
							|  |  |  |         self.assertIsSubclass(C1, collections.abc.Callable) | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |         self.assertIsInstance(T1(), tuple) | 
					
						
							|  |  |  |         self.assertIsSubclass(T2, tuple) | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Tuple[int, ...], typing.Sequence) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Tuple[int, ...], typing.Iterable) | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_fail_with_bare_union(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             List[Union] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Tuple[Optional] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             ClassVar[ClassVar] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             List[ClassVar[int]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_fail_with_bare_generic(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             List[Generic] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Tuple[Generic[T]] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |             List[typing.Protocol] | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_type_erasure_special(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							| 
									
										
										
										
											2016-11-19 10:32:41 -08:00
										 |  |  |         # this is the only test that checks type caching | 
					
						
							|  |  |  |         self.clear_caches() | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |         class MyTup(Tuple[T, T]): ... | 
					
						
							|  |  |  |         self.assertIs(MyTup[int]().__class__, MyTup) | 
					
						
							| 
									
										
										
										
											2020-04-07 09:50:06 -07:00
										 |  |  |         self.assertEqual(MyTup[int]().__orig_class__, MyTup[int]) | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |         class MyCall(Callable[..., T]): | 
					
						
							|  |  |  |             def __call__(self): return None | 
					
						
							|  |  |  |         self.assertIs(MyCall[T]().__class__, MyCall) | 
					
						
							| 
									
										
										
										
											2020-04-07 09:50:06 -07:00
										 |  |  |         self.assertEqual(MyCall[T]().__orig_class__, MyCall[T]) | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |         class MyDict(typing.Dict[T, T]): ... | 
					
						
							|  |  |  |         self.assertIs(MyDict[int]().__class__, MyDict) | 
					
						
							| 
									
										
										
										
											2020-04-07 09:50:06 -07:00
										 |  |  |         self.assertEqual(MyDict[int]().__orig_class__, MyDict[int]) | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |         class MyDef(typing.DefaultDict[str, T]): ... | 
					
						
							|  |  |  |         self.assertIs(MyDef[int]().__class__, MyDef) | 
					
						
							| 
									
										
										
										
											2020-04-07 09:50:06 -07:00
										 |  |  |         self.assertEqual(MyDef[int]().__orig_class__, MyDef[int]) | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         # ChainMap was added in 3.3 | 
					
						
							|  |  |  |         if sys.version_info >= (3, 3): | 
					
						
							|  |  |  |             class MyChain(typing.ChainMap[str, T]): ... | 
					
						
							|  |  |  |             self.assertIs(MyChain[int]().__class__, MyChain) | 
					
						
							| 
									
										
										
										
											2020-04-07 09:50:06 -07:00
										 |  |  |             self.assertEqual(MyChain[int]().__orig_class__, MyChain[int]) | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_all_repr_eq_any(self): | 
					
						
							|  |  |  |         objs = (getattr(typing, el) for el in typing.__all__) | 
					
						
							|  |  |  |         for obj in objs: | 
					
						
							|  |  |  |             self.assertNotEqual(repr(obj), '') | 
					
						
							|  |  |  |             self.assertEqual(obj, obj) | 
					
						
							|  |  |  |             if getattr(obj, '__parameters__', None) and len(obj.__parameters__) == 1: | 
					
						
							|  |  |  |                 self.assertEqual(obj[Any].__args__, (Any,)) | 
					
						
							|  |  |  |             if isinstance(obj, type): | 
					
						
							|  |  |  |                 for base in obj.__mro__: | 
					
						
							|  |  |  |                     self.assertNotEqual(repr(base), '') | 
					
						
							|  |  |  |                     self.assertEqual(base, base) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  |     def test_pickle(self): | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |         global C  # pickle wants to reference the class by name | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  |         T = TypeVar('T') | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  |         class B(Generic[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  |         class C(B[int]): | 
					
						
							|  |  |  |             pass | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  |         c = C() | 
					
						
							|  |  |  |         c.foo = 42 | 
					
						
							|  |  |  |         c.bar = 'abc' | 
					
						
							| 
									
										
										
										
											2015-11-20 18:33:02 +02:00
										 |  |  |         for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |             z = pickle.dumps(c, proto) | 
					
						
							|  |  |  |             x = pickle.loads(z) | 
					
						
							|  |  |  |             self.assertEqual(x.foo, 42) | 
					
						
							|  |  |  |             self.assertEqual(x.bar, 'abc') | 
					
						
							|  |  |  |             self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) | 
					
						
							| 
									
										
										
										
											2018-03-26 23:01:12 +01:00
										 |  |  |         samples = [Any, Union, Tuple, Callable, ClassVar, | 
					
						
							| 
									
										
										
										
											2018-04-05 01:25:15 +01:00
										 |  |  |                    Union[int, str], ClassVar[List], Tuple[int, ...], Callable[[str], bytes], | 
					
						
							|  |  |  |                    typing.DefaultDict, typing.FrozenSet[int]] | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         for s in samples: | 
					
						
							| 
									
										
										
										
											2016-10-29 12:44:29 -07:00
										 |  |  |             for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |                 z = pickle.dumps(s, proto) | 
					
						
							|  |  |  |                 x = pickle.loads(z) | 
					
						
							|  |  |  |                 self.assertEqual(s, x) | 
					
						
							| 
									
										
										
										
											2018-03-26 23:01:12 +01:00
										 |  |  |         more_samples = [List, typing.Iterable, typing.Type, List[int], | 
					
						
							| 
									
										
										
										
											2018-04-05 01:25:15 +01:00
										 |  |  |                         typing.Type[typing.Mapping], typing.AbstractSet[Tuple[int, str]]] | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         for s in more_samples: | 
					
						
							|  |  |  |             for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |                 z = pickle.dumps(s, proto) | 
					
						
							|  |  |  |                 x = pickle.loads(z) | 
					
						
							| 
									
										
										
										
											2018-03-26 23:01:12 +01:00
										 |  |  |                 self.assertEqual(s, x) | 
					
						
							| 
									
										
										
										
											2016-10-29 12:44:29 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_copy_and_deepcopy(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         class Node(Generic[T]): ... | 
					
						
							|  |  |  |         things = [Union[T, int], Tuple[T, int], Callable[..., T], Callable[[int], int], | 
					
						
							|  |  |  |                   Tuple[Any, Any], Node[T], Node[int], Node[Any], typing.Iterable[T], | 
					
						
							|  |  |  |                   typing.Iterable[Any], typing.Iterable[int], typing.Dict[int, str], | 
					
						
							|  |  |  |                   typing.Dict[T, Any], ClassVar[int], ClassVar[List[T]], Tuple['T', 'T'], | 
					
						
							|  |  |  |                   Union['T', int], List['T'], typing.Mapping['T', int]] | 
					
						
							|  |  |  |         for t in things + [Any]: | 
					
						
							|  |  |  |             self.assertEqual(t, copy(t)) | 
					
						
							| 
									
										
										
										
											2018-03-26 23:01:12 +01:00
										 |  |  |             self.assertEqual(t, deepcopy(t)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_immutability_by_copy_and_pickle(self): | 
					
						
							|  |  |  |         # Special forms like Union, Any, etc., generic aliases to containers like List, | 
					
						
							|  |  |  |         # Mapping, etc., and type variabcles are considered immutable by copy and pickle. | 
					
						
							|  |  |  |         global TP, TPB, TPV  # for pickle | 
					
						
							|  |  |  |         TP = TypeVar('TP') | 
					
						
							|  |  |  |         TPB = TypeVar('TPB', bound=int) | 
					
						
							|  |  |  |         TPV = TypeVar('TPV', bytes, str) | 
					
						
							|  |  |  |         for X in [TP, TPB, TPV, List, typing.Mapping, ClassVar, typing.Iterable, | 
					
						
							|  |  |  |                   Union, Any, Tuple, Callable]: | 
					
						
							|  |  |  |             self.assertIs(copy(X), X) | 
					
						
							|  |  |  |             self.assertIs(deepcopy(X), X) | 
					
						
							|  |  |  |             self.assertIs(pickle.loads(pickle.dumps(X)), X) | 
					
						
							|  |  |  |         # Check that local type variables are copyable. | 
					
						
							|  |  |  |         TL = TypeVar('TL') | 
					
						
							|  |  |  |         TLB = TypeVar('TLB', bound=int) | 
					
						
							|  |  |  |         TLV = TypeVar('TLV', bytes, str) | 
					
						
							|  |  |  |         for X in [TL, TLB, TLV]: | 
					
						
							|  |  |  |             self.assertIs(copy(X), X) | 
					
						
							|  |  |  |             self.assertIs(deepcopy(X), X) | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-05 03:43:58 +01:00
										 |  |  |     def test_copy_generic_instances(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         class C(Generic[T]): | 
					
						
							|  |  |  |             def __init__(self, attr: T) -> None: | 
					
						
							|  |  |  |                 self.attr = attr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         c = C(42) | 
					
						
							|  |  |  |         self.assertEqual(copy(c).attr, 42) | 
					
						
							|  |  |  |         self.assertEqual(deepcopy(c).attr, 42) | 
					
						
							|  |  |  |         self.assertIsNot(copy(c), c) | 
					
						
							|  |  |  |         self.assertIsNot(deepcopy(c), c) | 
					
						
							|  |  |  |         c.attr = 1 | 
					
						
							|  |  |  |         self.assertEqual(copy(c).attr, 1) | 
					
						
							|  |  |  |         self.assertEqual(deepcopy(c).attr, 1) | 
					
						
							|  |  |  |         ci = C[int](42) | 
					
						
							|  |  |  |         self.assertEqual(copy(ci).attr, 42) | 
					
						
							|  |  |  |         self.assertEqual(deepcopy(ci).attr, 42) | 
					
						
							|  |  |  |         self.assertIsNot(copy(ci), ci) | 
					
						
							|  |  |  |         self.assertIsNot(deepcopy(ci), ci) | 
					
						
							|  |  |  |         ci.attr = 1 | 
					
						
							|  |  |  |         self.assertEqual(copy(ci).attr, 1) | 
					
						
							|  |  |  |         self.assertEqual(deepcopy(ci).attr, 1) | 
					
						
							|  |  |  |         self.assertEqual(ci.__orig_class__, C[int]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-17 20:43:28 -08:00
										 |  |  |     def test_weakref_all(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         things = [Any, Union[T, int], Callable[..., T], Tuple[Any, Any], | 
					
						
							|  |  |  |                   Optional[List[int]], typing.Mapping[int, str], | 
					
						
							|  |  |  |                   typing.re.Match[bytes], typing.Iterable['whatever']] | 
					
						
							|  |  |  |         for t in things: | 
					
						
							|  |  |  |             self.assertEqual(weakref.ref(t)(), t) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-29 09:46:21 -08:00
										 |  |  |     def test_parameterized_slots(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         class C(Generic[T]): | 
					
						
							|  |  |  |             __slots__ = ('potato',) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         c = C() | 
					
						
							|  |  |  |         c_int = C[int]() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         c.potato = 0 | 
					
						
							|  |  |  |         c_int.potato = 0 | 
					
						
							|  |  |  |         with self.assertRaises(AttributeError): | 
					
						
							|  |  |  |             c.tomato = 0 | 
					
						
							|  |  |  |         with self.assertRaises(AttributeError): | 
					
						
							|  |  |  |             c_int.tomato = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(x: C['C']): ... | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(foo, globals(), locals())['x'], C[C]) | 
					
						
							|  |  |  |         self.assertEqual(copy(C[int]), deepcopy(C[int])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_parameterized_slots_dict(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         class D(Generic[T]): | 
					
						
							|  |  |  |             __slots__ = {'banana': 42} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         d = D() | 
					
						
							|  |  |  |         d_int = D[int]() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         d.banana = 'yes' | 
					
						
							|  |  |  |         d_int.banana = 'yes' | 
					
						
							|  |  |  |         with self.assertRaises(AttributeError): | 
					
						
							|  |  |  |             d.foobar = 'no' | 
					
						
							|  |  |  |         with self.assertRaises(AttributeError): | 
					
						
							|  |  |  |             d_int.foobar = 'no' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_errors(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             B = SimpleMapping[XK, Any] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             class C(Generic[B]): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr_2(self): | 
					
						
							|  |  |  |         class C(Generic[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(C.__module__, __name__) | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         self.assertEqual(C.__qualname__, | 
					
						
							|  |  |  |                          'GenericTests.test_repr_2.<locals>.C') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         X = C[int] | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(X.__module__, __name__) | 
					
						
							| 
									
										
										
										
											2016-10-21 14:27:58 -07:00
										 |  |  |         self.assertEqual(repr(X).split('.')[-1], 'C[int]') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class Y(C[int]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(Y.__module__, __name__) | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         self.assertEqual(Y.__qualname__, | 
					
						
							|  |  |  |                          'GenericTests.test_repr_2.<locals>.Y') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_eq_1(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(Generic, Generic) | 
					
						
							|  |  |  |         self.assertEqual(Generic[T], Generic[T]) | 
					
						
							|  |  |  |         self.assertNotEqual(Generic[KT], Generic[VT]) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_eq_2(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class A(Generic[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class B(Generic[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(A, A) | 
					
						
							|  |  |  |         self.assertNotEqual(A, B) | 
					
						
							|  |  |  |         self.assertEqual(A[T], A[T]) | 
					
						
							|  |  |  |         self.assertNotEqual(A[T], B[T]) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_multiple_inheritance(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class A(Generic[T, VT]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class B(Generic[KT, T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |         class C(A[T, VT], Generic[VT, T, KT], B[KT, T]): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(C.__parameters__, (VT, T, KT)) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |     def test_multiple_inheritance_special(self): | 
					
						
							|  |  |  |         S = TypeVar('S') | 
					
						
							|  |  |  |         class B(Generic[S]): ... | 
					
						
							|  |  |  |         class C(List[int], B): ... | 
					
						
							|  |  |  |         self.assertEqual(C.__mro__, (C, list, B, Generic, object)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 17:00:15 +01:00
										 |  |  |     def test_init_subclass_super_called(self): | 
					
						
							|  |  |  |         class FinalException(Exception): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Final: | 
					
						
							|  |  |  |             def __init_subclass__(cls, **kwargs) -> None: | 
					
						
							|  |  |  |                 for base in cls.__bases__: | 
					
						
							|  |  |  |                     if base is not Final and issubclass(base, Final): | 
					
						
							|  |  |  |                         raise FinalException(base) | 
					
						
							|  |  |  |                 super().__init_subclass__(**kwargs) | 
					
						
							|  |  |  |         class Test(Generic[T], Final): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         with self.assertRaises(FinalException): | 
					
						
							|  |  |  |             class Subclass(Test): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         with self.assertRaises(FinalException): | 
					
						
							|  |  |  |             class Subclass(Test[int]): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_nested(self): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |         G = Generic | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class Visitor(G[T]): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             a = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def set(self, a: T): | 
					
						
							|  |  |  |                 self.a = a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def get(self): | 
					
						
							|  |  |  |                 return self.a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def visit(self) -> T: | 
					
						
							|  |  |  |                 return self.a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         V = Visitor[typing.List[int]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class IntListVisitor(V): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def append(self, x: int): | 
					
						
							|  |  |  |                 self.a.append(x) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         a = IntListVisitor() | 
					
						
							|  |  |  |         a.set([]) | 
					
						
							|  |  |  |         a.append(1) | 
					
						
							|  |  |  |         a.append(42) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(a.get(), [1, 42]) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_type_erasure(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Node(Generic[T]): | 
					
						
							| 
									
										
										
										
											2015-09-04 12:15:54 -07:00
										 |  |  |             def __init__(self, label: T, | 
					
						
							|  |  |  |                          left: 'Node[T]' = None, | 
					
						
							|  |  |  |                          right: 'Node[T]' = None): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |                 self.label = label  # type: T | 
					
						
							|  |  |  |                 self.left = left  # type: Optional[Node[T]] | 
					
						
							|  |  |  |                 self.right = right  # type: Optional[Node[T]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(x: T): | 
					
						
							|  |  |  |             a = Node(x) | 
					
						
							|  |  |  |             b = Node[T](x) | 
					
						
							|  |  |  |             c = Node[Any](x) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |             self.assertIs(type(a), Node) | 
					
						
							|  |  |  |             self.assertIs(type(b), Node) | 
					
						
							|  |  |  |             self.assertIs(type(c), Node) | 
					
						
							|  |  |  |             self.assertEqual(a.label, x) | 
					
						
							|  |  |  |             self.assertEqual(b.label, x) | 
					
						
							|  |  |  |             self.assertEqual(c.label, x) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         foo(42) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |     def test_implicit_any(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(Generic[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D(C): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(D.__parameters__, ()) | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(Exception): | 
					
						
							|  |  |  |             D[int] | 
					
						
							|  |  |  |         with self.assertRaises(Exception): | 
					
						
							|  |  |  |             D[Any] | 
					
						
							|  |  |  |         with self.assertRaises(Exception): | 
					
						
							|  |  |  |             D[T] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 02:23:46 +01:00
										 |  |  |     def test_new_with_args(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class A(Generic[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class B: | 
					
						
							|  |  |  |             def __new__(cls, arg): | 
					
						
							|  |  |  |                 # call object | 
					
						
							|  |  |  |                 obj = super().__new__(cls) | 
					
						
							|  |  |  |                 obj.arg = arg | 
					
						
							|  |  |  |                 return obj | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # mro: C, A, Generic, B, object | 
					
						
							|  |  |  |         class C(A, B): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         c = C('foo') | 
					
						
							|  |  |  |         self.assertEqual(c.arg, 'foo') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_new_with_args2(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class A: | 
					
						
							|  |  |  |             def __init__(self, arg): | 
					
						
							|  |  |  |                 self.from_a = arg | 
					
						
							|  |  |  |                 # call object | 
					
						
							|  |  |  |                 super().__init__() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # mro: C, Generic, A, object | 
					
						
							|  |  |  |         class C(Generic[T], A): | 
					
						
							|  |  |  |             def __init__(self, arg): | 
					
						
							|  |  |  |                 self.from_c = arg | 
					
						
							|  |  |  |                 # call Generic | 
					
						
							|  |  |  |                 super().__init__(arg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         c = C('foo') | 
					
						
							|  |  |  |         self.assertEqual(c.from_a, 'foo') | 
					
						
							|  |  |  |         self.assertEqual(c.from_c, 'foo') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_new_no_args(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class A(Generic[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 23:10:10 -04:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             A('foo') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 02:23:46 +01:00
										 |  |  |         class B: | 
					
						
							|  |  |  |             def __new__(cls): | 
					
						
							|  |  |  |                 # call object | 
					
						
							|  |  |  |                 obj = super().__new__(cls) | 
					
						
							|  |  |  |                 obj.from_b = 'b' | 
					
						
							|  |  |  |                 return obj | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # mro: C, A, Generic, B, object | 
					
						
							|  |  |  |         class C(A, B): | 
					
						
							|  |  |  |             def __init__(self, arg): | 
					
						
							|  |  |  |                 self.arg = arg | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def __new__(cls, arg): | 
					
						
							|  |  |  |                 # call A | 
					
						
							|  |  |  |                 obj = super().__new__(cls) | 
					
						
							|  |  |  |                 obj.from_c = 'c' | 
					
						
							|  |  |  |                 return obj | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         c = C('foo') | 
					
						
							|  |  |  |         self.assertEqual(c.arg, 'foo') | 
					
						
							|  |  |  |         self.assertEqual(c.from_b, 'b') | 
					
						
							|  |  |  |         self.assertEqual(c.from_c, 'c') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-22 17:43:53 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | class ClassVarTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             ClassVar[1] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             ClassVar[int, str] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             ClassVar[int][str] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(ClassVar), 'typing.ClassVar') | 
					
						
							|  |  |  |         cv = ClassVar[int] | 
					
						
							|  |  |  |         self.assertEqual(repr(cv), 'typing.ClassVar[int]') | 
					
						
							|  |  |  |         cv = ClassVar[Employee] | 
					
						
							|  |  |  |         self.assertEqual(repr(cv), 'typing.ClassVar[%s.Employee]' % __name__) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(type(ClassVar)): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(type(ClassVar[int])): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_init(self): | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             ClassVar() | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(ClassVar)() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(ClassVar[Optional[int]])() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_isinstance(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(1, ClassVar[int]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, ClassVar) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:07 +01:00
										 |  |  | class FinalTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         Final[int]  # OK | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Final[1] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Final[int, str] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Final[int][str] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Optional[Final[int]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(Final), 'typing.Final') | 
					
						
							|  |  |  |         cv = Final[int] | 
					
						
							|  |  |  |         self.assertEqual(repr(cv), 'typing.Final[int]') | 
					
						
							|  |  |  |         cv = Final[Employee] | 
					
						
							|  |  |  |         self.assertEqual(repr(cv), 'typing.Final[%s.Employee]' % __name__) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(type(Final)): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(type(Final[int])): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_init(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Final() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(Final)() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(Final[Optional[int]])() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_isinstance(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(1, Final[int]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, Final) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_final_unmodified(self): | 
					
						
							|  |  |  |         def func(x): ... | 
					
						
							|  |  |  |         self.assertIs(func, final(func)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class CastTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(cast(int, 42), 42) | 
					
						
							|  |  |  |         self.assertEqual(cast(float, 42), 42) | 
					
						
							|  |  |  |         self.assertIs(type(cast(float, 42)), int) | 
					
						
							|  |  |  |         self.assertEqual(cast(Any, 42), 42) | 
					
						
							|  |  |  |         self.assertEqual(cast(list, 42), 42) | 
					
						
							|  |  |  |         self.assertEqual(cast(Union[str, float], 42), 42) | 
					
						
							|  |  |  |         self.assertEqual(cast(AnyStr, 42), 42) | 
					
						
							|  |  |  |         self.assertEqual(cast(None, 42), 42) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_errors(self): | 
					
						
							|  |  |  |         # Bogus calls are not expected to fail. | 
					
						
							|  |  |  |         cast(42, 42) | 
					
						
							|  |  |  |         cast('hello', 42) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class ForwardRefTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Node(Generic[T]): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def __init__(self, label: T): | 
					
						
							|  |  |  |                 self.label = label | 
					
						
							|  |  |  |                 self.left = self.right = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def add_both(self, | 
					
						
							|  |  |  |                          left: 'Optional[Node[T]]', | 
					
						
							|  |  |  |                          right: 'Node[T]' = None, | 
					
						
							|  |  |  |                          stuff: int = None, | 
					
						
							|  |  |  |                          blah=None): | 
					
						
							|  |  |  |                 self.left = left | 
					
						
							|  |  |  |                 self.right = right | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def add_left(self, node: Optional['Node[T]']): | 
					
						
							|  |  |  |                 self.add_both(node, None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def add_right(self, node: 'Node[T]' = None): | 
					
						
							|  |  |  |                 self.add_both(None, node) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         t = Node[int] | 
					
						
							|  |  |  |         both_hints = get_type_hints(t.add_both, globals(), locals()) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(both_hints['left'], Optional[Node[T]]) | 
					
						
							|  |  |  |         self.assertEqual(both_hints['right'], Optional[Node[T]]) | 
					
						
							|  |  |  |         self.assertEqual(both_hints['left'], both_hints['right']) | 
					
						
							|  |  |  |         self.assertEqual(both_hints['stuff'], Optional[int]) | 
					
						
							|  |  |  |         self.assertNotIn('blah', both_hints) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         left_hints = get_type_hints(t.add_left, globals(), locals()) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(left_hints['node'], Optional[Node[T]]) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         right_hints = get_type_hints(t.add_right, globals(), locals()) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(right_hints['node'], Optional[Node[T]]) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |     def test_forwardref_instance_type_error(self): | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         fr = typing.ForwardRef('int') | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(42, fr) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     def test_forwardref_subclass_type_error(self): | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         fr = typing.ForwardRef('int') | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, fr) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_forward_equality(self): | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         fr = typing.ForwardRef('int') | 
					
						
							|  |  |  |         self.assertEqual(fr, typing.ForwardRef('int')) | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         self.assertNotEqual(List['int'], List[int]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-13 20:40:54 +01:00
										 |  |  |     def test_forward_equality_gth(self): | 
					
						
							|  |  |  |         c1 = typing.ForwardRef('C') | 
					
						
							|  |  |  |         c1_gth = typing.ForwardRef('C') | 
					
						
							|  |  |  |         c2 = typing.ForwardRef('C') | 
					
						
							|  |  |  |         c2_gth = typing.ForwardRef('C') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         def foo(a: c1_gth, b: c2_gth): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(foo, globals(), locals()), {'a': C, 'b': C}) | 
					
						
							|  |  |  |         self.assertEqual(c1, c2) | 
					
						
							|  |  |  |         self.assertEqual(c1, c1_gth) | 
					
						
							|  |  |  |         self.assertEqual(c1_gth, c2_gth) | 
					
						
							|  |  |  |         self.assertEqual(List[c1], List[c1_gth]) | 
					
						
							|  |  |  |         self.assertNotEqual(List[c1], List[C]) | 
					
						
							|  |  |  |         self.assertNotEqual(List[c1_gth], List[C]) | 
					
						
							| 
									
										
										
										
											2019-09-14 01:42:56 -06:00
										 |  |  |         self.assertEqual(Union[c1, c1_gth], Union[c1]) | 
					
						
							|  |  |  |         self.assertEqual(Union[c1, c1_gth, int], Union[c1, int]) | 
					
						
							| 
									
										
										
										
											2019-09-13 20:40:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_forward_equality_hash(self): | 
					
						
							|  |  |  |         c1 = typing.ForwardRef('int') | 
					
						
							|  |  |  |         c1_gth = typing.ForwardRef('int') | 
					
						
							|  |  |  |         c2 = typing.ForwardRef('int') | 
					
						
							|  |  |  |         c2_gth = typing.ForwardRef('int') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(a: c1_gth, b: c2_gth): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         get_type_hints(foo, globals(), locals()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(hash(c1), hash(c2)) | 
					
						
							|  |  |  |         self.assertEqual(hash(c1_gth), hash(c2_gth)) | 
					
						
							|  |  |  |         self.assertEqual(hash(c1), hash(c1_gth)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_forward_equality_namespace(self): | 
					
						
							|  |  |  |         class A: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         def namespace1(): | 
					
						
							|  |  |  |             a = typing.ForwardRef('A') | 
					
						
							|  |  |  |             def fun(x: a): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             get_type_hints(fun, globals(), locals()) | 
					
						
							|  |  |  |             return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def namespace2(): | 
					
						
							|  |  |  |             a = typing.ForwardRef('A') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             class A: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             def fun(x: a): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             get_type_hints(fun, globals(), locals()) | 
					
						
							|  |  |  |             return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(namespace1(), namespace1()) | 
					
						
							|  |  |  |         self.assertNotEqual(namespace1(), namespace2()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     def test_forward_repr(self): | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         self.assertEqual(repr(List['int']), "typing.List[ForwardRef('int')]") | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_union_forward(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(a: Union['T']): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(foo, globals(), locals()), | 
					
						
							|  |  |  |                          {'a': Union[T]}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_tuple_forward(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(a: Tuple['T']): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(foo, globals(), locals()), | 
					
						
							|  |  |  |                          {'a': Tuple[T]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-13 20:40:54 +01:00
										 |  |  |     def test_forward_recursion_actually(self): | 
					
						
							|  |  |  |         def namespace1(): | 
					
						
							|  |  |  |             a = typing.ForwardRef('A') | 
					
						
							|  |  |  |             A = a | 
					
						
							|  |  |  |             def fun(x: a): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ret = get_type_hints(fun, globals(), locals()) | 
					
						
							|  |  |  |             return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def namespace2(): | 
					
						
							|  |  |  |             a = typing.ForwardRef('A') | 
					
						
							|  |  |  |             A = a | 
					
						
							|  |  |  |             def fun(x: a): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ret = get_type_hints(fun, globals(), locals()) | 
					
						
							|  |  |  |             return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def cmp(o1, o2): | 
					
						
							|  |  |  |             return o1 == o2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         r1 = namespace1() | 
					
						
							|  |  |  |         r2 = namespace2() | 
					
						
							|  |  |  |         self.assertIsNot(r1, r2) | 
					
						
							|  |  |  |         self.assertRaises(RecursionError, cmp, r1, r2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_union_forward_recursion(self): | 
					
						
							|  |  |  |         ValueList = List['Value'] | 
					
						
							|  |  |  |         Value = Union[str, ValueList] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             foo: List[Value] | 
					
						
							|  |  |  |         class D: | 
					
						
							|  |  |  |             foo: Union[Value, ValueList] | 
					
						
							|  |  |  |         class E: | 
					
						
							|  |  |  |             foo: Union[List[Value], ValueList] | 
					
						
							|  |  |  |         class F: | 
					
						
							|  |  |  |             foo: Union[Value, List[Value], ValueList] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(C, globals(), locals()), get_type_hints(C, globals(), locals())) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(C, globals(), locals()), | 
					
						
							|  |  |  |                          {'foo': List[Union[str, List[Union[str, List['Value']]]]]}) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(D, globals(), locals()), | 
					
						
							|  |  |  |                          {'foo': Union[str, List[Union[str, List['Value']]]]}) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(E, globals(), locals()), | 
					
						
							|  |  |  |                          {'foo': Union[ | 
					
						
							|  |  |  |                              List[Union[str, List[Union[str, List['Value']]]]], | 
					
						
							|  |  |  |                              List[Union[str, List['Value']]] | 
					
						
							|  |  |  |                          ] | 
					
						
							|  |  |  |                           }) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(F, globals(), locals()), | 
					
						
							|  |  |  |                          {'foo': Union[ | 
					
						
							|  |  |  |                              str, | 
					
						
							|  |  |  |                              List[Union[str, List['Value']]], | 
					
						
							|  |  |  |                              List[Union[str, List[Union[str, List['Value']]]]] | 
					
						
							|  |  |  |                          ] | 
					
						
							|  |  |  |                           }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_callable_forward(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(a: Callable[['T'], 'T']): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(foo, globals(), locals()), | 
					
						
							|  |  |  |                          {'a': Callable[[T], T]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |     def test_callable_with_ellipsis_forward(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(a: 'Callable[..., T]'): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(foo, globals(), locals()), | 
					
						
							|  |  |  |                          {'a': Callable[..., T]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_syntax_error(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							|  |  |  |             Generic['/T'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_delayed_syntax_error(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(a: 'Node[T'): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							|  |  |  |             get_type_hints(foo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_type_error(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(a: Tuple['42']): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             get_type_hints(foo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_name_error(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(a: 'Noode[T]'): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(NameError): | 
					
						
							|  |  |  |             get_type_hints(foo, locals()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_type_check(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @no_type_check | 
					
						
							|  |  |  |         def foo(a: 'whatevers') -> {}: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         th = get_type_hints(foo) | 
					
						
							|  |  |  |         self.assertEqual(th, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_type_check_class(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @no_type_check | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def foo(a: 'whatevers') -> {}: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cth = get_type_hints(C.foo) | 
					
						
							|  |  |  |         self.assertEqual(cth, {}) | 
					
						
							|  |  |  |         ith = get_type_hints(C().foo) | 
					
						
							|  |  |  |         self.assertEqual(ith, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     def test_no_type_check_no_bases(self): | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def meth(self, x: int): ... | 
					
						
							|  |  |  |         @no_type_check | 
					
						
							|  |  |  |         class D(C): | 
					
						
							|  |  |  |             c = C | 
					
						
							|  |  |  |         # verify that @no_type_check never affects bases | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(C.meth), {'x': int}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-16 12:27:03 -04:00
										 |  |  |     def test_no_type_check_forward_ref_as_string(self): | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             foo: typing.ClassVar[int] = 7 | 
					
						
							|  |  |  |         class D: | 
					
						
							|  |  |  |             foo: ClassVar[int] = 7 | 
					
						
							|  |  |  |         class E: | 
					
						
							|  |  |  |             foo: 'typing.ClassVar[int]' = 7 | 
					
						
							|  |  |  |         class F: | 
					
						
							|  |  |  |             foo: 'ClassVar[int]' = 7 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expected_result = {'foo': typing.ClassVar[int]} | 
					
						
							|  |  |  |         for clazz in [C, D, E, F]: | 
					
						
							|  |  |  |             self.assertEqual(get_type_hints(clazz), expected_result) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_nested_classvar_fails_forward_ref_check(self): | 
					
						
							|  |  |  |         class E: | 
					
						
							|  |  |  |             foo: 'typing.ClassVar[typing.ClassVar[int]]' = 7 | 
					
						
							|  |  |  |         class F: | 
					
						
							|  |  |  |             foo: ClassVar['ClassVar[int]'] = 7 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for clazz in [E, F]: | 
					
						
							|  |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 get_type_hints(clazz) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_meta_no_type_check(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @no_type_check_decorator | 
					
						
							| 
									
										
										
										
											2017-10-12 12:28:55 -04:00
										 |  |  |         def magic_decorator(func): | 
					
						
							|  |  |  |             return func | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(magic_decorator.__name__, 'magic_decorator') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @magic_decorator | 
					
						
							|  |  |  |         def foo(a: 'whatevers') -> {}: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @magic_decorator | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def foo(a: 'whatevers') -> {}: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(foo.__name__, 'foo') | 
					
						
							|  |  |  |         th = get_type_hints(foo) | 
					
						
							|  |  |  |         self.assertEqual(th, {}) | 
					
						
							|  |  |  |         cth = get_type_hints(C.foo) | 
					
						
							|  |  |  |         self.assertEqual(cth, {}) | 
					
						
							|  |  |  |         ith = get_type_hints(C().foo) | 
					
						
							|  |  |  |         self.assertEqual(ith, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_default_globals(self): | 
					
						
							|  |  |  |         code = ("class C:\n" | 
					
						
							|  |  |  |                 "    def foo(self, a: 'C') -> 'D': pass\n" | 
					
						
							|  |  |  |                 "class D:\n" | 
					
						
							|  |  |  |                 "    def bar(self, b: 'D') -> C: pass\n" | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |         ns = {} | 
					
						
							|  |  |  |         exec(code, ns) | 
					
						
							|  |  |  |         hints = get_type_hints(ns['C'].foo) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(hints, {'a': ns['C'], 'return': ns['D']}) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 00:54:13 +01:00
										 |  |  |     def test_final_forward_ref(self): | 
					
						
							|  |  |  |         self.assertEqual(gth(Loop, globals())['attr'], Final[Loop]) | 
					
						
							|  |  |  |         self.assertNotEqual(gth(Loop, globals())['attr'], Final[int]) | 
					
						
							|  |  |  |         self.assertNotEqual(gth(Loop, globals())['attr'], Final) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class OverloadTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_overload_fails(self): | 
					
						
							|  |  |  |         from typing import overload | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(RuntimeError): | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |             @overload | 
					
						
							|  |  |  |             def blah(): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |             blah() | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |     def test_overload_succeeds(self): | 
					
						
							|  |  |  |         from typing import overload | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @overload | 
					
						
							|  |  |  |         def blah(): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def blah(): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         blah() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-21 16:12:17 -07:00
										 |  |  | ASYNCIO_TESTS = """
 | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | import asyncio | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 16:05:26 -07:00
										 |  |  | T_a = TypeVar('T_a') | 
					
						
							| 
									
										
										
										
											2015-12-03 17:31:24 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class AwaitableWrapper(typing.Awaitable[T_a]): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, value): | 
					
						
							|  |  |  |         self.value = value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __await__(self) -> typing.Iterator[T_a]: | 
					
						
							|  |  |  |         yield | 
					
						
							|  |  |  |         return self.value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AsyncIteratorWrapper(typing.AsyncIterator[T_a]): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, value: typing.Iterable[T_a]): | 
					
						
							|  |  |  |         self.value = value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __aiter__(self) -> typing.AsyncIterator[T_a]: | 
					
						
							|  |  |  |         return self | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-16 17:52:10 +03:00
										 |  |  |     async def __anext__(self) -> T_a: | 
					
						
							|  |  |  |         data = await self.value | 
					
						
							| 
									
										
										
										
											2015-12-03 17:31:24 -08:00
										 |  |  |         if data: | 
					
						
							|  |  |  |             return data | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             raise StopAsyncIteration | 
					
						
							| 
									
										
										
										
											2017-06-10 21:57:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class ACM: | 
					
						
							|  |  |  |     async def __aenter__(self) -> int: | 
					
						
							|  |  |  |         return 42 | 
					
						
							|  |  |  |     async def __aexit__(self, etype, eval, tb): | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  | try: | 
					
						
							|  |  |  |     exec(ASYNCIO_TESTS) | 
					
						
							|  |  |  | except ImportError: | 
					
						
							|  |  |  |     ASYNCIO = False  # multithreading is not enabled | 
					
						
							| 
									
										
										
										
											2017-01-22 17:43:53 -08:00
										 |  |  | else: | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |     ASYNCIO = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Definitions needed for features introduced in Python 3.6 | 
					
						
							| 
									
										
										
										
											2015-12-03 17:31:24 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | from test import ann_module, ann_module2, ann_module3 | 
					
						
							| 
									
										
										
										
											2017-06-10 21:57:56 +02:00
										 |  |  | from typing import AsyncContextManager | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-09 13:12:51 -08:00
										 |  |  | class A: | 
					
						
							|  |  |  |     y: float | 
					
						
							|  |  |  | class B(A): | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |     x: ClassVar[Optional['B']] = None | 
					
						
							|  |  |  |     y: int | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     b: int | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | class CSub(B): | 
					
						
							|  |  |  |     z: ClassVar['CSub'] = B() | 
					
						
							|  |  |  | class G(Generic[T]): | 
					
						
							|  |  |  |     lst: ClassVar[List[T]] = [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-27 00:54:13 +01:00
										 |  |  | class Loop: | 
					
						
							|  |  |  |     attr: Final['Loop'] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  | class NoneAndForward: | 
					
						
							|  |  |  |     parent: 'NoneAndForward' | 
					
						
							|  |  |  |     meaning: None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | class CoolEmployee(NamedTuple): | 
					
						
							|  |  |  |     name: str | 
					
						
							|  |  |  |     cool: int | 
					
						
							| 
									
										
										
										
											2017-01-18 08:03:50 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class CoolEmployeeWithDefault(NamedTuple): | 
					
						
							|  |  |  |     name: str | 
					
						
							|  |  |  |     cool: int = 0 | 
					
						
							| 
									
										
										
										
											2017-01-22 17:47:20 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class XMeth(NamedTuple): | 
					
						
							|  |  |  |     x: int | 
					
						
							|  |  |  |     def double(self): | 
					
						
							|  |  |  |         return 2 * self.x | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  | class XRepr(NamedTuple): | 
					
						
							| 
									
										
										
										
											2017-01-22 17:47:20 -08:00
										 |  |  |     x: int | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     y: int = 1 | 
					
						
							|  |  |  |     def __str__(self): | 
					
						
							|  |  |  |         return f'{self.x} -> {self.y}' | 
					
						
							|  |  |  |     def __add__(self, other): | 
					
						
							|  |  |  |         return 0 | 
					
						
							| 
									
										
										
										
											2017-06-10 21:57:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-14 14:33:00 -04:00
										 |  |  | class HasForeignBaseClass(mod_generics_cache.A): | 
					
						
							|  |  |  |     some_xrepr: 'XRepr' | 
					
						
							|  |  |  |     other_a: 'mod_generics_cache.A' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-10 21:57:56 +02:00
										 |  |  | async def g_with(am: AsyncContextManager[int]): | 
					
						
							|  |  |  |     x: int | 
					
						
							|  |  |  |     async with am as x: | 
					
						
							|  |  |  |         return x | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | try: | 
					
						
							|  |  |  |     g_with(ACM()).send(None) | 
					
						
							|  |  |  | except StopIteration as e: | 
					
						
							|  |  |  |     assert e.args[0] == 42 | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | gth = get_type_hints | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-21 17:24:58 +00:00
										 |  |  | class ForRefExample: | 
					
						
							|  |  |  |     @ann_module.dec | 
					
						
							|  |  |  |     def func(self: 'ForRefExample'): | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @ann_module.dec | 
					
						
							|  |  |  |     @ann_module.dec | 
					
						
							|  |  |  |     def nested(self: 'ForRefExample'): | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-22 17:43:53 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | class GetTypeHintTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2016-11-09 13:12:51 -08:00
										 |  |  |     def test_get_type_hints_from_various_objects(self): | 
					
						
							|  |  |  |         # For invalid objects should fail with TypeError (not AttributeError etc). | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             gth(123) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             gth('abc') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             gth(None) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |     def test_get_type_hints_modules(self): | 
					
						
							| 
									
										
										
										
											2017-01-22 17:43:53 -08:00
										 |  |  |         ann_module_type_hints = {1: 2, 'f': Tuple[int, int], 'x': int, 'y': str} | 
					
						
							|  |  |  |         self.assertEqual(gth(ann_module), ann_module_type_hints) | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |         self.assertEqual(gth(ann_module2), {}) | 
					
						
							|  |  |  |         self.assertEqual(gth(ann_module3), {}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-11 09:18:31 -07:00
										 |  |  |     @skip("known bug") | 
					
						
							| 
									
										
										
										
											2017-09-14 14:33:00 -04:00
										 |  |  |     def test_get_type_hints_modules_forwardref(self): | 
					
						
							|  |  |  |         # FIXME: This currently exposes a bug in typing. Cached forward references | 
					
						
							|  |  |  |         # don't account for the case where there are multiple types of the same | 
					
						
							|  |  |  |         # name coming from different modules in the same program. | 
					
						
							|  |  |  |         mgc_hints = {'default_a': Optional[mod_generics_cache.A], | 
					
						
							|  |  |  |                      'default_b': Optional[mod_generics_cache.B]} | 
					
						
							|  |  |  |         self.assertEqual(gth(mod_generics_cache), mgc_hints) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |     def test_get_type_hints_classes(self): | 
					
						
							| 
									
										
										
										
											2017-09-14 14:33:00 -04:00
										 |  |  |         self.assertEqual(gth(ann_module.C),  # gth will find the right globalns | 
					
						
							| 
									
										
										
										
											2016-11-09 13:12:51 -08:00
										 |  |  |                          {'y': Optional[ann_module.C]}) | 
					
						
							|  |  |  |         self.assertIsInstance(gth(ann_module.j_class), dict) | 
					
						
							|  |  |  |         self.assertEqual(gth(ann_module.M), {'123': 123, 'o': type}) | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |         self.assertEqual(gth(ann_module.D), | 
					
						
							| 
									
										
										
										
											2016-11-09 13:12:51 -08:00
										 |  |  |                          {'j': str, 'k': str, 'y': Optional[ann_module.C]}) | 
					
						
							|  |  |  |         self.assertEqual(gth(ann_module.Y), {'z': int}) | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |         self.assertEqual(gth(ann_module.h_class), | 
					
						
							| 
									
										
										
										
											2016-11-09 13:12:51 -08:00
										 |  |  |                          {'y': Optional[ann_module.C]}) | 
					
						
							|  |  |  |         self.assertEqual(gth(ann_module.S), {'x': str, 'y': str}) | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |         self.assertEqual(gth(ann_module.foo), {'x': int}) | 
					
						
							| 
									
										
										
										
											2017-09-14 14:33:00 -04:00
										 |  |  |         self.assertEqual(gth(NoneAndForward), | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |                          {'parent': NoneAndForward, 'meaning': type(None)}) | 
					
						
							| 
									
										
										
										
											2017-09-14 14:33:00 -04:00
										 |  |  |         self.assertEqual(gth(HasForeignBaseClass), | 
					
						
							|  |  |  |                          {'some_xrepr': XRepr, 'other_a': mod_generics_cache.A, | 
					
						
							|  |  |  |                           'some_b': mod_generics_cache.B}) | 
					
						
							| 
									
										
										
										
											2018-05-09 02:23:46 +01:00
										 |  |  |         self.assertEqual(gth(XRepr.__new__), | 
					
						
							|  |  |  |                          {'x': int, 'y': int}) | 
					
						
							| 
									
										
										
										
											2017-09-14 14:33:00 -04:00
										 |  |  |         self.assertEqual(gth(mod_generics_cache.B), | 
					
						
							|  |  |  |                          {'my_inner_a1': mod_generics_cache.B.A, | 
					
						
							|  |  |  |                           'my_inner_a2': mod_generics_cache.B.A, | 
					
						
							|  |  |  |                           'my_outer_a': mod_generics_cache.A}) | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_respect_no_type_check(self): | 
					
						
							|  |  |  |         @no_type_check | 
					
						
							|  |  |  |         class NoTpCheck: | 
					
						
							|  |  |  |             class Inn: | 
					
						
							|  |  |  |                 def __init__(self, x: 'not a type'): ... | 
					
						
							|  |  |  |         self.assertTrue(NoTpCheck.__no_type_check__) | 
					
						
							|  |  |  |         self.assertTrue(NoTpCheck.Inn.__init__.__no_type_check__) | 
					
						
							|  |  |  |         self.assertEqual(gth(ann_module2.NTC.meth), {}) | 
					
						
							|  |  |  |         class ABase(Generic[T]): | 
					
						
							|  |  |  |             def meth(x: int): ... | 
					
						
							|  |  |  |         @no_type_check | 
					
						
							|  |  |  |         class Der(ABase): ... | 
					
						
							|  |  |  |         self.assertEqual(gth(ABase.meth), {'x': int}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     def test_get_type_hints_for_builtins(self): | 
					
						
							| 
									
										
										
										
											2016-11-09 13:12:51 -08:00
										 |  |  |         # Should not fail for built-in classes and functions. | 
					
						
							|  |  |  |         self.assertEqual(gth(int), {}) | 
					
						
							|  |  |  |         self.assertEqual(gth(type), {}) | 
					
						
							|  |  |  |         self.assertEqual(gth(dir), {}) | 
					
						
							|  |  |  |         self.assertEqual(gth(len), {}) | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         self.assertEqual(gth(object.__str__), {}) | 
					
						
							|  |  |  |         self.assertEqual(gth(object().__str__), {}) | 
					
						
							|  |  |  |         self.assertEqual(gth(str.join), {}) | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_previous_behavior(self): | 
					
						
							|  |  |  |         def testf(x, y): ... | 
					
						
							|  |  |  |         testf.__annotations__['x'] = 'int' | 
					
						
							|  |  |  |         self.assertEqual(gth(testf), {'x': int}) | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         def testg(x: None): ... | 
					
						
							|  |  |  |         self.assertEqual(gth(testg), {'x': type(None)}) | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-09 13:12:51 -08:00
										 |  |  |     def test_get_type_hints_for_object_with_annotations(self): | 
					
						
							|  |  |  |         class A: ... | 
					
						
							|  |  |  |         class B: ... | 
					
						
							|  |  |  |         b = B() | 
					
						
							|  |  |  |         b.__annotations__ = {'x': 'A'} | 
					
						
							|  |  |  |         self.assertEqual(gth(b, locals()), {'x': A}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |     def test_get_type_hints_ClassVar(self): | 
					
						
							| 
									
										
										
										
											2016-11-09 13:12:51 -08:00
										 |  |  |         self.assertEqual(gth(ann_module2.CV, ann_module2.__dict__), | 
					
						
							|  |  |  |                          {'var': typing.ClassVar[ann_module2.CV]}) | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |         self.assertEqual(gth(B, globals()), | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |                          {'y': int, 'x': ClassVar[Optional[B]], 'b': int}) | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |         self.assertEqual(gth(CSub, globals()), | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |                          {'z': ClassVar[CSub], 'y': int, 'b': int, | 
					
						
							|  |  |  |                           'x': ClassVar[Optional[B]]}) | 
					
						
							| 
									
										
										
										
											2016-11-09 13:12:51 -08:00
										 |  |  |         self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-21 17:24:58 +00:00
										 |  |  |     def test_get_type_hints_wrapped_decoratored_func(self): | 
					
						
							|  |  |  |         expects = {'self': ForRefExample} | 
					
						
							|  |  |  |         self.assertEqual(gth(ForRefExample.func), expects) | 
					
						
							|  |  |  |         self.assertEqual(gth(ForRefExample.nested), expects) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |     def test_get_type_hints_annotated(self): | 
					
						
							|  |  |  |         def foobar(x: List['X']): ... | 
					
						
							|  |  |  |         X = Annotated[int, (1, 10)] | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(foobar, globals(), locals()), | 
					
						
							|  |  |  |             {'x': List[int]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(foobar, globals(), locals(), include_extras=True), | 
					
						
							|  |  |  |             {'x': List[Annotated[int, (1, 10)]]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         BA = Tuple[Annotated[T, (1, 0)], ...] | 
					
						
							|  |  |  |         def barfoo(x: BA): ... | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], Tuple[T, ...]) | 
					
						
							|  |  |  |         self.assertIs( | 
					
						
							|  |  |  |             get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'], | 
					
						
							|  |  |  |             BA | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         def barfoo2(x: typing.Callable[..., Annotated[List[T], "const"]], | 
					
						
							|  |  |  |                     y: typing.Union[int, Annotated[T, "mutable"]]): ... | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(barfoo2, globals(), locals()), | 
					
						
							|  |  |  |             {'x': typing.Callable[..., List[T]], 'y': typing.Union[int, T]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         BA2 = typing.Callable[..., List[T]] | 
					
						
							|  |  |  |         def barfoo3(x: BA2): ... | 
					
						
							|  |  |  |         self.assertIs( | 
					
						
							|  |  |  |             get_type_hints(barfoo3, globals(), locals(), include_extras=True)["x"], | 
					
						
							|  |  |  |             BA2 | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_type_hints_annotated_refs(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Const = Annotated[T, "Const"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MySet(Generic[T]): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def __ior__(self, other: "Const[MySet[T]]") -> "MySet[T]": | 
					
						
							|  |  |  |                 ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def __iand__(self, other: Const["MySet[T]"]) -> "MySet[T]": | 
					
						
							|  |  |  |                 ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(MySet.__iand__, globals(), locals()), | 
					
						
							|  |  |  |             {'other': MySet[T], 'return': MySet[T]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(MySet.__iand__, globals(), locals(), include_extras=True), | 
					
						
							|  |  |  |             {'other': Const[MySet[T]], 'return': MySet[T]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(MySet.__ior__, globals(), locals()), | 
					
						
							|  |  |  |             {'other': MySet[T], 'return': MySet[T]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-03 17:31:24 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 00:10:07 +01:00
										 |  |  | class GetUtilitiesTestCase(TestCase): | 
					
						
							|  |  |  |     def test_get_origin(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         class C(Generic[T]): pass | 
					
						
							|  |  |  |         self.assertIs(get_origin(C[int]), C) | 
					
						
							|  |  |  |         self.assertIs(get_origin(C[T]), C) | 
					
						
							|  |  |  |         self.assertIs(get_origin(int), None) | 
					
						
							|  |  |  |         self.assertIs(get_origin(ClassVar[int]), ClassVar) | 
					
						
							|  |  |  |         self.assertIs(get_origin(Union[int, str]), Union) | 
					
						
							|  |  |  |         self.assertIs(get_origin(Literal[42, 43]), Literal) | 
					
						
							|  |  |  |         self.assertIs(get_origin(Final[List[int]]), Final) | 
					
						
							|  |  |  |         self.assertIs(get_origin(Generic), Generic) | 
					
						
							|  |  |  |         self.assertIs(get_origin(Generic[T]), Generic) | 
					
						
							|  |  |  |         self.assertIs(get_origin(List[Tuple[T, T]][int]), list) | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |         self.assertIs(get_origin(Annotated[T, 'thing']), Annotated) | 
					
						
							| 
									
										
										
										
											2019-05-31 00:10:07 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_get_args(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         class C(Generic[T]): pass | 
					
						
							|  |  |  |         self.assertEqual(get_args(C[int]), (int,)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(C[T]), (T,)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(int), ()) | 
					
						
							|  |  |  |         self.assertEqual(get_args(ClassVar[int]), (int,)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Union[int, str]), (int, str)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Literal[42, 43]), (42, 43)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Final[List[int]]), (List[int],)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Union[int, Tuple[T, int]][str]), | 
					
						
							|  |  |  |                          (int, Tuple[str, int])) | 
					
						
							|  |  |  |         self.assertEqual(get_args(typing.Dict[int, Tuple[T, T]][Optional[int]]), | 
					
						
							|  |  |  |                          (int, Tuple[Optional[int], Optional[int]])) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Callable[[], T][int]), ([], int,)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Union[int, Callable[[Tuple[T, ...]], str]]), | 
					
						
							|  |  |  |                          (int, Callable[[Tuple[T, ...]], str])) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Tuple[int, ...]), (int, ...)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Tuple[()]), ((),)) | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |         self.assertEqual(get_args(Annotated[T, 'one', 2, ['three']]), (T, 'one', 2, ['three'])) | 
					
						
							| 
									
										
										
										
											2019-05-31 00:10:07 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class CollectionsAbcTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_hashable(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(42, typing.Hashable) | 
					
						
							|  |  |  |         self.assertNotIsInstance([], typing.Hashable) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_iterable(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance([], typing.Iterable) | 
					
						
							| 
									
										
										
										
											2015-09-04 12:15:54 -07:00
										 |  |  |         # Due to ABC caching, the second time takes a separate code | 
					
						
							|  |  |  |         # path and could fail.  So call this a few times. | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance([], typing.Iterable) | 
					
						
							|  |  |  |         self.assertIsInstance([], typing.Iterable) | 
					
						
							|  |  |  |         self.assertNotIsInstance(42, typing.Iterable) | 
					
						
							| 
									
										
										
										
											2015-09-04 12:15:54 -07:00
										 |  |  |         # Just in case, also test issubclass() a few times. | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(list, typing.Iterable) | 
					
						
							|  |  |  |         self.assertIsSubclass(list, typing.Iterable) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_iterator(self): | 
					
						
							|  |  |  |         it = iter([]) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(it, typing.Iterator) | 
					
						
							|  |  |  |         self.assertNotIsInstance(42, typing.Iterator) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-21 16:12:17 -07:00
										 |  |  |     @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') | 
					
						
							| 
									
										
										
										
											2015-12-03 17:31:24 -08:00
										 |  |  |     def test_awaitable(self): | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |         ns = {} | 
					
						
							|  |  |  |         exec( | 
					
						
							|  |  |  |             "async def foo() -> typing.Awaitable[int]:\n" | 
					
						
							|  |  |  |             "    return await AwaitableWrapper(42)\n", | 
					
						
							|  |  |  |             globals(), ns) | 
					
						
							|  |  |  |         foo = ns['foo'] | 
					
						
							| 
									
										
										
										
											2015-12-03 17:31:24 -08:00
										 |  |  |         g = foo() | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(g, typing.Awaitable) | 
					
						
							|  |  |  |         self.assertNotIsInstance(foo, typing.Awaitable) | 
					
						
							| 
									
										
										
										
											2015-12-03 17:31:24 -08:00
										 |  |  |         g.send(None)  # Run foo() till completion, to avoid warning. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 16:05:26 -07:00
										 |  |  |     @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') | 
					
						
							|  |  |  |     def test_coroutine(self): | 
					
						
							|  |  |  |         ns = {} | 
					
						
							|  |  |  |         exec( | 
					
						
							|  |  |  |             "async def foo():\n" | 
					
						
							|  |  |  |             "    return\n", | 
					
						
							|  |  |  |             globals(), ns) | 
					
						
							|  |  |  |         foo = ns['foo'] | 
					
						
							|  |  |  |         g = foo() | 
					
						
							|  |  |  |         self.assertIsInstance(g, typing.Coroutine) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(g, typing.Coroutine[int]) | 
					
						
							|  |  |  |         self.assertNotIsInstance(foo, typing.Coroutine) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             g.send(None) | 
					
						
							|  |  |  |         except StopIteration: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-21 16:12:17 -07:00
										 |  |  |     @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') | 
					
						
							| 
									
										
										
										
											2015-12-03 17:31:24 -08:00
										 |  |  |     def test_async_iterable(self): | 
					
						
							|  |  |  |         base_it = range(10)  # type: Iterator[int] | 
					
						
							|  |  |  |         it = AsyncIteratorWrapper(base_it) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(it, typing.AsyncIterable) | 
					
						
							|  |  |  |         self.assertIsInstance(it, typing.AsyncIterable) | 
					
						
							|  |  |  |         self.assertNotIsInstance(42, typing.AsyncIterable) | 
					
						
							| 
									
										
										
										
											2015-12-03 17:31:24 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-21 16:12:17 -07:00
										 |  |  |     @skipUnless(ASYNCIO, 'Python 3.5 and multithreading required') | 
					
						
							| 
									
										
										
										
											2015-12-03 17:31:24 -08:00
										 |  |  |     def test_async_iterator(self): | 
					
						
							|  |  |  |         base_it = range(10)  # type: Iterator[int] | 
					
						
							|  |  |  |         it = AsyncIteratorWrapper(base_it) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(it, typing.AsyncIterator) | 
					
						
							|  |  |  |         self.assertNotIsInstance(42, typing.AsyncIterator) | 
					
						
							| 
									
										
										
										
											2015-12-03 17:31:24 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_sized(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance([], typing.Sized) | 
					
						
							|  |  |  |         self.assertNotIsInstance(42, typing.Sized) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_container(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance([], typing.Container) | 
					
						
							|  |  |  |         self.assertNotIsInstance(42, typing.Container) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-23 11:01:50 -07:00
										 |  |  |     def test_collection(self): | 
					
						
							|  |  |  |         if hasattr(typing, 'Collection'): | 
					
						
							|  |  |  |             self.assertIsInstance(tuple(), typing.Collection) | 
					
						
							|  |  |  |             self.assertIsInstance(frozenset(), typing.Collection) | 
					
						
							|  |  |  |             self.assertIsSubclass(dict, typing.Collection) | 
					
						
							|  |  |  |             self.assertNotIsInstance(42, typing.Collection) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_abstractset(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(set(), typing.AbstractSet) | 
					
						
							|  |  |  |         self.assertNotIsInstance(42, typing.AbstractSet) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_mutableset(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(set(), typing.MutableSet) | 
					
						
							|  |  |  |         self.assertNotIsInstance(frozenset(), typing.MutableSet) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_mapping(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance({}, typing.Mapping) | 
					
						
							|  |  |  |         self.assertNotIsInstance(42, typing.Mapping) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_mutablemapping(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance({}, typing.MutableMapping) | 
					
						
							|  |  |  |         self.assertNotIsInstance(42, typing.MutableMapping) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_sequence(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance([], typing.Sequence) | 
					
						
							|  |  |  |         self.assertNotIsInstance(42, typing.Sequence) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_mutablesequence(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance([], typing.MutableSequence) | 
					
						
							|  |  |  |         self.assertNotIsInstance((), typing.MutableSequence) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_bytestring(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(b'', typing.ByteString) | 
					
						
							|  |  |  |         self.assertIsInstance(bytearray(b''), typing.ByteString) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_list(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(list, typing.List) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-16 22:42:37 -08:00
										 |  |  |     def test_deque(self): | 
					
						
							|  |  |  |         self.assertIsSubclass(collections.deque, typing.Deque) | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         class MyDeque(typing.Deque[int]): ... | 
					
						
							|  |  |  |         self.assertIsInstance(MyDeque(), collections.deque) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_counter(self): | 
					
						
							|  |  |  |         self.assertIsSubclass(collections.Counter, typing.Counter) | 
					
						
							| 
									
										
										
										
											2017-01-16 22:42:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_set(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(set, typing.Set) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(frozenset, typing.Set) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_frozenset(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(frozenset, typing.FrozenSet) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(set, typing.FrozenSet) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_dict(self): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(dict, typing.Dict) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_no_list_instantiation(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.List() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.List[T]() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.List[int]() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-18 08:35:00 -07:00
										 |  |  |     def test_list_subclass(self): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class MyList(typing.List[int]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         a = MyList() | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(a, MyList) | 
					
						
							| 
									
										
										
										
											2016-05-18 08:35:00 -07:00
										 |  |  |         self.assertIsInstance(a, typing.Sequence) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsSubclass(MyList, list) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(list, MyList) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_no_dict_instantiation(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.Dict() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.Dict[KT, VT]() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.Dict[str, int]() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-18 08:35:00 -07:00
										 |  |  |     def test_dict_subclass(self): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class MyDict(typing.Dict[str, int]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         d = MyDict() | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(d, MyDict) | 
					
						
							| 
									
										
										
										
											2016-05-18 08:35:00 -07:00
										 |  |  |         self.assertIsInstance(d, typing.MutableMapping) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsSubclass(MyDict, dict) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(dict, MyDict) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     def test_defaultdict_instantiation(self): | 
					
						
							|  |  |  |         self.assertIs(type(typing.DefaultDict()), collections.defaultdict) | 
					
						
							|  |  |  |         self.assertIs(type(typing.DefaultDict[KT, VT]()), collections.defaultdict) | 
					
						
							|  |  |  |         self.assertIs(type(typing.DefaultDict[str, int]()), collections.defaultdict) | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-18 08:35:00 -07:00
										 |  |  |     def test_defaultdict_subclass(self): | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class MyDefDict(typing.DefaultDict[str, int]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         dd = MyDefDict() | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(dd, MyDefDict) | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-18 08:35:00 -07:00
										 |  |  |         self.assertIsSubclass(MyDefDict, collections.defaultdict) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(collections.defaultdict, MyDefDict) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-02 17:53:14 +02:00
										 |  |  |     def test_ordereddict_instantiation(self): | 
					
						
							|  |  |  |         self.assertIs(type(typing.OrderedDict()), collections.OrderedDict) | 
					
						
							|  |  |  |         self.assertIs(type(typing.OrderedDict[KT, VT]()), collections.OrderedDict) | 
					
						
							|  |  |  |         self.assertIs(type(typing.OrderedDict[str, int]()), collections.OrderedDict) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_ordereddict_subclass(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MyOrdDict(typing.OrderedDict[str, int]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         od = MyOrdDict() | 
					
						
							|  |  |  |         self.assertIsInstance(od, MyOrdDict) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsSubclass(MyOrdDict, collections.OrderedDict) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(collections.OrderedDict, MyOrdDict) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') | 
					
						
							|  |  |  |     def test_chainmap_instantiation(self): | 
					
						
							|  |  |  |         self.assertIs(type(typing.ChainMap()), collections.ChainMap) | 
					
						
							|  |  |  |         self.assertIs(type(typing.ChainMap[KT, VT]()), collections.ChainMap) | 
					
						
							|  |  |  |         self.assertIs(type(typing.ChainMap[str, int]()), collections.ChainMap) | 
					
						
							|  |  |  |         class CM(typing.ChainMap[KT, VT]): ... | 
					
						
							|  |  |  |         self.assertIs(type(CM[int, str]()), CM) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') | 
					
						
							|  |  |  |     def test_chainmap_subclass(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MyChainMap(typing.ChainMap[str, int]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cm = MyChainMap() | 
					
						
							|  |  |  |         self.assertIsInstance(cm, MyChainMap) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsSubclass(MyChainMap, collections.ChainMap) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(collections.ChainMap, MyChainMap) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_deque_instantiation(self): | 
					
						
							|  |  |  |         self.assertIs(type(typing.Deque()), collections.deque) | 
					
						
							|  |  |  |         self.assertIs(type(typing.Deque[T]()), collections.deque) | 
					
						
							|  |  |  |         self.assertIs(type(typing.Deque[int]()), collections.deque) | 
					
						
							|  |  |  |         class D(typing.Deque[T]): ... | 
					
						
							|  |  |  |         self.assertIs(type(D[int]()), D) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_counter_instantiation(self): | 
					
						
							|  |  |  |         self.assertIs(type(typing.Counter()), collections.Counter) | 
					
						
							|  |  |  |         self.assertIs(type(typing.Counter[T]()), collections.Counter) | 
					
						
							|  |  |  |         self.assertIs(type(typing.Counter[int]()), collections.Counter) | 
					
						
							|  |  |  |         class C(typing.Counter[T]): ... | 
					
						
							|  |  |  |         self.assertIs(type(C[int]()), C) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_counter_subclass_instantiation(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MyCounter(typing.Counter[int]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         d = MyCounter() | 
					
						
							|  |  |  |         self.assertIsInstance(d, MyCounter) | 
					
						
							|  |  |  |         self.assertIsInstance(d, typing.Counter) | 
					
						
							|  |  |  |         self.assertIsInstance(d, collections.Counter) | 
					
						
							| 
									
										
										
										
											2017-01-16 22:42:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_no_set_instantiation(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.Set() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.Set[T]() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.Set[int]() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_set_subclass_instantiation(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MySet(typing.Set[int]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         d = MySet() | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(d, MySet) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_no_frozenset_instantiation(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.FrozenSet() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.FrozenSet[T]() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.FrozenSet[int]() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_frozenset_subclass_instantiation(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MyFrozenSet(typing.FrozenSet[int]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         d = MyFrozenSet() | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(d, MyFrozenSet) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_no_tuple_instantiation(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Tuple() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Tuple[T]() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Tuple[int]() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_generator(self): | 
					
						
							|  |  |  |         def foo(): | 
					
						
							|  |  |  |             yield 42 | 
					
						
							|  |  |  |         g = foo() | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(type(g), typing.Generator) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_no_generator_instantiation(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.Generator() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.Generator[T, T, T]() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.Generator[int, int, int]() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 13:10:31 -08:00
										 |  |  |     def test_async_generator(self): | 
					
						
							|  |  |  |         ns = {} | 
					
						
							|  |  |  |         exec("async def f():\n" | 
					
						
							| 
									
										
										
										
											2017-01-22 17:47:20 -08:00
										 |  |  |              "    yield 42\n", globals(), ns) | 
					
						
							| 
									
										
										
										
											2017-01-18 13:10:31 -08:00
										 |  |  |         g = ns['f']() | 
					
						
							|  |  |  |         self.assertIsSubclass(type(g), typing.AsyncGenerator) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_async_generator_instantiation(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.AsyncGenerator() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.AsyncGenerator[T, T]() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.AsyncGenerator[int, int]() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_subclassing(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MMA(typing.MutableMapping): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError):  # It's abstract | 
					
						
							|  |  |  |             MMA() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MMC(MMA): | 
					
						
							| 
									
										
										
										
											2016-10-03 08:40:50 -07:00
										 |  |  |             def __getitem__(self, k): | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  |             def __setitem__(self, k, v): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             def __delitem__(self, k): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             def __iter__(self): | 
					
						
							|  |  |  |                 return iter(()) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |             def __len__(self): | 
					
						
							|  |  |  |                 return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(len(MMC()), 0) | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  |         assert callable(MMC.update) | 
					
						
							|  |  |  |         self.assertIsInstance(MMC(), typing.Mapping) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class MMB(typing.MutableMapping[KT, VT]): | 
					
						
							| 
									
										
										
										
											2016-10-03 08:40:50 -07:00
										 |  |  |             def __getitem__(self, k): | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  |             def __setitem__(self, k, v): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             def __delitem__(self, k): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             def __iter__(self): | 
					
						
							|  |  |  |                 return iter(()) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |             def __len__(self): | 
					
						
							|  |  |  |                 return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(len(MMB()), 0) | 
					
						
							|  |  |  |         self.assertEqual(len(MMB[str, str]()), 0) | 
					
						
							|  |  |  |         self.assertEqual(len(MMB[KT, VT]()), 0) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-18 08:35:00 -07:00
										 |  |  |         self.assertNotIsSubclass(dict, MMA) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(dict, MMB) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsSubclass(MMA, typing.Mapping) | 
					
						
							|  |  |  |         self.assertIsSubclass(MMB, typing.Mapping) | 
					
						
							|  |  |  |         self.assertIsSubclass(MMC, typing.Mapping) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  |         self.assertIsInstance(MMB[KT, VT](), typing.Mapping) | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         self.assertIsInstance(MMB[KT, VT](), collections.abc.Mapping) | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         self.assertIsSubclass(MMA, collections.abc.Mapping) | 
					
						
							|  |  |  |         self.assertIsSubclass(MMB, collections.abc.Mapping) | 
					
						
							|  |  |  |         self.assertIsSubclass(MMC, collections.abc.Mapping) | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(MMB[str, str], typing.Mapping) | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  |         self.assertIsSubclass(MMC, MMA) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class I(typing.Iterable): ... | 
					
						
							|  |  |  |         self.assertNotIsSubclass(list, I) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class G(typing.Generator[int, int, int]): ... | 
					
						
							|  |  |  |         def g(): yield 0 | 
					
						
							|  |  |  |         self.assertIsSubclass(G, typing.Generator) | 
					
						
							|  |  |  |         self.assertIsSubclass(G, typing.Iterable) | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         self.assertIsSubclass(G, collections.abc.Generator) | 
					
						
							|  |  |  |         self.assertIsSubclass(G, collections.abc.Iterable) | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  |         self.assertNotIsSubclass(type(g), G) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 13:10:31 -08:00
										 |  |  |     def test_subclassing_async_generator(self): | 
					
						
							|  |  |  |         class G(typing.AsyncGenerator[int, int]): | 
					
						
							|  |  |  |             def asend(self, value): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             def athrow(self, typ, val=None, tb=None): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ns = {} | 
					
						
							|  |  |  |         exec('async def g(): yield 0', globals(), ns) | 
					
						
							|  |  |  |         g = ns['g'] | 
					
						
							|  |  |  |         self.assertIsSubclass(G, typing.AsyncGenerator) | 
					
						
							|  |  |  |         self.assertIsSubclass(G, typing.AsyncIterable) | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         self.assertIsSubclass(G, collections.abc.AsyncGenerator) | 
					
						
							|  |  |  |         self.assertIsSubclass(G, collections.abc.AsyncIterable) | 
					
						
							| 
									
										
										
										
											2017-01-18 13:10:31 -08:00
										 |  |  |         self.assertNotIsSubclass(type(g), G) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         instance = G() | 
					
						
							|  |  |  |         self.assertIsInstance(instance, typing.AsyncGenerator) | 
					
						
							|  |  |  |         self.assertIsInstance(instance, typing.AsyncIterable) | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         self.assertIsInstance(instance, collections.abc.AsyncGenerator) | 
					
						
							|  |  |  |         self.assertIsInstance(instance, collections.abc.AsyncIterable) | 
					
						
							| 
									
										
										
										
											2017-01-18 13:10:31 -08:00
										 |  |  |         self.assertNotIsInstance(type(g), G) | 
					
						
							|  |  |  |         self.assertNotIsInstance(g, G) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  |     def test_subclassing_subclasshook(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Base(typing.Iterable): | 
					
						
							|  |  |  |             @classmethod | 
					
						
							|  |  |  |             def __subclasshook__(cls, other): | 
					
						
							|  |  |  |                 if other.__name__ == 'Foo': | 
					
						
							|  |  |  |                     return True | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(Base): ... | 
					
						
							|  |  |  |         class Foo: ... | 
					
						
							|  |  |  |         class Bar: ... | 
					
						
							|  |  |  |         self.assertIsSubclass(Foo, Base) | 
					
						
							|  |  |  |         self.assertIsSubclass(Foo, C) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(Bar, C) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_subclassing_register(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class A(typing.Container): ... | 
					
						
							|  |  |  |         class B(A): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: ... | 
					
						
							|  |  |  |         A.register(C) | 
					
						
							|  |  |  |         self.assertIsSubclass(C, A) | 
					
						
							|  |  |  |         self.assertNotIsSubclass(C, B) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D: ... | 
					
						
							|  |  |  |         B.register(D) | 
					
						
							|  |  |  |         self.assertIsSubclass(D, A) | 
					
						
							|  |  |  |         self.assertIsSubclass(D, B) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class M(): ... | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         collections.abc.MutableMapping.register(M) | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  |         self.assertIsSubclass(M, typing.Mapping) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_collections_as_base(self): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         class M(collections.abc.Mapping): ... | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  |         self.assertIsSubclass(M, typing.Mapping) | 
					
						
							|  |  |  |         self.assertIsSubclass(M, typing.Iterable) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         class S(collections.abc.MutableSequence): ... | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  |         self.assertIsSubclass(S, typing.MutableSequence) | 
					
						
							|  |  |  |         self.assertIsSubclass(S, typing.Iterable) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         class I(collections.abc.Iterable): ... | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  |         self.assertIsSubclass(I, typing.Iterable) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         class A(collections.abc.Mapping, metaclass=abc.ABCMeta): ... | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  |         class B: ... | 
					
						
							|  |  |  |         A.register(B) | 
					
						
							|  |  |  |         self.assertIsSubclass(B, typing.Mapping) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class OtherABCTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2016-04-17 17:52:05 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_contextmanager(self): | 
					
						
							|  |  |  |         @contextlib.contextmanager | 
					
						
							|  |  |  |         def manager(): | 
					
						
							|  |  |  |             yield 42 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cm = manager() | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(cm, typing.ContextManager) | 
					
						
							|  |  |  |         self.assertNotIsInstance(42, typing.ContextManager) | 
					
						
							| 
									
										
										
										
											2016-04-17 17:52:05 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-10 21:57:56 +02:00
										 |  |  |     @skipUnless(ASYNCIO, 'Python 3.5 required') | 
					
						
							|  |  |  |     def test_async_contextmanager(self): | 
					
						
							|  |  |  |         class NotACM: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         self.assertIsInstance(ACM(), typing.AsyncContextManager) | 
					
						
							|  |  |  |         self.assertNotIsInstance(NotACM(), typing.AsyncContextManager) | 
					
						
							|  |  |  |         @contextlib.contextmanager | 
					
						
							|  |  |  |         def manager(): | 
					
						
							|  |  |  |             yield 42 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cm = manager() | 
					
						
							|  |  |  |         self.assertNotIsInstance(cm, typing.AsyncContextManager) | 
					
						
							|  |  |  |         self.assertEqual(typing.AsyncContextManager[int].__args__, (int,)) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(42, typing.AsyncContextManager[int]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.AsyncContextManager[int, str] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-17 17:52:05 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-24 16:38:22 -07:00
										 |  |  | class TypeTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_type_basic(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class User: pass | 
					
						
							|  |  |  |         class BasicUser(User): pass | 
					
						
							|  |  |  |         class ProUser(User): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def new_user(user_class: Type[User]) -> User: | 
					
						
							|  |  |  |             return user_class() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-22 17:43:53 -08:00
										 |  |  |         new_user(BasicUser) | 
					
						
							| 
									
										
										
										
											2016-05-24 16:38:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_type_typevar(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class User: pass | 
					
						
							|  |  |  |         class BasicUser(User): pass | 
					
						
							|  |  |  |         class ProUser(User): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         U = TypeVar('U', bound=User) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def new_user(user_class: Type[U]) -> U: | 
					
						
							|  |  |  |             return user_class() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-22 17:43:53 -08:00
										 |  |  |         new_user(BasicUser) | 
					
						
							| 
									
										
										
										
											2016-05-24 16:38:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |     def test_type_optional(self): | 
					
						
							|  |  |  |         A = Optional[Type[BaseException]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(a: A) -> Optional[BaseException]: | 
					
						
							|  |  |  |             if a is None: | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 return a() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         assert isinstance(foo(KeyboardInterrupt), KeyboardInterrupt) | 
					
						
							|  |  |  |         assert foo(None) is None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-24 16:38:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 11:19:11 -07:00
										 |  |  | class NewTypeTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							|  |  |  |         UserId = NewType('UserId', int) | 
					
						
							|  |  |  |         UserName = NewType('UserName', str) | 
					
						
							|  |  |  |         self.assertIsInstance(UserId(5), int) | 
					
						
							|  |  |  |         self.assertIsInstance(UserName('Joe'), str) | 
					
						
							|  |  |  |         self.assertEqual(UserId(5) + 1, 6) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_errors(self): | 
					
						
							|  |  |  |         UserId = NewType('UserId', int) | 
					
						
							|  |  |  |         UserName = NewType('UserName', str) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(UserId, int) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class D(UserName): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class NamedTupleTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2019-10-08 16:29:52 +03:00
										 |  |  |     class NestedEmployee(NamedTuple): | 
					
						
							|  |  |  |         name: str | 
					
						
							|  |  |  |         cool: int | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         Emp = NamedTuple('Emp', [('name', str), ('id', int)]) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(Emp, tuple) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         joe = Emp('Joe', 42) | 
					
						
							|  |  |  |         jim = Emp(name='Jim', id=1) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsInstance(joe, Emp) | 
					
						
							|  |  |  |         self.assertIsInstance(joe, tuple) | 
					
						
							|  |  |  |         self.assertEqual(joe.name, 'Joe') | 
					
						
							|  |  |  |         self.assertEqual(joe.id, 42) | 
					
						
							|  |  |  |         self.assertEqual(jim.name, 'Jim') | 
					
						
							|  |  |  |         self.assertEqual(jim.id, 1) | 
					
						
							|  |  |  |         self.assertEqual(Emp.__name__, 'Emp') | 
					
						
							|  |  |  |         self.assertEqual(Emp._fields, ('name', 'id')) | 
					
						
							| 
									
										
										
										
											2017-01-17 20:43:28 -08:00
										 |  |  |         self.assertEqual(Emp.__annotations__, | 
					
						
							|  |  |  |                          collections.OrderedDict([('name', str), ('id', int)])) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     def test_namedtuple_pyversion(self): | 
					
						
							|  |  |  |         if sys.version_info[:2] < (3, 6): | 
					
						
							|  |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 NamedTuple('Name', one=int, other=str) | 
					
						
							|  |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 class NotYet(NamedTuple): | 
					
						
							|  |  |  |                     whatever = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |     def test_annotation_usage(self): | 
					
						
							|  |  |  |         tim = CoolEmployee('Tim', 9000) | 
					
						
							|  |  |  |         self.assertIsInstance(tim, CoolEmployee) | 
					
						
							|  |  |  |         self.assertIsInstance(tim, tuple) | 
					
						
							|  |  |  |         self.assertEqual(tim.name, 'Tim') | 
					
						
							|  |  |  |         self.assertEqual(tim.cool, 9000) | 
					
						
							|  |  |  |         self.assertEqual(CoolEmployee.__name__, 'CoolEmployee') | 
					
						
							|  |  |  |         self.assertEqual(CoolEmployee._fields, ('name', 'cool')) | 
					
						
							| 
									
										
										
										
											2017-01-17 20:43:28 -08:00
										 |  |  |         self.assertEqual(CoolEmployee.__annotations__, | 
					
						
							|  |  |  |                          collections.OrderedDict(name=str, cool=int)) | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-18 08:03:50 -08:00
										 |  |  |     def test_annotation_usage_with_default(self): | 
					
						
							|  |  |  |         jelle = CoolEmployeeWithDefault('Jelle') | 
					
						
							|  |  |  |         self.assertIsInstance(jelle, CoolEmployeeWithDefault) | 
					
						
							|  |  |  |         self.assertIsInstance(jelle, tuple) | 
					
						
							|  |  |  |         self.assertEqual(jelle.name, 'Jelle') | 
					
						
							|  |  |  |         self.assertEqual(jelle.cool, 0) | 
					
						
							|  |  |  |         cooler_employee = CoolEmployeeWithDefault('Sjoerd', 1) | 
					
						
							|  |  |  |         self.assertEqual(cooler_employee.cool, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(CoolEmployeeWithDefault.__name__, 'CoolEmployeeWithDefault') | 
					
						
							|  |  |  |         self.assertEqual(CoolEmployeeWithDefault._fields, ('name', 'cool')) | 
					
						
							| 
									
										
										
										
											2020-04-05 00:43:20 +03:00
										 |  |  |         self.assertEqual(CoolEmployeeWithDefault.__annotations__, | 
					
						
							|  |  |  |                          dict(name=str, cool=int)) | 
					
						
							| 
									
										
										
										
											2017-01-18 08:03:50 -08:00
										 |  |  |         self.assertEqual(CoolEmployeeWithDefault._field_defaults, dict(cool=0)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2020-04-08 10:59:04 +03:00
										 |  |  |             class NonDefaultAfterDefault(NamedTuple): | 
					
						
							|  |  |  |                 x: int = 3 | 
					
						
							|  |  |  |                 y: int | 
					
						
							| 
									
										
										
										
											2017-01-18 08:03:50 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-22 17:47:20 -08:00
										 |  |  |     def test_annotation_usage_with_methods(self): | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         self.assertEqual(XMeth(1).double(), 2) | 
					
						
							|  |  |  |         self.assertEqual(XMeth(42).x, XMeth(42)[0]) | 
					
						
							|  |  |  |         self.assertEqual(str(XRepr(42)), '42 -> 1') | 
					
						
							|  |  |  |         self.assertEqual(XRepr(1, 2) + XRepr(3), 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(AttributeError): | 
					
						
							| 
									
										
										
										
											2020-04-08 10:59:04 +03:00
										 |  |  |             class XMethBad(NamedTuple): | 
					
						
							|  |  |  |                 x: int | 
					
						
							|  |  |  |                 def _fields(self): | 
					
						
							|  |  |  |                     return 'no chance for this' | 
					
						
							| 
									
										
										
										
											2017-01-22 17:47:20 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  |         with self.assertRaises(AttributeError): | 
					
						
							| 
									
										
										
										
											2020-04-08 10:59:04 +03:00
										 |  |  |             class XMethBad2(NamedTuple): | 
					
						
							|  |  |  |                 x: int | 
					
						
							|  |  |  |                 def _source(self): | 
					
						
							|  |  |  |                     return 'no chance for this as well' | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 21:31:30 +03:00
										 |  |  |     def test_multiple_inheritance(self): | 
					
						
							|  |  |  |         class A: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class X(NamedTuple, A): | 
					
						
							|  |  |  |                 x: int | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-15 09:48:06 -08:00
										 |  |  |     def test_namedtuple_keyword_usage(self): | 
					
						
							|  |  |  |         LocalEmployee = NamedTuple("LocalEmployee", name=str, age=int) | 
					
						
							|  |  |  |         nick = LocalEmployee('Nick', 25) | 
					
						
							|  |  |  |         self.assertIsInstance(nick, tuple) | 
					
						
							|  |  |  |         self.assertEqual(nick.name, 'Nick') | 
					
						
							|  |  |  |         self.assertEqual(LocalEmployee.__name__, 'LocalEmployee') | 
					
						
							|  |  |  |         self.assertEqual(LocalEmployee._fields, ('name', 'age')) | 
					
						
							| 
									
										
										
										
											2017-01-17 20:43:28 -08:00
										 |  |  |         self.assertEqual(LocalEmployee.__annotations__, dict(name=str, age=int)) | 
					
						
							| 
									
										
										
										
											2016-11-15 09:48:06 -08:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NamedTuple('Name', [('x', int)], y=str) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NamedTuple('Name', x=1, y='a') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-17 21:22:00 +03:00
										 |  |  |     def test_namedtuple_special_keyword_names(self): | 
					
						
							|  |  |  |         NT = NamedTuple("NT", cls=type, self=object, typename=str, fields=list) | 
					
						
							|  |  |  |         self.assertEqual(NT.__name__, 'NT') | 
					
						
							|  |  |  |         self.assertEqual(NT._fields, ('cls', 'self', 'typename', 'fields')) | 
					
						
							|  |  |  |         a = NT(cls=str, self=42, typename='foo', fields=[('bar', tuple)]) | 
					
						
							|  |  |  |         self.assertEqual(a.cls, str) | 
					
						
							|  |  |  |         self.assertEqual(a.self, 42) | 
					
						
							|  |  |  |         self.assertEqual(a.typename, 'foo') | 
					
						
							|  |  |  |         self.assertEqual(a.fields, [('bar', tuple)]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_namedtuple_errors(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NamedTuple.__new__() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NamedTuple() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NamedTuple('Emp', [('name', str)], None) | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             NamedTuple('Emp', [('_name', str)]) | 
					
						
							| 
									
										
										
										
											2019-09-17 22:41:55 +03:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NamedTuple(typename='Emp', name=str, id=int) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NamedTuple('Emp', fields=[('name', str), ('id', int)]) | 
					
						
							| 
									
										
										
										
											2019-09-17 21:22:00 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 16:29:52 +03:00
										 |  |  |     def test_copy_and_pickle(self): | 
					
						
							| 
									
										
										
										
											2015-11-19 08:16:31 -08:00
										 |  |  |         global Emp  # pickle wants to reference the class by name | 
					
						
							| 
									
										
										
										
											2019-10-08 16:29:52 +03:00
										 |  |  |         Emp = NamedTuple('Emp', [('name', str), ('cool', int)]) | 
					
						
							|  |  |  |         for cls in Emp, CoolEmployee, self.NestedEmployee: | 
					
						
							|  |  |  |             with self.subTest(cls=cls): | 
					
						
							|  |  |  |                 jane = cls('jane', 37) | 
					
						
							|  |  |  |                 for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |                     z = pickle.dumps(jane, proto) | 
					
						
							|  |  |  |                     jane2 = pickle.loads(z) | 
					
						
							|  |  |  |                     self.assertEqual(jane2, jane) | 
					
						
							|  |  |  |                     self.assertIsInstance(jane2, cls) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 jane2 = copy(jane) | 
					
						
							|  |  |  |                 self.assertEqual(jane2, jane) | 
					
						
							|  |  |  |                 self.assertIsInstance(jane2, cls) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 jane2 = deepcopy(jane) | 
					
						
							|  |  |  |                 self.assertEqual(jane2, jane) | 
					
						
							|  |  |  |                 self.assertIsInstance(jane2, cls) | 
					
						
							| 
									
										
										
										
											2015-11-19 08:16:31 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  | 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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-17 21:22:00 +03:00
										 |  |  |     def test_typeddict_special_keyword_names(self): | 
					
						
							|  |  |  |         TD = TypedDict("TD", cls=type, self=object, typename=str, _typename=int, fields=list, _fields=dict) | 
					
						
							|  |  |  |         self.assertEqual(TD.__name__, 'TD') | 
					
						
							|  |  |  |         self.assertEqual(TD.__annotations__, {'cls': type, 'self': object, 'typename': str, '_typename': int, 'fields': list, '_fields': dict}) | 
					
						
							|  |  |  |         a = TD(cls=str, self=42, typename='foo', _typename=53, fields=[('bar', tuple)], _fields={'baz', set}) | 
					
						
							|  |  |  |         self.assertEqual(a['cls'], str) | 
					
						
							|  |  |  |         self.assertEqual(a['self'], 42) | 
					
						
							|  |  |  |         self.assertEqual(a['typename'], 'foo') | 
					
						
							|  |  |  |         self.assertEqual(a['_typename'], 53) | 
					
						
							|  |  |  |         self.assertEqual(a['fields'], [('bar', tuple)]) | 
					
						
							|  |  |  |         self.assertEqual(a['_fields'], {'baz', set}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_typeddict_create_errors(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypedDict.__new__() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypedDict() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypedDict('Emp', [('name', str)], None) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-17 22:41:55 +03:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypedDict(_typename='Emp', name=str, id=int) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypedDict('Emp', _fields={'name': str, 'id': int}) | 
					
						
							| 
									
										
										
										
											2019-09-17 21:22:00 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  |     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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-24 21:48:48 +11:00
										 |  |  |     def test_optional_keys(self): | 
					
						
							|  |  |  |         class Point2Dor3D(Point2D, total=False): | 
					
						
							|  |  |  |             z: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         assert Point2Dor3D.__required_keys__ == frozenset(['x', 'y']) | 
					
						
							|  |  |  |         assert Point2Dor3D.__optional_keys__ == frozenset(['z']) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-13 20:53:29 +01:00
										 |  |  |     def test_keys_inheritance(self): | 
					
						
							|  |  |  |         class BaseAnimal(TypedDict): | 
					
						
							|  |  |  |             name: str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Animal(BaseAnimal, total=False): | 
					
						
							|  |  |  |             voice: str | 
					
						
							|  |  |  |             tail: bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Cat(Animal): | 
					
						
							|  |  |  |             fur_color: str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         assert BaseAnimal.__required_keys__ == frozenset(['name']) | 
					
						
							|  |  |  |         assert BaseAnimal.__optional_keys__ == frozenset([]) | 
					
						
							|  |  |  |         assert BaseAnimal.__annotations__ == {'name': str} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         assert Animal.__required_keys__ == frozenset(['name']) | 
					
						
							|  |  |  |         assert Animal.__optional_keys__ == frozenset(['tail', 'voice']) | 
					
						
							|  |  |  |         assert Animal.__annotations__ == { | 
					
						
							|  |  |  |             'name': str, | 
					
						
							|  |  |  |             'tail': bool, | 
					
						
							|  |  |  |             'voice': str, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         assert Cat.__required_keys__ == frozenset(['name', 'fur_color']) | 
					
						
							|  |  |  |         assert Cat.__optional_keys__ == frozenset(['tail', 'voice']) | 
					
						
							|  |  |  |         assert Cat.__annotations__ == { | 
					
						
							|  |  |  |             'fur_color': str, | 
					
						
							|  |  |  |             'name': str, | 
					
						
							|  |  |  |             'tail': bool, | 
					
						
							|  |  |  |             'voice': str, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class IOTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_io(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def stuff(a: IO) -> AnyStr: | 
					
						
							|  |  |  |             return a.readline() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         a = stuff.__annotations__['a'] | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(a.__parameters__, (AnyStr,)) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_textio(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def stuff(a: TextIO) -> str: | 
					
						
							|  |  |  |             return a.readline() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         a = stuff.__annotations__['a'] | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(a.__parameters__, ()) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_binaryio(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def stuff(a: BinaryIO) -> bytes: | 
					
						
							|  |  |  |             return a.readline() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         a = stuff.__annotations__['a'] | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(a.__parameters__, ()) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_io_submodule(self): | 
					
						
							|  |  |  |         from typing.io import IO, TextIO, BinaryIO, __all__, __name__ | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIs(IO, typing.IO) | 
					
						
							|  |  |  |         self.assertIs(TextIO, typing.TextIO) | 
					
						
							|  |  |  |         self.assertIs(BinaryIO, typing.BinaryIO) | 
					
						
							|  |  |  |         self.assertEqual(set(__all__), set(['IO', 'TextIO', 'BinaryIO'])) | 
					
						
							|  |  |  |         self.assertEqual(__name__, 'typing.io') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class RETests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     # Much of this is really testing _TypeAlias. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         pat = re.compile('[a-z]+', re.I) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(pat.__class__, Pattern) | 
					
						
							|  |  |  |         self.assertIsSubclass(type(pat), Pattern) | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         self.assertIsInstance(pat, Pattern) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         mat = pat.search('12345abcde.....') | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIsSubclass(mat.__class__, Match) | 
					
						
							|  |  |  |         self.assertIsSubclass(type(mat), Match) | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         self.assertIsInstance(mat, Match) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         # these should just work | 
					
						
							| 
									
										
										
										
											2017-01-22 17:43:53 -08:00
										 |  |  |         Pattern[Union[str, bytes]] | 
					
						
							|  |  |  |         Match[Union[bytes, str]] | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     def test_alias_equality(self): | 
					
						
							|  |  |  |         self.assertEqual(Pattern[str], Pattern[str]) | 
					
						
							|  |  |  |         self.assertNotEqual(Pattern[str], Pattern[bytes]) | 
					
						
							|  |  |  |         self.assertNotEqual(Pattern[str], Match[str]) | 
					
						
							|  |  |  |         self.assertNotEqual(Pattern[str], str) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_errors(self): | 
					
						
							|  |  |  |         m = Match[Union[str, bytes]] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             m[str] | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             # We don't support isinstance(). | 
					
						
							|  |  |  |             isinstance(42, Pattern[str]) | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             # We don't support issubclass(). | 
					
						
							|  |  |  |             issubclass(Pattern[bytes], Pattern[str]) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |         self.assertEqual(repr(Pattern), 'typing.Pattern') | 
					
						
							|  |  |  |         self.assertEqual(repr(Pattern[str]), 'typing.Pattern[str]') | 
					
						
							|  |  |  |         self.assertEqual(repr(Pattern[bytes]), 'typing.Pattern[bytes]') | 
					
						
							|  |  |  |         self.assertEqual(repr(Match), 'typing.Match') | 
					
						
							|  |  |  |         self.assertEqual(repr(Match[str]), 'typing.Match[str]') | 
					
						
							|  |  |  |         self.assertEqual(repr(Match[bytes]), 'typing.Match[bytes]') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_re_submodule(self): | 
					
						
							|  |  |  |         from typing.re import Match, Pattern, __all__, __name__ | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIs(Match, typing.Match) | 
					
						
							|  |  |  |         self.assertIs(Pattern, typing.Pattern) | 
					
						
							|  |  |  |         self.assertEqual(set(__all__), set(['Match', 'Pattern'])) | 
					
						
							|  |  |  |         self.assertEqual(__name__, 'typing.re') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError) as ex: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             class A(typing.Match): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(str(ex.exception), | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  |                          "type 're.Match' is not an acceptable base type") | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  | class AnnotatedTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             repr(Annotated[int, 4, 5]), | 
					
						
							|  |  |  |             "typing.Annotated[int, 4, 5]" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             repr(Annotated[List[int], 4, 5]), | 
					
						
							|  |  |  |             "typing.Annotated[typing.List[int], 4, 5]" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_flatten(self): | 
					
						
							|  |  |  |         A = Annotated[Annotated[int, 4], 5] | 
					
						
							|  |  |  |         self.assertEqual(A, Annotated[int, 4, 5]) | 
					
						
							|  |  |  |         self.assertEqual(A.__metadata__, (4, 5)) | 
					
						
							|  |  |  |         self.assertEqual(A.__origin__, int) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_specialize(self): | 
					
						
							|  |  |  |         L = Annotated[List[T], "my decoration"] | 
					
						
							|  |  |  |         LI = Annotated[List[int], "my decoration"] | 
					
						
							|  |  |  |         self.assertEqual(L[int], Annotated[List[int], "my decoration"]) | 
					
						
							|  |  |  |         self.assertEqual(L[int].__metadata__, ("my decoration",)) | 
					
						
							|  |  |  |         self.assertEqual(L[int].__origin__, List[int]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             LI[int] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             L[int, float] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_hash_eq(self): | 
					
						
							|  |  |  |         self.assertEqual(len({Annotated[int, 4, 5], Annotated[int, 4, 5]}), 1) | 
					
						
							|  |  |  |         self.assertNotEqual(Annotated[int, 4, 5], Annotated[int, 5, 4]) | 
					
						
							|  |  |  |         self.assertNotEqual(Annotated[int, 4, 5], Annotated[str, 4, 5]) | 
					
						
							|  |  |  |         self.assertNotEqual(Annotated[int, 4], Annotated[int, 4, 4]) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             {Annotated[int, 4, 5], Annotated[int, 4, 5], Annotated[T, 4, 5]}, | 
					
						
							|  |  |  |             {Annotated[int, 4, 5], Annotated[T, 4, 5]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_instantiate(self): | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             classvar = 4 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def __init__(self, x): | 
					
						
							|  |  |  |                 self.x = x | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             def __eq__(self, other): | 
					
						
							|  |  |  |                 if not isinstance(other, C): | 
					
						
							|  |  |  |                     return NotImplemented | 
					
						
							|  |  |  |                 return other.x == self.x | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A = Annotated[C, "a decoration"] | 
					
						
							|  |  |  |         a = A(5) | 
					
						
							|  |  |  |         c = C(5) | 
					
						
							|  |  |  |         self.assertEqual(a, c) | 
					
						
							|  |  |  |         self.assertEqual(a.x, c.x) | 
					
						
							|  |  |  |         self.assertEqual(a.classvar, c.classvar) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_instantiate_generic(self): | 
					
						
							|  |  |  |         MyCount = Annotated[typing.Counter[T], "my decoration"] | 
					
						
							|  |  |  |         self.assertEqual(MyCount([4, 4, 5]), {4: 2, 5: 1}) | 
					
						
							|  |  |  |         self.assertEqual(MyCount[int]([4, 4, 5]), {4: 2, 5: 1}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_instantiate_forward(self): | 
					
						
							|  |  |  |         A = Annotated["int", (5, 6)] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             A(5) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_instantiate_type_var(self): | 
					
						
							|  |  |  |         A = Annotated[T, (5, 6)] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             A(5) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_getattr_typevar(self): | 
					
						
							|  |  |  |         with self.assertRaises(AttributeError): | 
					
						
							|  |  |  |             Annotated[T, (5, 7)].x | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_attr_passthrough(self): | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             classvar = 4 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A = Annotated[C, "a decoration"] | 
					
						
							|  |  |  |         self.assertEqual(A.classvar, 4) | 
					
						
							|  |  |  |         A.x = 5 | 
					
						
							|  |  |  |         self.assertEqual(C.x, 5) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_hash_eq(self): | 
					
						
							|  |  |  |         self.assertEqual(len({Annotated[int, 4, 5], Annotated[int, 4, 5]}), 1) | 
					
						
							|  |  |  |         self.assertNotEqual(Annotated[int, 4, 5], Annotated[int, 5, 4]) | 
					
						
							|  |  |  |         self.assertNotEqual(Annotated[int, 4, 5], Annotated[str, 4, 5]) | 
					
						
							|  |  |  |         self.assertNotEqual(Annotated[int, 4], Annotated[int, 4, 4]) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             {Annotated[int, 4, 5], Annotated[int, 4, 5], Annotated[T, 4, 5]}, | 
					
						
							|  |  |  |             {Annotated[int, 4, 5], Annotated[T, 4, 5]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, "Cannot subclass .*Annotated"): | 
					
						
							|  |  |  |             class C(Annotated): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_check_instance(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(5, Annotated[int, "positive"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_check_subclass(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, Annotated[int, "positive"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_pickle(self): | 
					
						
							|  |  |  |         samples = [typing.Any, typing.Union[int, str], | 
					
						
							|  |  |  |                    typing.Optional[str], Tuple[int, ...], | 
					
						
							|  |  |  |                    typing.Callable[[str], bytes]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for t in samples: | 
					
						
							|  |  |  |             x = Annotated[t, "a"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for prot in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |                 with self.subTest(protocol=prot, type=t): | 
					
						
							|  |  |  |                     pickled = pickle.dumps(x, prot) | 
					
						
							|  |  |  |                     restored = pickle.loads(pickled) | 
					
						
							|  |  |  |                     self.assertEqual(x, restored) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         global _Annotated_test_G | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class _Annotated_test_G(Generic[T]): | 
					
						
							|  |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         G = Annotated[_Annotated_test_G[int], "A decoration"] | 
					
						
							|  |  |  |         G.foo = 42 | 
					
						
							|  |  |  |         G.bar = 'abc' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |             z = pickle.dumps(G, proto) | 
					
						
							|  |  |  |             x = pickle.loads(z) | 
					
						
							|  |  |  |             self.assertEqual(x.foo, 42) | 
					
						
							|  |  |  |             self.assertEqual(x.bar, 'abc') | 
					
						
							|  |  |  |             self.assertEqual(x.x, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_subst(self): | 
					
						
							|  |  |  |         dec = "a decoration" | 
					
						
							|  |  |  |         dec2 = "another decoration" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         S = Annotated[T, dec2] | 
					
						
							|  |  |  |         self.assertEqual(S[int], Annotated[int, dec2]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(S[Annotated[int, dec]], Annotated[int, dec, dec2]) | 
					
						
							|  |  |  |         L = Annotated[List[T], dec] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(L[int], Annotated[List[int], dec]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             L[int, int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(S[L[int]], Annotated[List[int], dec, dec2]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         D = Annotated[typing.Dict[KT, VT], dec] | 
					
						
							|  |  |  |         self.assertEqual(D[str, int], Annotated[typing.Dict[str, int], dec]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             D[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         It = Annotated[int, dec] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             It[None] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         LI = L[int] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             LI[None] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_annotated_in_other_types(self): | 
					
						
							|  |  |  |         X = List[Annotated[T, 5]] | 
					
						
							|  |  |  |         self.assertEqual(X[int], List[Annotated[int, 5]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class AllTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     """Tests for __all__.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_all(self): | 
					
						
							|  |  |  |         from typing import __all__ as a | 
					
						
							|  |  |  |         # Just spot-check the first and last of every category. | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIn('AbstractSet', a) | 
					
						
							|  |  |  |         self.assertIn('ValuesView', a) | 
					
						
							|  |  |  |         self.assertIn('cast', a) | 
					
						
							|  |  |  |         self.assertIn('overload', a) | 
					
						
							| 
									
										
										
										
											2016-04-17 17:52:05 -07:00
										 |  |  |         if hasattr(contextlib, 'AbstractContextManager'): | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |             self.assertIn('ContextManager', a) | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |         # Check that io and re are not exported. | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertNotIn('io', a) | 
					
						
							|  |  |  |         self.assertNotIn('re', a) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         # Spot-check that stdlib modules aren't exported. | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertNotIn('os', a) | 
					
						
							|  |  |  |         self.assertNotIn('sys', a) | 
					
						
							| 
									
										
										
										
											2016-04-17 17:52:05 -07:00
										 |  |  |         # Check that Text is defined. | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertIn('Text', a) | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  |         # Check previously missing classes. | 
					
						
							|  |  |  |         self.assertIn('SupportsBytes', a) | 
					
						
							|  |  |  |         self.assertIn('SupportsComplex', a) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-29 11:19:38 -07:00
										 |  |  |     def test_all_exported_names(self): | 
					
						
							|  |  |  |         import typing | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         actual_all = set(typing.__all__) | 
					
						
							|  |  |  |         computed_all = { | 
					
						
							|  |  |  |             k for k, v in vars(typing).items() | 
					
						
							|  |  |  |             # explicitly exported, not a thing with __module__ | 
					
						
							|  |  |  |             if k in actual_all or ( | 
					
						
							|  |  |  |                 # avoid private names | 
					
						
							|  |  |  |                 not k.startswith('_') and | 
					
						
							|  |  |  |                 # avoid things in the io / re typing submodules | 
					
						
							|  |  |  |                 k not in typing.io.__all__ and | 
					
						
							|  |  |  |                 k not in typing.re.__all__ and | 
					
						
							|  |  |  |                 k not in {'io', 're'} and | 
					
						
							|  |  |  |                 # there's a few types and metaclasses that aren't exported | 
					
						
							|  |  |  |                 not k.endswith(('Meta', '_contra', '_co')) and | 
					
						
							|  |  |  |                 not k.upper() == k and | 
					
						
							|  |  |  |                 # but export all things that have __module__ == 'typing' | 
					
						
							|  |  |  |                 getattr(v, '__module__', None) == typing.__name__ | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         self.assertSetEqual(computed_all, actual_all) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     main() |