| 
									
										
										
										
											2016-04-17 17:52:05 -07:00
										 |  |  | import contextlib | 
					
						
							| 
									
										
										
										
											2016-05-18 08:35:00 -07:00
										 |  |  | import collections | 
					
						
							| 
									
										
										
										
											2022-04-16 09:01:43 -07:00
										 |  |  | from collections import defaultdict | 
					
						
							| 
									
										
										
										
											2022-04-22 05:22:53 +01:00
										 |  |  | from functools import lru_cache, wraps | 
					
						
							| 
									
										
										
										
											2022-01-12 11:38:25 -08:00
										 |  |  | import inspect | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  | import itertools | 
					
						
							| 
									
										
										
										
											2015-11-18 21:12:58 -08:00
										 |  |  | import pickle | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | import re | 
					
						
							|  |  |  | import sys | 
					
						
							| 
									
										
										
										
											2021-06-19 19:31:18 +02:00
										 |  |  | import warnings | 
					
						
							| 
									
										
										
										
											2020-04-30 01:48:37 +02:00
										 |  |  | from unittest import TestCase, main, skipUnless, skip | 
					
						
							| 
									
										
										
										
											2022-04-16 09:01:43 -07:00
										 |  |  | from unittest.mock import patch | 
					
						
							| 
									
										
										
										
											2016-10-29 12:44:29 -07:00
										 |  |  | from copy import copy, deepcopy | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  | from typing import Any, NoReturn, Never, assert_never | 
					
						
							| 
									
										
										
										
											2022-04-16 09:01:43 -07:00
										 |  |  | from typing import overload, get_overloads, clear_overloads | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | from typing import TypeVar, TypeVarTuple, Unpack, AnyStr | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | from typing import T, KT, VT  # Not in __all__. | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:48 +01:00
										 |  |  | from typing import Union, Optional, Literal | 
					
						
							| 
									
										
										
										
											2020-05-10 13:39:40 +03:00
										 |  |  | from typing import Tuple, List, Dict, 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 | 
					
						
							| 
									
										
										
										
											2022-03-16 20:02:26 -07:00
										 |  |  | from typing import assert_type, 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 | 
					
						
							| 
									
										
										
										
											2023-02-27 13:16:11 -08:00
										 |  |  | from typing import override | 
					
						
							| 
									
										
										
										
											2020-09-16 05:58:32 +01:00
										 |  |  | from typing import is_typeddict | 
					
						
							| 
									
										
										
										
											2022-02-01 18:48:55 -08:00
										 |  |  | from typing import reveal_type | 
					
						
							| 
									
										
										
										
											2022-04-25 20:30:25 -07:00
										 |  |  | from typing import dataclass_transform | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  | from typing import NamedTuple, NotRequired, Required, TypedDict | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | from typing import IO, TextIO, BinaryIO | 
					
						
							|  |  |  | from typing import Pattern, Match | 
					
						
							| 
									
										
										
										
											2020-04-26 21:21:08 +03:00
										 |  |  | from typing import Annotated, ForwardRef | 
					
						
							| 
									
										
										
										
											2022-04-05 07:21:03 -07:00
										 |  |  | from typing import Self, LiteralString | 
					
						
							| 
									
										
										
										
											2020-10-08 00:44:31 +03:00
										 |  |  | from typing import TypeAlias | 
					
						
							| 
									
										
										
										
											2021-04-10 19:57:05 -07:00
										 |  |  | from typing import ParamSpec, Concatenate, ParamSpecArgs, ParamSpecKwargs | 
					
						
							| 
									
										
										
										
											2021-04-27 22:31:04 +08:00
										 |  |  | from typing import TypeGuard | 
					
						
							| 
									
										
										
										
											2016-10-08 20:27:22 -07:00
										 |  |  | import abc | 
					
						
							| 
									
										
										
										
											2022-03-07 19:02:59 +01:00
										 |  |  | import textwrap | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-26 16:15:39 +03:00
										 |  |  | from test.support import import_helper, captured_stderr, cpython_only | 
					
						
							| 
									
										
										
										
											2018-01-20 11:23:59 +00:00
										 |  |  | from test import mod_generics_cache | 
					
						
							| 
									
										
										
										
											2021-07-16 20:49:30 -07:00
										 |  |  | from test import _typed_dict_helper | 
					
						
							| 
									
										
										
										
											2017-12-05 03:43:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  | CANNOT_SUBCLASS_TYPE = 'Cannot subclass special typing classes' | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  | NOT_A_BASE_TYPE = "type 'typing.%s' is not an acceptable base type" | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  | CANNOT_SUBCLASS_INSTANCE = 'Cannot subclass an instance of %s' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-22 05:22:53 +01:00
										 |  |  | def all_pickle_protocols(test_func): | 
					
						
							|  |  |  |     """Runs `test_func` with various values for `proto` argument.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @wraps(test_func) | 
					
						
							|  |  |  |     def wrapper(self): | 
					
						
							|  |  |  |         for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |             with self.subTest(pickle_proto=proto): | 
					
						
							|  |  |  |                 test_func(self, proto=proto) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return wrapper | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(Any), 'typing.Any') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-30 20:36:16 +03:00
										 |  |  |         class Sub(Any): pass | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             repr(Sub), | 
					
						
							| 
									
										
										
										
											2023-05-01 16:42:59 +03:00
										 |  |  |             f"<class '{__name__}.AnyTests.test_repr.<locals>.Sub'>", | 
					
						
							| 
									
										
										
										
											2022-08-30 20:36:16 +03:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_errors(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(42, Any) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Any[int]  # Any is not a generic type. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-04 19:35:29 -07:00
										 |  |  |     def test_can_subclass(self): | 
					
						
							|  |  |  |         class Mock(Any): pass | 
					
						
							|  |  |  |         self.assertTrue(issubclass(Mock, Any)) | 
					
						
							|  |  |  |         self.assertIsInstance(Mock(), Mock) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Something: pass | 
					
						
							|  |  |  |         self.assertFalse(issubclass(Something, Any)) | 
					
						
							|  |  |  |         self.assertNotIsInstance(Something(), Mock) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MockSomething(Something, Mock): pass | 
					
						
							|  |  |  |         self.assertTrue(issubclass(MockSomething, Any)) | 
					
						
							|  |  |  |         ms = MockSomething() | 
					
						
							|  |  |  |         self.assertIsInstance(ms, MockSomething) | 
					
						
							|  |  |  |         self.assertIsInstance(ms, Something) | 
					
						
							|  |  |  |         self.assertIsInstance(ms, Mock) | 
					
						
							| 
									
										
										
										
											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] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  | class BottomTypeTestsMixin: | 
					
						
							|  |  |  |     bottom_type: ClassVar[Any] | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 04:56:30 +03:00
										 |  |  |     def test_equality(self): | 
					
						
							|  |  |  |         self.assertEqual(self.bottom_type, self.bottom_type) | 
					
						
							|  |  |  |         self.assertIs(self.bottom_type, self.bottom_type) | 
					
						
							|  |  |  |         self.assertNotEqual(self.bottom_type, None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_origin(self): | 
					
						
							|  |  |  |         self.assertIs(get_origin(self.bottom_type), None) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  |     def test_instance_type_error(self): | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  |             isinstance(42, self.bottom_type) | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  |     def test_subclass_type_error(self): | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  |             issubclass(Employee, self.bottom_type) | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  |             issubclass(NoReturn, self.bottom_type) | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_not_generic(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  |             self.bottom_type[int] | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 'Cannot subclass ' + re.escape(str(self.bottom_type))): | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  |             class A(self.bottom_type): | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  |             class A(type(self.bottom_type)): | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_instantiate(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  |             self.bottom_type() | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  |             type(self.bottom_type)() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NoReturnTests(BottomTypeTestsMixin, BaseTestCase): | 
					
						
							|  |  |  |     bottom_type = NoReturn | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(NoReturn), 'typing.NoReturn') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 04:56:30 +03:00
										 |  |  |     def test_get_type_hints(self): | 
					
						
							|  |  |  |         def some(arg: NoReturn) -> NoReturn: ... | 
					
						
							|  |  |  |         def some_str(arg: 'NoReturn') -> 'typing.NoReturn': ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expected = {'arg': NoReturn, 'return': NoReturn} | 
					
						
							|  |  |  |         for target in [some, some_str]: | 
					
						
							|  |  |  |             with self.subTest(target=target): | 
					
						
							|  |  |  |                 self.assertEqual(gth(target), expected) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_not_equality(self): | 
					
						
							|  |  |  |         self.assertNotEqual(NoReturn, Never) | 
					
						
							|  |  |  |         self.assertNotEqual(Never, NoReturn) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class NeverTests(BottomTypeTestsMixin, BaseTestCase): | 
					
						
							|  |  |  |     bottom_type = Never | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(Never), 'typing.Never') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 04:56:30 +03:00
										 |  |  |     def test_get_type_hints(self): | 
					
						
							|  |  |  |         def some(arg: Never) -> Never: ... | 
					
						
							|  |  |  |         def some_str(arg: 'Never') -> 'typing.Never': ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expected = {'arg': Never, 'return': Never} | 
					
						
							|  |  |  |         for target in [some, some_str]: | 
					
						
							|  |  |  |             with self.subTest(target=target): | 
					
						
							|  |  |  |                 self.assertEqual(gth(target), expected) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 10:50:26 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class AssertNeverTests(BaseTestCase): | 
					
						
							|  |  |  |     def test_exception(self): | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError): | 
					
						
							|  |  |  |             assert_never(None) | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-25 06:40:18 -07:00
										 |  |  |         value = "some value" | 
					
						
							|  |  |  |         with self.assertRaisesRegex(AssertionError, value): | 
					
						
							|  |  |  |             assert_never(value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Make sure a huge value doesn't get printed in its entirety | 
					
						
							|  |  |  |         huge_value = "a" * 10000 | 
					
						
							|  |  |  |         with self.assertRaises(AssertionError) as cm: | 
					
						
							|  |  |  |             assert_never(huge_value) | 
					
						
							|  |  |  |         self.assertLess( | 
					
						
							|  |  |  |             len(cm.exception.args[0]), | 
					
						
							|  |  |  |             typing._ASSERT_NEVER_REPR_MAX_LENGTH * 2, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-02 19:14:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 20:47:48 +00:00
										 |  |  | class SelfTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2022-02-19 04:56:30 +03:00
										 |  |  |     def test_equality(self): | 
					
						
							|  |  |  |         self.assertEqual(Self, Self) | 
					
						
							|  |  |  |         self.assertIs(Self, Self) | 
					
						
							|  |  |  |         self.assertNotEqual(Self, None) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 20:47:48 +00:00
										 |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         class Foo: | 
					
						
							|  |  |  |             def bar(self) -> Self: ... | 
					
						
							| 
									
										
										
										
											2022-02-19 04:56:30 +03:00
										 |  |  |         class FooStr: | 
					
						
							|  |  |  |             def bar(self) -> 'Self': ... | 
					
						
							|  |  |  |         class FooStrTyping: | 
					
						
							|  |  |  |             def bar(self) -> 'typing.Self': ... | 
					
						
							| 
									
										
										
										
											2022-02-07 20:47:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 04:56:30 +03:00
										 |  |  |         for target in [Foo, FooStr, FooStrTyping]: | 
					
						
							|  |  |  |             with self.subTest(target=target): | 
					
						
							|  |  |  |                 self.assertEqual(gth(target.bar), {'return': Self}) | 
					
						
							|  |  |  |         self.assertIs(get_origin(Self), None) | 
					
						
							| 
									
										
										
										
											2022-02-07 20:47:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(Self), 'typing.Self') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subscript(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Self[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2022-02-07 20:47:48 +00:00
										 |  |  |             class C(type(Self)): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 r'Cannot subclass typing\.Self'): | 
					
						
							| 
									
										
										
										
											2022-02-19 04:56:30 +03:00
										 |  |  |             class C(Self): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 20:47:48 +00:00
										 |  |  |     def test_cannot_init(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Self() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(Self)() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_isinstance(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(1, Self) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, Self) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_alias(self): | 
					
						
							|  |  |  |         # TypeAliases are not actually part of the spec | 
					
						
							|  |  |  |         alias_1 = Tuple[Self, Self] | 
					
						
							|  |  |  |         alias_2 = List[Self] | 
					
						
							|  |  |  |         alias_3 = ClassVar[Self] | 
					
						
							|  |  |  |         self.assertEqual(get_args(alias_1), (Self, Self)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(alias_2), (Self,)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(alias_3), (Self,)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 07:21:03 -07:00
										 |  |  | class LiteralStringTests(BaseTestCase): | 
					
						
							|  |  |  |     def test_equality(self): | 
					
						
							|  |  |  |         self.assertEqual(LiteralString, LiteralString) | 
					
						
							|  |  |  |         self.assertIs(LiteralString, LiteralString) | 
					
						
							|  |  |  |         self.assertNotEqual(LiteralString, None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         class Foo: | 
					
						
							|  |  |  |             def bar(self) -> LiteralString: ... | 
					
						
							|  |  |  |         class FooStr: | 
					
						
							|  |  |  |             def bar(self) -> 'LiteralString': ... | 
					
						
							|  |  |  |         class FooStrTyping: | 
					
						
							|  |  |  |             def bar(self) -> 'typing.LiteralString': ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for target in [Foo, FooStr, FooStrTyping]: | 
					
						
							|  |  |  |             with self.subTest(target=target): | 
					
						
							|  |  |  |                 self.assertEqual(gth(target.bar), {'return': LiteralString}) | 
					
						
							|  |  |  |         self.assertIs(get_origin(LiteralString), None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(LiteralString), 'typing.LiteralString') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subscript(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             LiteralString[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2022-04-05 07:21:03 -07:00
										 |  |  |             class C(type(LiteralString)): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 r'Cannot subclass typing\.LiteralString'): | 
					
						
							| 
									
										
										
										
											2022-04-05 07:21:03 -07:00
										 |  |  |             class C(LiteralString): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_init(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             LiteralString() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(LiteralString)() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_isinstance(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(1, LiteralString) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, LiteralString) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_alias(self): | 
					
						
							|  |  |  |         alias_1 = Tuple[LiteralString, LiteralString] | 
					
						
							|  |  |  |         alias_2 = List[LiteralString] | 
					
						
							|  |  |  |         alias_3 = ClassVar[LiteralString] | 
					
						
							|  |  |  |         self.assertEqual(get_args(alias_1), (LiteralString, LiteralString)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(alias_2), (LiteralString,)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(alias_3), (LiteralString,)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 20:47:48 +00: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) | 
					
						
							| 
									
										
										
										
											2023-05-17 06:08:21 -07:00
										 |  |  |         self.assertEqual(T.__name__, 'T') | 
					
						
							|  |  |  |         self.assertEqual(T.__constraints__, ()) | 
					
						
							|  |  |  |         self.assertIs(T.__bound__, None) | 
					
						
							|  |  |  |         self.assertIs(T.__covariant__, False) | 
					
						
							|  |  |  |         self.assertIs(T.__contravariant__, False) | 
					
						
							|  |  |  |         self.assertIs(T.__infer_variance__, False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_attributes(self): | 
					
						
							|  |  |  |         T_bound = TypeVar('T_bound', bound=int) | 
					
						
							|  |  |  |         self.assertEqual(T_bound.__name__, 'T_bound') | 
					
						
							|  |  |  |         self.assertEqual(T_bound.__constraints__, ()) | 
					
						
							|  |  |  |         self.assertIs(T_bound.__bound__, int) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         T_constraints = TypeVar('T_constraints', int, str) | 
					
						
							|  |  |  |         self.assertEqual(T_constraints.__name__, 'T_constraints') | 
					
						
							|  |  |  |         self.assertEqual(T_constraints.__constraints__, (int, str)) | 
					
						
							|  |  |  |         self.assertIs(T_constraints.__bound__, None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         T_co = TypeVar('T_co', covariant=True) | 
					
						
							|  |  |  |         self.assertEqual(T_co.__name__, 'T_co') | 
					
						
							|  |  |  |         self.assertIs(T_co.__covariant__, True) | 
					
						
							|  |  |  |         self.assertIs(T_co.__contravariant__, False) | 
					
						
							|  |  |  |         self.assertIs(T_co.__infer_variance__, False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         T_contra = TypeVar('T_contra', contravariant=True) | 
					
						
							|  |  |  |         self.assertEqual(T_contra.__name__, 'T_contra') | 
					
						
							|  |  |  |         self.assertIs(T_contra.__covariant__, False) | 
					
						
							|  |  |  |         self.assertIs(T_contra.__contravariant__, True) | 
					
						
							|  |  |  |         self.assertIs(T_contra.__infer_variance__, False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         T_infer = TypeVar('T_infer', infer_variance=True) | 
					
						
							|  |  |  |         self.assertEqual(T_infer.__name__, 'T_infer') | 
					
						
							|  |  |  |         self.assertIs(T_infer.__covariant__, False) | 
					
						
							|  |  |  |         self.assertIs(T_infer.__contravariant__, False) | 
					
						
							|  |  |  |         self.assertIs(T_infer.__infer_variance__, True) | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-10 20:00:05 -07:00
										 |  |  |     def test_or(self): | 
					
						
							|  |  |  |         X = TypeVar('X') | 
					
						
							|  |  |  |         # use a string because str doesn't implement | 
					
						
							|  |  |  |         # __or__/__ror__ itself | 
					
						
							|  |  |  |         self.assertEqual(X | "x", Union[X, "x"]) | 
					
						
							|  |  |  |         self.assertEqual("x" | X, Union["x", X]) | 
					
						
							|  |  |  |         # make sure the order is correct | 
					
						
							|  |  |  |         self.assertEqual(get_args(X | "x"), (X, ForwardRef("x"))) | 
					
						
							|  |  |  |         self.assertEqual(get_args("x" | X), (ForwardRef("x"), X)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |     def test_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |         with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'TypeVar'): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |             class V(TypeVar): pass | 
					
						
							|  |  |  |         T = TypeVar("T") | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 CANNOT_SUBCLASS_INSTANCE % 'TypeVar'): | 
					
						
							|  |  |  |             class V(T): pass | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_instantiate_vars(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypeVar('A')() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_bound_errors(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-03-11 17:12:17 -08:00
										 |  |  |             TypeVar('X', bound=Union) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypeVar('X', str, float, bound=Employee) | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                                     r"Bound must be a type\. Got \(1, 2\)\."): | 
					
						
							|  |  |  |             TypeVar('X', bound=(1, 2)) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-17 06:08:21 -07:00
										 |  |  |     def test_cannot_combine_explicit_and_infer(self): | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             TypeVar('T', covariant=True, infer_variance=True) | 
					
						
							|  |  |  |         with self.assertRaises(ValueError): | 
					
						
							|  |  |  |             TypeVar('T', contravariant=True, infer_variance=True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 10:47:26 +02:00
										 |  |  |     def test_var_substitution(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         subst = T.__typing_subst__ | 
					
						
							|  |  |  |         self.assertIs(subst(int), int) | 
					
						
							|  |  |  |         self.assertEqual(subst(list[int]), list[int]) | 
					
						
							|  |  |  |         self.assertEqual(subst(List[int]), List[int]) | 
					
						
							|  |  |  |         self.assertEqual(subst(List), List) | 
					
						
							|  |  |  |         self.assertIs(subst(Any), Any) | 
					
						
							|  |  |  |         self.assertIs(subst(None), type(None)) | 
					
						
							|  |  |  |         self.assertIs(subst(T), T) | 
					
						
							|  |  |  |         self.assertEqual(subst(int|str), int|str) | 
					
						
							|  |  |  |         self.assertEqual(subst(Union[int, str]), Union[int, str]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-06 21:52:39 +02:00
										 |  |  |     def test_bad_var_substitution(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							| 
									
										
										
										
											2022-03-11 10:47:26 +02:00
										 |  |  |         bad_args = ( | 
					
						
							| 
									
										
										
										
											2022-03-11 18:17:45 -08:00
										 |  |  |             (), (int, str), Union, | 
					
						
							| 
									
										
										
										
											2022-03-11 10:47:26 +02:00
										 |  |  |             Generic, Generic[T], Protocol, Protocol[T], | 
					
						
							|  |  |  |             Final, Final[int], ClassVar, ClassVar[int], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         for arg in bad_args: | 
					
						
							| 
									
										
										
										
											2022-02-06 21:52:39 +02:00
										 |  |  |             with self.subTest(arg=arg): | 
					
						
							| 
									
										
										
										
											2022-03-11 10:47:26 +02:00
										 |  |  |                 with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                     T.__typing_subst__(arg) | 
					
						
							| 
									
										
										
										
											2022-02-06 21:52:39 +02:00
										 |  |  |                 with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                     List[T][arg] | 
					
						
							|  |  |  |                 with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                     list[T][arg] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  | def template_replace(templates: list[str], replacements: dict[str, list[str]]) -> list[tuple[str]]: | 
					
						
							|  |  |  |     """Renders templates with possible combinations of replacements.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Example 1: Suppose that: | 
					
						
							|  |  |  |       templates = ["dog_breed are awesome", "dog_breed are cool"] | 
					
						
							|  |  |  |       replacements = ["dog_breed": ["Huskies", "Beagles"]] | 
					
						
							|  |  |  |     Then we would return: | 
					
						
							|  |  |  |       [ | 
					
						
							|  |  |  |           ("Huskies are awesome", "Huskies are cool"), | 
					
						
							|  |  |  |           ("Beagles are awesome", "Beagles are cool") | 
					
						
							|  |  |  |       ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Example 2: Suppose that: | 
					
						
							|  |  |  |       templates = ["Huskies are word1 but also word2"] | 
					
						
							|  |  |  |       replacements = {"word1": ["playful", "cute"], | 
					
						
							|  |  |  |                       "word2": ["feisty", "tiring"]} | 
					
						
							|  |  |  |     Then we would return: | 
					
						
							|  |  |  |       [ | 
					
						
							|  |  |  |           ("Huskies are playful but also feisty"), | 
					
						
							|  |  |  |           ("Huskies are playful but also tiring"), | 
					
						
							|  |  |  |           ("Huskies are cute but also feisty"), | 
					
						
							|  |  |  |           ("Huskies are cute but also tiring") | 
					
						
							|  |  |  |       ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Note that if any of the replacements do not occur in any template: | 
					
						
							|  |  |  |       templates = ["Huskies are word1", "Beagles!"] | 
					
						
							|  |  |  |       replacements = {"word1": ["playful", "cute"], | 
					
						
							|  |  |  |                       "word2": ["feisty", "tiring"]} | 
					
						
							|  |  |  |     Then we do not generate duplicates, returning: | 
					
						
							|  |  |  |       [ | 
					
						
							|  |  |  |           ("Huskies are playful", "Beagles!"), | 
					
						
							|  |  |  |           ("Huskies are cute", "Beagles!") | 
					
						
							|  |  |  |       ] | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     # First, build a structure like: | 
					
						
							|  |  |  |     #   [ | 
					
						
							|  |  |  |     #     [("word1", "playful"), ("word1", "cute")], | 
					
						
							|  |  |  |     #     [("word2", "feisty"), ("word2", "tiring")] | 
					
						
							|  |  |  |     #   ] | 
					
						
							|  |  |  |     replacement_combos = [] | 
					
						
							|  |  |  |     for original, possible_replacements in replacements.items(): | 
					
						
							|  |  |  |         original_replacement_tuples = [] | 
					
						
							|  |  |  |         for replacement in possible_replacements: | 
					
						
							|  |  |  |             original_replacement_tuples.append((original, replacement)) | 
					
						
							|  |  |  |         replacement_combos.append(original_replacement_tuples) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Second, generate rendered templates, including possible duplicates. | 
					
						
							|  |  |  |     rendered_templates = [] | 
					
						
							|  |  |  |     for replacement_combo in itertools.product(*replacement_combos): | 
					
						
							|  |  |  |         # replacement_combo would be e.g. | 
					
						
							|  |  |  |         #   [("word1", "playful"), ("word2", "feisty")] | 
					
						
							|  |  |  |         templates_with_replacements = [] | 
					
						
							|  |  |  |         for template in templates: | 
					
						
							|  |  |  |             for original, replacement in replacement_combo: | 
					
						
							|  |  |  |                 template = template.replace(original, replacement) | 
					
						
							|  |  |  |             templates_with_replacements.append(template) | 
					
						
							|  |  |  |         rendered_templates.append(tuple(templates_with_replacements)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Finally, remove the duplicates (but keep the order). | 
					
						
							|  |  |  |     rendered_templates_no_duplicates = [] | 
					
						
							|  |  |  |     for x in rendered_templates: | 
					
						
							|  |  |  |         # Inefficient, but should be fine for our purposes. | 
					
						
							|  |  |  |         if x not in rendered_templates_no_duplicates: | 
					
						
							|  |  |  |             rendered_templates_no_duplicates.append(x) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return rendered_templates_no_duplicates | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TemplateReplacementTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_two_templates_two_replacements_yields_correct_renders(self): | 
					
						
							|  |  |  |         actual = template_replace( | 
					
						
							|  |  |  |                 templates=["Cats are word1", "Dogs are word2"], | 
					
						
							|  |  |  |                 replacements={ | 
					
						
							|  |  |  |                     "word1": ["small", "cute"], | 
					
						
							|  |  |  |                     "word2": ["big", "fluffy"], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         expected = [ | 
					
						
							|  |  |  |             ("Cats are small", "Dogs are big"), | 
					
						
							|  |  |  |             ("Cats are small", "Dogs are fluffy"), | 
					
						
							|  |  |  |             ("Cats are cute", "Dogs are big"), | 
					
						
							|  |  |  |             ("Cats are cute", "Dogs are fluffy"), | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         self.assertEqual(actual, expected) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_duplicates_if_replacement_not_in_templates(self): | 
					
						
							|  |  |  |         actual = template_replace( | 
					
						
							|  |  |  |                 templates=["Cats are word1", "Dogs!"], | 
					
						
							|  |  |  |                 replacements={ | 
					
						
							|  |  |  |                     "word1": ["small", "cute"], | 
					
						
							|  |  |  |                     "word2": ["big", "fluffy"], | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         expected = [ | 
					
						
							|  |  |  |             ("Cats are small", "Dogs!"), | 
					
						
							|  |  |  |             ("Cats are cute", "Dogs!"), | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         self.assertEqual(actual, expected) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class GenericAliasSubstitutionTests(BaseTestCase): | 
					
						
							|  |  |  |     """Tests for type variable substitution in generic aliases.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |     For variadic cases, these tests should be regarded as the source of truth, | 
					
						
							|  |  |  |     since we hadn't realised the full complexity of variadic substitution | 
					
						
							|  |  |  |     at the time of finalizing PEP 646. For full discussion, see | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  |     https://github.com/python/cpython/issues/91162. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_one_parameter(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-08-30 10:34:55 +03:00
										 |  |  |         Ts2 = TypeVarTuple('Ts2') | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class C(Generic[T]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         generics = ['C', 'list', 'List'] | 
					
						
							|  |  |  |         tuple_types = ['tuple', 'Tuple'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         tests = [ | 
					
						
							|  |  |  |             # Alias                               # Args                     # Expected result | 
					
						
							|  |  |  |             ('generic[T]',                        '[()]',                    'TypeError'), | 
					
						
							|  |  |  |             ('generic[T]',                        '[int]',                   'generic[int]'), | 
					
						
							|  |  |  |             ('generic[T]',                        '[int, str]',              'TypeError'), | 
					
						
							|  |  |  |             ('generic[T]',                        '[tuple_type[int, ...]]',  'generic[tuple_type[int, ...]]'), | 
					
						
							| 
									
										
										
										
											2022-05-08 18:32:32 +03:00
										 |  |  |             ('generic[T]',                        '[*tuple_type[int]]',      'generic[int]'), | 
					
						
							|  |  |  |             ('generic[T]',                        '[*tuple_type[()]]',       'TypeError'), | 
					
						
							|  |  |  |             ('generic[T]',                        '[*tuple_type[int, str]]', 'TypeError'), | 
					
						
							|  |  |  |             ('generic[T]',                        '[*tuple_type[int, ...]]', 'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  |             ('generic[T]',                        '[*Ts]',                   'TypeError'), | 
					
						
							|  |  |  |             ('generic[T]',                        '[T, *Ts]',                'TypeError'), | 
					
						
							|  |  |  |             ('generic[T]',                        '[*Ts, T]',                'TypeError'), | 
					
						
							|  |  |  |             # Raises TypeError because C is not variadic. | 
					
						
							|  |  |  |             # (If C _were_ variadic, it'd be fine.) | 
					
						
							|  |  |  |             ('C[T, *tuple_type[int, ...]]',       '[int]',                   'TypeError'), | 
					
						
							|  |  |  |             # Should definitely raise TypeError: list only takes one argument. | 
					
						
							|  |  |  |             ('list[T, *tuple_type[int, ...]]',    '[int]',                   'list[int, *tuple_type[int, ...]]'), | 
					
						
							|  |  |  |             ('List[T, *tuple_type[int, ...]]',    '[int]',                   'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-08-30 10:34:55 +03:00
										 |  |  |             # Should raise, because more than one `TypeVarTuple` is not supported. | 
					
						
							|  |  |  |             ('generic[*Ts, *Ts2]',                '[int]',                   'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for alias_template, args_template, expected_template in tests: | 
					
						
							|  |  |  |             rendered_templates = template_replace( | 
					
						
							|  |  |  |                     templates=[alias_template, args_template, expected_template], | 
					
						
							|  |  |  |                     replacements={'generic': generics, 'tuple_type': tuple_types} | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             for alias_str, args_str, expected_str in rendered_templates: | 
					
						
							|  |  |  |                 with self.subTest(alias=alias_str, args=args_str, expected=expected_str): | 
					
						
							|  |  |  |                     if expected_str == 'TypeError': | 
					
						
							|  |  |  |                         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                             eval(alias_str + args_str) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         self.assertEqual( | 
					
						
							|  |  |  |                             eval(alias_str + args_str), | 
					
						
							|  |  |  |                             eval(expected_str) | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_two_parameters(self): | 
					
						
							|  |  |  |         T1 = TypeVar('T1') | 
					
						
							|  |  |  |         T2 = TypeVar('T2') | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(Generic[T1, T2]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         generics = ['C', 'dict', 'Dict'] | 
					
						
							|  |  |  |         tuple_types = ['tuple', 'Tuple'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         tests = [ | 
					
						
							|  |  |  |             # Alias                                    # Args                                               # Expected result | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[()]',                                              'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[int]',                                             'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[int, str]',                                        'generic[int, str]'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[int, str, bool]',                                  'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int]]',                                'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-05-08 18:32:32 +03:00
										 |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int, str]]',                           'generic[int, str]'), | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int, str, bool]]',                     'TypeError'), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-08 18:32:32 +03:00
										 |  |  |             ('generic[T1, T2]',                        '[int, *tuple_type[str]]',                           'generic[int, str]'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int], str]',                           'generic[int, str]'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int], *tuple_type[str]]',              'generic[int, str]'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int, str], *tuple_type[()]]',          'generic[int, str]'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[()], *tuple_type[int, str]]',          'generic[int, str]'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int], *tuple_type[()]]',               'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[()], *tuple_type[int]]',               'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int, str], *tuple_type[float]]',       'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int], *tuple_type[str, float]]',       'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int, str], *tuple_type[float, bool]]', 'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[tuple_type[int, ...]]',                            'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[tuple_type[int, ...], tuple_type[str, ...]]',      'generic[tuple_type[int, ...], tuple_type[str, ...]]'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int, ...]]',                           'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-05-08 18:32:32 +03:00
										 |  |  |             ('generic[T1, T2]',                        '[int, *tuple_type[str, ...]]',                      'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int, ...], str]',                      'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*tuple_type[int, ...], *tuple_type[str, ...]]',    'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  |             ('generic[T1, T2]',                        '[*Ts]',                                             'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[T, *Ts]',                                          'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2]',                        '[*Ts, T]',                                          'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             # This one isn't technically valid - none of the things that | 
					
						
							|  |  |  |             # `generic` can be (defined in `generics` above) are variadic, so we | 
					
						
							|  |  |  |             # shouldn't really be able to do `generic[T1, *tuple_type[int, ...]]`. | 
					
						
							|  |  |  |             # So even if type checkers shouldn't allow it, we allow it at | 
					
						
							|  |  |  |             # runtime, in accordance with a general philosophy of "Keep the | 
					
						
							|  |  |  |             # runtime lenient so people can experiment with typing constructs". | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  |             ('generic[T1, *tuple_type[int, ...]]',     '[str]',                                             'generic[str, *tuple_type[int, ...]]'), | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for alias_template, args_template, expected_template in tests: | 
					
						
							|  |  |  |             rendered_templates = template_replace( | 
					
						
							|  |  |  |                     templates=[alias_template, args_template, expected_template], | 
					
						
							|  |  |  |                     replacements={'generic': generics, 'tuple_type': tuple_types} | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             for alias_str, args_str, expected_str in rendered_templates: | 
					
						
							|  |  |  |                 with self.subTest(alias=alias_str, args=args_str, expected=expected_str): | 
					
						
							|  |  |  |                     if expected_str == 'TypeError': | 
					
						
							|  |  |  |                         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                             eval(alias_str + args_str) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         self.assertEqual( | 
					
						
							|  |  |  |                             eval(alias_str + args_str), | 
					
						
							|  |  |  |                             eval(expected_str) | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_three_parameters(self): | 
					
						
							|  |  |  |         T1 = TypeVar('T1') | 
					
						
							|  |  |  |         T2 = TypeVar('T2') | 
					
						
							|  |  |  |         T3 = TypeVar('T3') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(Generic[T1, T2, T3]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         generics = ['C'] | 
					
						
							|  |  |  |         tuple_types = ['tuple', 'Tuple'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         tests = [ | 
					
						
							|  |  |  |             # Alias                                    # Args                                               # Expected result | 
					
						
							|  |  |  |             ('generic[T1, bool, T2]',                  '[int, str]',                                        'generic[int, bool, str]'), | 
					
						
							| 
									
										
										
										
											2022-05-08 18:32:32 +03:00
										 |  |  |             ('generic[T1, bool, T2]',                  '[*tuple_type[int, str]]',                           'generic[int, bool, str]'), | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for alias_template, args_template, expected_template in tests: | 
					
						
							|  |  |  |             rendered_templates = template_replace( | 
					
						
							|  |  |  |                 templates=[alias_template, args_template, expected_template], | 
					
						
							|  |  |  |                 replacements={'generic': generics, 'tuple_type': tuple_types} | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             for alias_str, args_str, expected_str in rendered_templates: | 
					
						
							|  |  |  |                 with self.subTest(alias=alias_str, args=args_str, expected=expected_str): | 
					
						
							|  |  |  |                     if expected_str == 'TypeError': | 
					
						
							|  |  |  |                         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                             eval(alias_str + args_str) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         self.assertEqual( | 
					
						
							|  |  |  |                             eval(alias_str + args_str), | 
					
						
							|  |  |  |                             eval(expected_str) | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_variadic_parameters(self): | 
					
						
							|  |  |  |         T1 = TypeVar('T1') | 
					
						
							|  |  |  |         T2 = TypeVar('T2') | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(Generic[*Ts]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         generics = ['C', 'tuple', 'Tuple'] | 
					
						
							|  |  |  |         tuple_types = ['tuple', 'Tuple'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         tests = [ | 
					
						
							|  |  |  |             # Alias                                    # Args                                            # Expected result | 
					
						
							| 
									
										
										
										
											2022-05-08 18:32:32 +03:00
										 |  |  |             ('generic[*Ts]',                           '[()]',                                           'generic[()]'), | 
					
						
							|  |  |  |             ('generic[*Ts]',                           '[int]',                                          'generic[int]'), | 
					
						
							|  |  |  |             ('generic[*Ts]',                           '[int, str]',                                     'generic[int, str]'), | 
					
						
							|  |  |  |             ('generic[*Ts]',                           '[*tuple_type[int]]',                             'generic[int]'), | 
					
						
							|  |  |  |             ('generic[*Ts]',                           '[*tuple_type[*Ts]]',                             'generic[*Ts]'), | 
					
						
							|  |  |  |             ('generic[*Ts]',                           '[*tuple_type[int, str]]',                        'generic[int, str]'), | 
					
						
							| 
									
										
										
										
											2022-06-12 16:22:01 +03:00
										 |  |  |             ('generic[*Ts]',                           '[str, *tuple_type[int, ...], bool]',             'generic[str, *tuple_type[int, ...], bool]'), | 
					
						
							| 
									
										
										
										
											2022-05-08 18:32:32 +03:00
										 |  |  |             ('generic[*Ts]',                           '[tuple_type[int, ...]]',                         'generic[tuple_type[int, ...]]'), | 
					
						
							|  |  |  |             ('generic[*Ts]',                           '[tuple_type[int, ...], tuple_type[str, ...]]',   'generic[tuple_type[int, ...], tuple_type[str, ...]]'), | 
					
						
							|  |  |  |             ('generic[*Ts]',                           '[*tuple_type[int, ...]]',                        'generic[*tuple_type[int, ...]]'), | 
					
						
							| 
									
										
										
										
											2022-06-12 16:22:01 +03:00
										 |  |  |             ('generic[*Ts]',                           '[*tuple_type[int, ...], *tuple_type[str, ...]]', 'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-08 18:32:32 +03:00
										 |  |  |             ('generic[*Ts]',                           '[*Ts]',                                          'generic[*Ts]'), | 
					
						
							|  |  |  |             ('generic[*Ts]',                           '[T, *Ts]',                                       'generic[T, *Ts]'), | 
					
						
							|  |  |  |             ('generic[*Ts]',                           '[*Ts, T]',                                       'generic[*Ts, T]'), | 
					
						
							| 
									
										
										
										
											2022-11-29 09:46:52 +02:00
										 |  |  |             ('generic[T, *Ts]',                        '[()]',                                           'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-05-08 18:32:32 +03:00
										 |  |  |             ('generic[T, *Ts]',                        '[int]',                                          'generic[int]'), | 
					
						
							|  |  |  |             ('generic[T, *Ts]',                        '[int, str]',                                     'generic[int, str]'), | 
					
						
							|  |  |  |             ('generic[T, *Ts]',                        '[int, str, bool]',                               'generic[int, str, bool]'), | 
					
						
							| 
									
										
										
										
											2022-11-29 09:46:52 +02:00
										 |  |  |             ('generic[list[T], *Ts]',                  '[()]',                                           'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-05-31 08:46:16 +03:00
										 |  |  |             ('generic[list[T], *Ts]',                  '[int]',                                          'generic[list[int]]'), | 
					
						
							|  |  |  |             ('generic[list[T], *Ts]',                  '[int, str]',                                     'generic[list[int], str]'), | 
					
						
							|  |  |  |             ('generic[list[T], *Ts]',                  '[int, str, bool]',                               'generic[list[int], str, bool]'), | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-29 09:46:52 +02:00
										 |  |  |             ('generic[*Ts, T]',                        '[()]',                                           'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-05-08 18:32:32 +03:00
										 |  |  |             ('generic[*Ts, T]',                        '[int]',                                          'generic[int]'), | 
					
						
							|  |  |  |             ('generic[*Ts, T]',                        '[int, str]',                                     'generic[int, str]'), | 
					
						
							| 
									
										
										
										
											2022-05-31 08:46:16 +03:00
										 |  |  |             ('generic[*Ts, T]',                        '[int, str, bool]',                               'generic[int, str, bool]'), | 
					
						
							| 
									
										
										
										
											2022-11-29 09:46:52 +02:00
										 |  |  |             ('generic[*Ts, list[T]]',                  '[()]',                                           'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-05-31 08:46:16 +03:00
										 |  |  |             ('generic[*Ts, list[T]]',                  '[int]',                                          'generic[list[int]]'), | 
					
						
							|  |  |  |             ('generic[*Ts, list[T]]',                  '[int, str]',                                     'generic[int, list[str]]'), | 
					
						
							|  |  |  |             ('generic[*Ts, list[T]]',                  '[int, str, bool]',                               'generic[int, str, list[bool]]'), | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-29 09:46:52 +02:00
										 |  |  |             ('generic[T1, T2, *Ts]',                   '[()]',                                           'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2, *Ts]',                   '[int]',                                          'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, T2, *Ts]',                   '[int, str]',                                     'generic[int, str]'), | 
					
						
							|  |  |  |             ('generic[T1, T2, *Ts]',                   '[int, str, bool]',                               'generic[int, str, bool]'), | 
					
						
							|  |  |  |             ('generic[T1, T2, *Ts]',                   '[int, str, bool, bytes]',                        'generic[int, str, bool, bytes]'), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ('generic[*Ts, T1, T2]',                   '[()]',                                           'TypeError'), | 
					
						
							|  |  |  |             ('generic[*Ts, T1, T2]',                   '[int]',                                          'TypeError'), | 
					
						
							|  |  |  |             ('generic[*Ts, T1, T2]',                   '[int, str]',                                     'generic[int, str]'), | 
					
						
							|  |  |  |             ('generic[*Ts, T1, T2]',                   '[int, str, bool]',                               'generic[int, str, bool]'), | 
					
						
							|  |  |  |             ('generic[*Ts, T1, T2]',                   '[int, str, bool, bytes]',                        'generic[int, str, bool, bytes]'), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ('generic[T1, *Ts, T2]',                   '[()]',                                           'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, *Ts, T2]',                   '[int]',                                          'TypeError'), | 
					
						
							|  |  |  |             ('generic[T1, *Ts, T2]',                   '[int, str]',                                     'generic[int, str]'), | 
					
						
							|  |  |  |             ('generic[T1, *Ts, T2]',                   '[int, str, bool]',                               'generic[int, str, bool]'), | 
					
						
							|  |  |  |             ('generic[T1, *Ts, T2]',                   '[int, str, bool, bytes]',                        'generic[int, str, bool, bytes]'), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-12 16:22:01 +03:00
										 |  |  |             ('generic[T, *Ts]',                        '[*tuple_type[int, ...]]',                        'generic[int, *tuple_type[int, ...]]'), | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             ('generic[T, *Ts]',                        '[str, *tuple_type[int, ...]]',                   'generic[str, *tuple_type[int, ...]]'), | 
					
						
							|  |  |  |             ('generic[T, *Ts]',                        '[*tuple_type[int, ...], str]',                   'generic[int, *tuple_type[int, ...], str]'), | 
					
						
							| 
									
										
										
										
											2022-06-12 16:22:01 +03:00
										 |  |  |             ('generic[*Ts, T]',                        '[*tuple_type[int, ...]]',                        'generic[*tuple_type[int, ...], int]'), | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             ('generic[*Ts, T]',                        '[str, *tuple_type[int, ...]]',                   'generic[str, *tuple_type[int, ...], int]'), | 
					
						
							|  |  |  |             ('generic[*Ts, T]',                        '[*tuple_type[int, ...], str]',                   'generic[*tuple_type[int, ...], str]'), | 
					
						
							| 
									
										
										
										
											2022-06-12 16:22:01 +03:00
										 |  |  |             ('generic[T1, *Ts, T2]',                   '[*tuple_type[int, ...]]',                        'generic[int, *tuple_type[int, ...], int]'), | 
					
						
							|  |  |  |             ('generic[T, str, *Ts]',                   '[*tuple_type[int, ...]]',                        'generic[int, str, *tuple_type[int, ...]]'), | 
					
						
							|  |  |  |             ('generic[*Ts, str, T]',                   '[*tuple_type[int, ...]]',                        'generic[*tuple_type[int, ...], str, int]'), | 
					
						
							|  |  |  |             ('generic[list[T], *Ts]',                  '[*tuple_type[int, ...]]',                        'generic[list[int], *tuple_type[int, ...]]'), | 
					
						
							|  |  |  |             ('generic[*Ts, list[T]]',                  '[*tuple_type[int, ...]]',                        'generic[*tuple_type[int, ...], list[int]]'), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  |             ('generic[T, *tuple_type[int, ...]]',      '[str]',                                          'generic[str, *tuple_type[int, ...]]'), | 
					
						
							|  |  |  |             ('generic[T1, T2, *tuple_type[int, ...]]', '[str, bool]',                                    'generic[str, bool, *tuple_type[int, ...]]'), | 
					
						
							|  |  |  |             ('generic[T1, *tuple_type[int, ...], T2]', '[str, bool]',                                    'generic[str, *tuple_type[int, ...], bool]'), | 
					
						
							|  |  |  |             ('generic[T1, *tuple_type[int, ...], T2]', '[str, bool, float]',                             'TypeError'), | 
					
						
							| 
									
										
										
										
											2022-05-08 18:32:32 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |             ('generic[T1, *tuple_type[T2, ...]]',      '[int, str]',                                     'generic[int, *tuple_type[str, ...]]'), | 
					
						
							|  |  |  |             ('generic[*tuple_type[T1, ...], T2]',      '[int, str]',                                     'generic[*tuple_type[int, ...], str]'), | 
					
						
							|  |  |  |             ('generic[T1, *tuple_type[generic[*Ts], ...]]', '[int, str, bool]',                          'generic[int, *tuple_type[generic[str, bool], ...]]'), | 
					
						
							|  |  |  |             ('generic[*tuple_type[generic[*Ts], ...], T1]', '[int, str, bool]',                          'generic[*tuple_type[generic[int, str], ...], bool]'), | 
					
						
							| 
									
										
										
										
											2022-04-29 14:03:21 -06:00
										 |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for alias_template, args_template, expected_template in tests: | 
					
						
							|  |  |  |             rendered_templates = template_replace( | 
					
						
							|  |  |  |                     templates=[alias_template, args_template, expected_template], | 
					
						
							|  |  |  |                     replacements={'generic': generics, 'tuple_type': tuple_types} | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             for alias_str, args_str, expected_str in rendered_templates: | 
					
						
							|  |  |  |                 with self.subTest(alias=alias_str, args=args_str, expected=expected_str): | 
					
						
							|  |  |  |                     if expected_str == 'TypeError': | 
					
						
							|  |  |  |                         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                             eval(alias_str + args_str) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         self.assertEqual( | 
					
						
							|  |  |  |                             eval(alias_str + args_str), | 
					
						
							|  |  |  |                             eval(expected_str) | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | class UnpackTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_accepts_single_type(self): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         (*tuple[int],) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         Unpack[Tuple[int]] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 14:09:19 +03:00
										 |  |  |     def test_dir(self): | 
					
						
							|  |  |  |         dir_items = set(dir(Unpack[Tuple[int]])) | 
					
						
							|  |  |  |         for required_item in [ | 
					
						
							|  |  |  |             '__args__', '__parameters__', '__origin__', | 
					
						
							|  |  |  |         ]: | 
					
						
							|  |  |  |             with self.subTest(required_item=required_item): | 
					
						
							|  |  |  |                 self.assertIn(required_item, dir_items) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |     def test_rejects_multiple_types(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Unpack[Tuple[int], Tuple[str]] | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         # We can't do the equivalent for `*` here - | 
					
						
							|  |  |  |         # *(Tuple[int], Tuple[str]) is just plain tuple unpacking, | 
					
						
							|  |  |  |         # which is valid. | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_rejects_multiple_parameterization(self): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             (*tuple[int],)[0][tuple[int]] | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Unpack[Tuple[int]][Tuple[int]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_be_called(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Unpack() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |     def test_usage_with_kwargs(self): | 
					
						
							|  |  |  |         Movie = TypedDict('Movie', {'name': str, 'year': int}) | 
					
						
							|  |  |  |         def foo(**kwargs: Unpack[Movie]): ... | 
					
						
							|  |  |  |         self.assertEqual(repr(foo.__annotations__['kwargs']), | 
					
						
							|  |  |  |                          f"typing.Unpack[{__name__}.Movie]") | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class TypeVarTupleTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |     def assertEndsWith(self, string, tail): | 
					
						
							|  |  |  |         if not string.endswith(tail): | 
					
						
							|  |  |  |             self.fail(f"String {string!r} does not end with {tail!r}") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-18 10:56:36 -07:00
										 |  |  |     def test_name(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         self.assertEqual(Ts.__name__, 'Ts') | 
					
						
							|  |  |  |         Ts2 = TypeVarTuple('Ts2') | 
					
						
							|  |  |  |         self.assertEqual(Ts2.__name__, 'Ts2') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |     def test_instance_is_equal_to_itself(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         self.assertEqual(Ts, Ts) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_different_instances_are_different(self): | 
					
						
							|  |  |  |         self.assertNotEqual(TypeVarTuple('Ts'), TypeVarTuple('Ts')) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_instance_isinstance_of_typevartuple(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         self.assertIsInstance(Ts, TypeVarTuple) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_call_instance(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Ts() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_unpacked_typevartuple_is_equal_to_itself(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual((*Ts,)[0], (*Ts,)[0]) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual(Unpack[Ts], Unpack[Ts]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_parameterised_tuple_is_equal_to_itself(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual(tuple[*Ts], tuple[*Ts]) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual(Tuple[Unpack[Ts]], Tuple[Unpack[Ts]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def tests_tuple_arg_ordering_matters(self): | 
					
						
							|  |  |  |         Ts1 = TypeVarTuple('Ts1') | 
					
						
							|  |  |  |         Ts2 = TypeVarTuple('Ts2') | 
					
						
							|  |  |  |         self.assertNotEqual( | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             tuple[*Ts1, *Ts2], | 
					
						
							|  |  |  |             tuple[*Ts2, *Ts1], | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         ) | 
					
						
							|  |  |  |         self.assertNotEqual( | 
					
						
							|  |  |  |             Tuple[Unpack[Ts1], Unpack[Ts2]], | 
					
						
							|  |  |  |             Tuple[Unpack[Ts2], Unpack[Ts1]], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_tuple_args_and_parameters_are_correct(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         t1 = tuple[*Ts] | 
					
						
							|  |  |  |         self.assertEqual(t1.__args__, (*Ts,)) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual(t1.__parameters__, (Ts,)) | 
					
						
							|  |  |  |         t2 = Tuple[Unpack[Ts]] | 
					
						
							|  |  |  |         self.assertEqual(t2.__args__, (Unpack[Ts],)) | 
					
						
							|  |  |  |         self.assertEqual(t2.__parameters__, (Ts,)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |     def test_var_substitution(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         T2 = TypeVar('T2') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         class G1(Generic[*Ts]): pass | 
					
						
							|  |  |  |         class G2(Generic[Unpack[Ts]]): pass | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         for A in G1, G2, Tuple, tuple: | 
					
						
							|  |  |  |             B = A[*Ts] | 
					
						
							| 
									
										
										
										
											2022-03-17 09:52:24 +02:00
										 |  |  |             self.assertEqual(B[()], A[()]) | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |             self.assertEqual(B[float], A[float]) | 
					
						
							|  |  |  |             self.assertEqual(B[float, str], A[float, str]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             C = A[Unpack[Ts]] | 
					
						
							|  |  |  |             self.assertEqual(C[()], A[()]) | 
					
						
							|  |  |  |             self.assertEqual(C[float], A[float]) | 
					
						
							|  |  |  |             self.assertEqual(C[float, str], A[float, str]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             D = list[A[*Ts]] | 
					
						
							|  |  |  |             self.assertEqual(D[()], list[A[()]]) | 
					
						
							|  |  |  |             self.assertEqual(D[float], list[A[float]]) | 
					
						
							|  |  |  |             self.assertEqual(D[float, str], list[A[float, str]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             E = List[A[Unpack[Ts]]] | 
					
						
							|  |  |  |             self.assertEqual(E[()], List[A[()]]) | 
					
						
							|  |  |  |             self.assertEqual(E[float], List[A[float]]) | 
					
						
							|  |  |  |             self.assertEqual(E[float, str], List[A[float, str]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             F = A[T, *Ts, T2] | 
					
						
							|  |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 F[()] | 
					
						
							|  |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 F[float] | 
					
						
							|  |  |  |             self.assertEqual(F[float, str], A[float, str]) | 
					
						
							|  |  |  |             self.assertEqual(F[float, str, int], A[float, str, int]) | 
					
						
							|  |  |  |             self.assertEqual(F[float, str, int, bytes], A[float, str, int, bytes]) | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             G = A[T, Unpack[Ts], T2] | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |             with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |                 G[()] | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |             with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |                 G[float] | 
					
						
							|  |  |  |             self.assertEqual(G[float, str], A[float, str]) | 
					
						
							|  |  |  |             self.assertEqual(G[float, str, int], A[float, str, int]) | 
					
						
							|  |  |  |             self.assertEqual(G[float, str, int, bytes], A[float, str, int, bytes]) | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             H = tuple[list[T], A[*Ts], list[T2]] | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |             with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |                 H[()] | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |             with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |                 H[float] | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |             if A != Tuple: | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |                 self.assertEqual(H[float, str], | 
					
						
							|  |  |  |                                  tuple[list[float], A[()], list[str]]) | 
					
						
							|  |  |  |             self.assertEqual(H[float, str, int], | 
					
						
							|  |  |  |                              tuple[list[float], A[str], list[int]]) | 
					
						
							|  |  |  |             self.assertEqual(H[float, str, int, bytes], | 
					
						
							|  |  |  |                              tuple[list[float], A[str, int], list[bytes]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             I = Tuple[List[T], A[Unpack[Ts]], List[T2]] | 
					
						
							|  |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 I[()] | 
					
						
							|  |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 I[float] | 
					
						
							|  |  |  |             if A != Tuple: | 
					
						
							|  |  |  |                 self.assertEqual(I[float, str], | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |                                  Tuple[List[float], A[()], List[str]]) | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             self.assertEqual(I[float, str, int], | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |                              Tuple[List[float], A[str], List[int]]) | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             self.assertEqual(I[float, str, int, bytes], | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |                              Tuple[List[float], A[str, int], List[bytes]]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-13 06:08:49 +03:00
										 |  |  |     def test_bad_var_substitution(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         T2 = TypeVar('T2') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         class G1(Generic[*Ts]): pass | 
					
						
							|  |  |  |         class G2(Generic[Unpack[Ts]]): pass | 
					
						
							| 
									
										
										
										
											2022-04-13 06:08:49 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         for A in G1, G2, Tuple, tuple: | 
					
						
							| 
									
										
										
										
											2022-04-30 08:22:46 +03:00
										 |  |  |             B = A[Ts] | 
					
						
							|  |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 B[int, str] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             C = A[T, T2] | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 C[*Ts] | 
					
						
							| 
									
										
										
										
											2022-04-30 08:22:46 +03:00
										 |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 C[Unpack[Ts]] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             B = A[T, *Ts, str, T2] | 
					
						
							| 
									
										
										
										
											2022-04-13 06:08:49 +03:00
										 |  |  |             with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |                 B[int, *Ts] | 
					
						
							|  |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 B[int, *Ts, *Ts] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-13 06:08:49 +03:00
										 |  |  |             C = A[T, Unpack[Ts], str, T2] | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 C[int, Unpack[Ts]] | 
					
						
							| 
									
										
										
										
											2022-04-13 06:08:49 +03:00
										 |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 C[int, Unpack[Ts], Unpack[Ts]] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |     def test_repr_is_correct(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class G1(Generic[*Ts]): pass | 
					
						
							|  |  |  |         class G2(Generic[Unpack[Ts]]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |         self.assertEqual(repr(Ts), 'Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEqual(repr((*Ts,)[0]), 'typing.Unpack[Ts]') | 
					
						
							|  |  |  |         self.assertEqual(repr(Unpack[Ts]), 'typing.Unpack[Ts]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEqual(repr(tuple[*Ts]), 'tuple[typing.Unpack[Ts]]') | 
					
						
							|  |  |  |         self.assertEqual(repr(Tuple[Unpack[Ts]]), 'typing.Tuple[typing.Unpack[Ts]]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEqual(repr(*tuple[*Ts]), '*tuple[typing.Unpack[Ts]]') | 
					
						
							|  |  |  |         self.assertEqual(repr(Unpack[Tuple[Unpack[Ts]]]), 'typing.Unpack[typing.Tuple[typing.Unpack[Ts]]]') | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |     def test_variadic_class_repr_is_correct(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         class A(Generic[*Ts]): pass | 
					
						
							|  |  |  |         class B(Generic[Unpack[Ts]]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |         self.assertEndsWith(repr(A[()]), 'A[()]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(B[()]), 'B[()]') | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |         self.assertEndsWith(repr(A[float]), 'A[float]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(B[float]), 'B[float]') | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |         self.assertEndsWith(repr(A[float, str]), 'A[float, str]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(B[float, str]), 'B[float, str]') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEndsWith(repr(A[*tuple[int, ...]]), | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |                             'A[*tuple[int, ...]]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(B[Unpack[Tuple[int, ...]]]), | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |                             'B[typing.Unpack[typing.Tuple[int, ...]]]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEndsWith(repr(A[float, *tuple[int, ...]]), | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |                             'A[float, *tuple[int, ...]]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(A[float, Unpack[Tuple[int, ...]]]), | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |                             'A[float, typing.Unpack[typing.Tuple[int, ...]]]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEndsWith(repr(A[*tuple[int, ...], str]), | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |                             'A[*tuple[int, ...], str]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(B[Unpack[Tuple[int, ...]], str]), | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |                             'B[typing.Unpack[typing.Tuple[int, ...]], str]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEndsWith(repr(A[float, *tuple[int, ...], str]), | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |                             'A[float, *tuple[int, ...], str]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(B[float, Unpack[Tuple[int, ...]], str]), | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |                             'B[float, typing.Unpack[typing.Tuple[int, ...]], str]') | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_variadic_class_alias_repr_is_correct(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         class A(Generic[Unpack[Ts]]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         B = A[*Ts] | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEndsWith(repr(B), 'A[typing.Unpack[Ts]]') | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |         self.assertEndsWith(repr(B[()]), 'A[()]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(B[float]), 'A[float]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(B[float, str]), 'A[float, str]') | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         C = A[Unpack[Ts]] | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEndsWith(repr(C), 'A[typing.Unpack[Ts]]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(C[()]), 'A[()]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(C[float]), 'A[float]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(C[float, str]), 'A[float, str]') | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         D = A[*Ts, int] | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEndsWith(repr(D), 'A[typing.Unpack[Ts], int]') | 
					
						
							| 
									
										
										
										
											2022-03-11 21:43:58 +02:00
										 |  |  |         self.assertEndsWith(repr(D[()]), 'A[int]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(D[float]), 'A[float, int]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(D[float, str]), 'A[float, str, int]') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         E = A[Unpack[Ts], int] | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEndsWith(repr(E), 'A[typing.Unpack[Ts], int]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(E[()]), 'A[int]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(E[float]), 'A[float, int]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(E[float, str]), 'A[float, str, int]') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         F = A[int, *Ts] | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEndsWith(repr(F), 'A[int, typing.Unpack[Ts]]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(F[()]), 'A[int]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(F[float]), 'A[int, float]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(F[float, str]), 'A[int, float, str]') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         G = A[int, Unpack[Ts]] | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEndsWith(repr(G), 'A[int, typing.Unpack[Ts]]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(G[()]), 'A[int]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(G[float]), 'A[int, float]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(G[float, str]), 'A[int, float, str]') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         H = A[int, *Ts, str] | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEndsWith(repr(H), 'A[int, typing.Unpack[Ts], str]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(H[()]), 'A[int, str]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(H[float]), 'A[int, float, str]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(H[float, str]), 'A[int, float, str, str]') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         I = A[int, Unpack[Ts], str] | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEndsWith(repr(I), 'A[int, typing.Unpack[Ts], str]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(I[()]), 'A[int, str]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(I[float]), 'A[int, float, str]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(I[float, str]), 'A[int, float, str, str]') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         J = A[*Ts, *tuple[str, ...]] | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEndsWith(repr(J), 'A[typing.Unpack[Ts], *tuple[str, ...]]') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEndsWith(repr(J[()]), 'A[*tuple[str, ...]]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(J[float]), 'A[float, *tuple[str, ...]]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(J[float, str]), 'A[float, str, *tuple[str, ...]]') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         K = A[Unpack[Ts], Unpack[Tuple[str, ...]]] | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         self.assertEndsWith(repr(K), 'A[typing.Unpack[Ts], typing.Unpack[typing.Tuple[str, ...]]]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(K[()]), 'A[typing.Unpack[typing.Tuple[str, ...]]]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(K[float]), 'A[float, typing.Unpack[typing.Tuple[str, ...]]]') | 
					
						
							|  |  |  |         self.assertEndsWith(repr(K[float, str]), 'A[float, str, typing.Unpack[typing.Tuple[str, ...]]]') | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |     def test_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |         with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'TypeVarTuple'): | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |             class C(TypeVarTuple): pass | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 CANNOT_SUBCLASS_INSTANCE % 'TypeVarTuple'): | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |             class C(Ts): pass | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:16 +03:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							|  |  |  |             class C(type(Unpack)): pass | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							|  |  |  |             class C(type(*Ts)): pass | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:16 +03:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							|  |  |  |             class C(type(Unpack[Ts])): pass | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                                     r'Cannot subclass typing\.Unpack'): | 
					
						
							|  |  |  |             class C(Unpack): pass | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         with self.assertRaisesRegex(TypeError, r'Cannot subclass typing.Unpack\[Ts\]'): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             class C(*Ts): pass | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |         with self.assertRaisesRegex(TypeError, r'Cannot subclass typing.Unpack\[Ts\]'): | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |             class C(Unpack[Ts]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_variadic_class_args_are_correct(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         class A(Generic[*Ts]): pass | 
					
						
							|  |  |  |         class B(Generic[Unpack[Ts]]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         C = A[()] | 
					
						
							|  |  |  |         D = B[()] | 
					
						
							|  |  |  |         self.assertEqual(C.__args__, ()) | 
					
						
							|  |  |  |         self.assertEqual(D.__args__, ()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         E = A[int] | 
					
						
							|  |  |  |         F = B[int] | 
					
						
							|  |  |  |         self.assertEqual(E.__args__, (int,)) | 
					
						
							|  |  |  |         self.assertEqual(F.__args__, (int,)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         G = A[int, str] | 
					
						
							|  |  |  |         H = B[int, str] | 
					
						
							|  |  |  |         self.assertEqual(G.__args__, (int, str)) | 
					
						
							|  |  |  |         self.assertEqual(H.__args__, (int, str)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         I = A[T] | 
					
						
							|  |  |  |         J = B[T] | 
					
						
							|  |  |  |         self.assertEqual(I.__args__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(J.__args__, (T,)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         K = A[*Ts] | 
					
						
							|  |  |  |         L = B[Unpack[Ts]] | 
					
						
							|  |  |  |         self.assertEqual(K.__args__, (*Ts,)) | 
					
						
							|  |  |  |         self.assertEqual(L.__args__, (Unpack[Ts],)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         M = A[T, *Ts] | 
					
						
							|  |  |  |         N = B[T, Unpack[Ts]] | 
					
						
							|  |  |  |         self.assertEqual(M.__args__, (T, *Ts)) | 
					
						
							|  |  |  |         self.assertEqual(N.__args__, (T, Unpack[Ts])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         O = A[*Ts, T] | 
					
						
							|  |  |  |         P = B[Unpack[Ts], T] | 
					
						
							|  |  |  |         self.assertEqual(O.__args__, (*Ts, T)) | 
					
						
							|  |  |  |         self.assertEqual(P.__args__, (Unpack[Ts], T)) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_variadic_class_origin_is_correct(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class C(Generic[*Ts]): pass | 
					
						
							|  |  |  |         self.assertIs(C[int].__origin__, C) | 
					
						
							|  |  |  |         self.assertIs(C[T].__origin__, C) | 
					
						
							|  |  |  |         self.assertIs(C[Unpack[Ts]].__origin__, C) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         class D(Generic[Unpack[Ts]]): pass | 
					
						
							|  |  |  |         self.assertIs(D[int].__origin__, D) | 
					
						
							|  |  |  |         self.assertIs(D[T].__origin__, D) | 
					
						
							|  |  |  |         self.assertIs(D[Unpack[Ts]].__origin__, D) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-23 10:52:58 +03:00
										 |  |  |     def test_get_type_hints_on_unpack_args(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def func1(*args: *Ts): pass | 
					
						
							|  |  |  |         self.assertEqual(gth(func1), {'args': Unpack[Ts]}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def func2(*args: *tuple[int, str]): pass | 
					
						
							|  |  |  |         self.assertEqual(gth(func2), {'args': Unpack[tuple[int, str]]}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CustomVariadic(Generic[*Ts]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def func3(*args: *CustomVariadic[int, str]): pass | 
					
						
							|  |  |  |         self.assertEqual(gth(func3), {'args': Unpack[CustomVariadic[int, str]]}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_type_hints_on_unpack_args_string(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def func1(*args: '*Ts'): pass | 
					
						
							|  |  |  |         self.assertEqual(gth(func1, localns={'Ts': Ts}), | 
					
						
							|  |  |  |                         {'args': Unpack[Ts]}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def func2(*args: '*tuple[int, str]'): pass | 
					
						
							|  |  |  |         self.assertEqual(gth(func2), {'args': Unpack[tuple[int, str]]}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CustomVariadic(Generic[*Ts]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def func3(*args: '*CustomVariadic[int, str]'): pass | 
					
						
							|  |  |  |         self.assertEqual(gth(func3, localns={'CustomVariadic': CustomVariadic}), | 
					
						
							|  |  |  |                          {'args': Unpack[CustomVariadic[int, str]]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |     def test_tuple_args_are_correct(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual(tuple[*Ts].__args__, (*Ts,)) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual(Tuple[Unpack[Ts]].__args__, (Unpack[Ts],)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual(tuple[*Ts, int].__args__, (*Ts, int)) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual(Tuple[Unpack[Ts], int].__args__, (Unpack[Ts], int)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual(tuple[int, *Ts].__args__, (int, *Ts)) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual(Tuple[int, Unpack[Ts]].__args__, (int, Unpack[Ts])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual(tuple[int, *Ts, str].__args__, | 
					
						
							|  |  |  |                          (int, *Ts, str)) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual(Tuple[int, Unpack[Ts], str].__args__, | 
					
						
							|  |  |  |                          (int, Unpack[Ts], str)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual(tuple[*Ts, int].__args__, (*Ts, int)) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual(Tuple[Unpack[Ts]].__args__, (Unpack[Ts],)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_callable_args_are_correct(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         Ts1 = TypeVarTuple('Ts1') | 
					
						
							|  |  |  |         Ts2 = TypeVarTuple('Ts2') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # TypeVarTuple in the arguments | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         a = Callable[[*Ts], None] | 
					
						
							|  |  |  |         b = Callable[[Unpack[Ts]], None] | 
					
						
							|  |  |  |         self.assertEqual(a.__args__, (*Ts, type(None))) | 
					
						
							|  |  |  |         self.assertEqual(b.__args__, (Unpack[Ts], type(None))) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         c = Callable[[int, *Ts], None] | 
					
						
							|  |  |  |         d = Callable[[int, Unpack[Ts]], None] | 
					
						
							|  |  |  |         self.assertEqual(c.__args__, (int, *Ts, type(None))) | 
					
						
							|  |  |  |         self.assertEqual(d.__args__, (int, Unpack[Ts], type(None))) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         e = Callable[[*Ts, int], None] | 
					
						
							|  |  |  |         f = Callable[[Unpack[Ts], int], None] | 
					
						
							|  |  |  |         self.assertEqual(e.__args__, (*Ts, int, type(None))) | 
					
						
							|  |  |  |         self.assertEqual(f.__args__, (Unpack[Ts], int, type(None))) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         g = Callable[[str, *Ts, int], None] | 
					
						
							|  |  |  |         h = Callable[[str, Unpack[Ts], int], None] | 
					
						
							|  |  |  |         self.assertEqual(g.__args__, (str, *Ts, int, type(None))) | 
					
						
							|  |  |  |         self.assertEqual(h.__args__, (str, Unpack[Ts], int, type(None))) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # TypeVarTuple as the return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         i = Callable[[None], *Ts] | 
					
						
							|  |  |  |         j = Callable[[None], Unpack[Ts]] | 
					
						
							|  |  |  |         self.assertEqual(i.__args__, (type(None), *Ts)) | 
					
						
							| 
									
										
										
										
											2023-03-05 21:37:29 +00:00
										 |  |  |         self.assertEqual(j.__args__, (type(None), Unpack[Ts])) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         k = Callable[[None], tuple[int, *Ts]] | 
					
						
							|  |  |  |         l = Callable[[None], Tuple[int, Unpack[Ts]]] | 
					
						
							|  |  |  |         self.assertEqual(k.__args__, (type(None), tuple[int, *Ts])) | 
					
						
							|  |  |  |         self.assertEqual(l.__args__, (type(None), Tuple[int, Unpack[Ts]])) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         m = Callable[[None], tuple[*Ts, int]] | 
					
						
							|  |  |  |         n = Callable[[None], Tuple[Unpack[Ts], int]] | 
					
						
							|  |  |  |         self.assertEqual(m.__args__, (type(None), tuple[*Ts, int])) | 
					
						
							|  |  |  |         self.assertEqual(n.__args__, (type(None), Tuple[Unpack[Ts], int])) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         o = Callable[[None], tuple[str, *Ts, int]] | 
					
						
							|  |  |  |         p = Callable[[None], Tuple[str, Unpack[Ts], int]] | 
					
						
							|  |  |  |         self.assertEqual(o.__args__, (type(None), tuple[str, *Ts, int])) | 
					
						
							|  |  |  |         self.assertEqual(p.__args__, (type(None), Tuple[str, Unpack[Ts], int])) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # TypeVarTuple in both | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         q = Callable[[*Ts], *Ts] | 
					
						
							|  |  |  |         r = Callable[[Unpack[Ts]], Unpack[Ts]] | 
					
						
							|  |  |  |         self.assertEqual(q.__args__, (*Ts, *Ts)) | 
					
						
							|  |  |  |         self.assertEqual(r.__args__, (Unpack[Ts], Unpack[Ts])) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         s = Callable[[*Ts1], *Ts2] | 
					
						
							|  |  |  |         u = Callable[[Unpack[Ts1]], Unpack[Ts2]] | 
					
						
							|  |  |  |         self.assertEqual(s.__args__, (*Ts1, *Ts2)) | 
					
						
							|  |  |  |         self.assertEqual(u.__args__, (Unpack[Ts1], Unpack[Ts2])) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_variadic_class_with_duplicate_typevartuples_fails(self): | 
					
						
							|  |  |  |         Ts1 = TypeVarTuple('Ts1') | 
					
						
							|  |  |  |         Ts2 = TypeVarTuple('Ts2') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(Generic[*Ts1, *Ts1]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(Generic[Unpack[Ts1], Unpack[Ts1]]): pass | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(Generic[*Ts1, *Ts2, *Ts1]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(Generic[Unpack[Ts1], Unpack[Ts2], Unpack[Ts1]]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_type_concatenation_in_variadic_class_argument_list_succeeds(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         class C(Generic[Unpack[Ts]]): pass | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         C[int, *Ts] | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         C[int, Unpack[Ts]] | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         C[*Ts, int] | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         C[Unpack[Ts], int] | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         C[int, *Ts, str] | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         C[int, Unpack[Ts], str] | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         C[int, bool, *Ts, float, str] | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         C[int, bool, Unpack[Ts], float, str] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_type_concatenation_in_tuple_argument_list_succeeds(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         tuple[int, *Ts] | 
					
						
							|  |  |  |         tuple[*Ts, int] | 
					
						
							|  |  |  |         tuple[int, *Ts, str] | 
					
						
							|  |  |  |         tuple[int, bool, *Ts, float, str] | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Tuple[int, Unpack[Ts]] | 
					
						
							|  |  |  |         Tuple[Unpack[Ts], int] | 
					
						
							|  |  |  |         Tuple[int, Unpack[Ts], str] | 
					
						
							|  |  |  |         Tuple[int, bool, Unpack[Ts], float, str] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_variadic_class_definition_using_packed_typevartuple_fails(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(Generic[Ts]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_variadic_class_definition_using_concrete_types_fails(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class F(Generic[*Ts, int]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class E(Generic[Unpack[Ts], int]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_variadic_class_with_2_typevars_accepts_2_or_more_args(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         T1 = TypeVar('T1') | 
					
						
							|  |  |  |         T2 = TypeVar('T2') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         class A(Generic[T1, T2, *Ts]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         A[int, str] | 
					
						
							|  |  |  |         A[int, str, float] | 
					
						
							|  |  |  |         A[int, str, float, bool] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         class B(Generic[T1, T2, Unpack[Ts]]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         B[int, str] | 
					
						
							|  |  |  |         B[int, str, float] | 
					
						
							|  |  |  |         B[int, str, float, bool] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         class C(Generic[T1, *Ts, T2]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         C[int, str] | 
					
						
							|  |  |  |         C[int, str, float] | 
					
						
							|  |  |  |         C[int, str, float, bool] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         class D(Generic[T1, Unpack[Ts], T2]): pass | 
					
						
							|  |  |  |         D[int, str] | 
					
						
							|  |  |  |         D[int, str, float] | 
					
						
							|  |  |  |         D[int, str, float, bool] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class E(Generic[*Ts, T1, T2]): pass | 
					
						
							|  |  |  |         E[int, str] | 
					
						
							|  |  |  |         E[int, str, float] | 
					
						
							|  |  |  |         E[int, str, float, bool] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class F(Generic[Unpack[Ts], T1, T2]): pass | 
					
						
							|  |  |  |         F[int, str] | 
					
						
							|  |  |  |         F[int, str, float] | 
					
						
							|  |  |  |         F[int, str, float, bool] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |     def test_variadic_args_annotations_are_correct(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         def f(*args: Unpack[Ts]): pass | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         def g(*args: *Ts): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual(f.__annotations__, {'args': Unpack[Ts]}) | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual(g.__annotations__, {'args': (*Ts,)[0]}) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_variadic_args_with_ellipsis_annotations_are_correct(self): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         def a(*args: *tuple[int, ...]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual(a.__annotations__, | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |                          {'args': (*tuple[int, ...],)[0]}) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def b(*args: Unpack[Tuple[int, ...]]): pass | 
					
						
							|  |  |  |         self.assertEqual(b.__annotations__, | 
					
						
							|  |  |  |                          {'args': Unpack[Tuple[int, ...]]}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_concatenation_in_variadic_args_annotations_are_correct(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         # Unpacking using `*`, native `tuple` type | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         def a(*args: *tuple[int, *Ts]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             a.__annotations__, | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             {'args': (*tuple[int, *Ts],)[0]}, | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         def b(*args: *tuple[*Ts, int]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             b.__annotations__, | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             {'args': (*tuple[*Ts, int],)[0]}, | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         def c(*args: *tuple[str, *Ts, int]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             c.__annotations__, | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             {'args': (*tuple[str, *Ts, int],)[0]}, | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         def d(*args: *tuple[int, bool, *Ts, float, str]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             d.__annotations__, | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             {'args': (*tuple[int, bool, *Ts, float, str],)[0]}, | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Unpacking using `Unpack`, `Tuple` type from typing.py | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def e(*args: Unpack[Tuple[int, Unpack[Ts]]]): pass | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             e.__annotations__, | 
					
						
							|  |  |  |             {'args': Unpack[Tuple[int, Unpack[Ts]]]}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def f(*args: Unpack[Tuple[Unpack[Ts], int]]): pass | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             f.__annotations__, | 
					
						
							|  |  |  |             {'args': Unpack[Tuple[Unpack[Ts], int]]}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def g(*args: Unpack[Tuple[str, Unpack[Ts], int]]): pass | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             g.__annotations__, | 
					
						
							|  |  |  |             {'args': Unpack[Tuple[str, Unpack[Ts], int]]}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def h(*args: Unpack[Tuple[int, bool, Unpack[Ts], float, str]]): pass | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             h.__annotations__, | 
					
						
							|  |  |  |             {'args': Unpack[Tuple[int, bool, Unpack[Ts], float, str]]}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_variadic_class_same_args_results_in_equalty(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         class C(Generic[*Ts]): pass | 
					
						
							|  |  |  |         class D(Generic[Unpack[Ts]]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(C[int], C[int]) | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual(D[int], D[int]) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Ts1 = TypeVarTuple('Ts1') | 
					
						
							|  |  |  |         Ts2 = TypeVarTuple('Ts2') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertEqual( | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             C[*Ts1], | 
					
						
							|  |  |  |             C[*Ts1], | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             D[Unpack[Ts1]], | 
					
						
							|  |  |  |             D[Unpack[Ts1]], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             C[*Ts1, *Ts2], | 
					
						
							|  |  |  |             C[*Ts1, *Ts2], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             D[Unpack[Ts1], Unpack[Ts2]], | 
					
						
							|  |  |  |             D[Unpack[Ts1], Unpack[Ts2]], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             C[int, *Ts1, *Ts2], | 
					
						
							|  |  |  |             C[int, *Ts1, *Ts2], | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             D[int, Unpack[Ts1], Unpack[Ts2]], | 
					
						
							|  |  |  |             D[int, Unpack[Ts1], Unpack[Ts2]], | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_variadic_class_arg_ordering_matters(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         class C(Generic[*Ts]): pass | 
					
						
							|  |  |  |         class D(Generic[Unpack[Ts]]): pass | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotEqual( | 
					
						
							|  |  |  |             C[int, str], | 
					
						
							|  |  |  |             C[str, int], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertNotEqual( | 
					
						
							|  |  |  |             D[int, str], | 
					
						
							|  |  |  |             D[str, int], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Ts1 = TypeVarTuple('Ts1') | 
					
						
							|  |  |  |         Ts2 = TypeVarTuple('Ts2') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotEqual( | 
					
						
							|  |  |  |             C[*Ts1, *Ts2], | 
					
						
							|  |  |  |             C[*Ts2, *Ts1], | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         self.assertNotEqual( | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             D[Unpack[Ts1], Unpack[Ts2]], | 
					
						
							|  |  |  |             D[Unpack[Ts2], Unpack[Ts1]], | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_variadic_class_arg_typevartuple_identity_matters(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         Ts1 = TypeVarTuple('Ts1') | 
					
						
							|  |  |  |         Ts2 = TypeVarTuple('Ts2') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class C(Generic[*Ts]): pass | 
					
						
							|  |  |  |         class D(Generic[Unpack[Ts]]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotEqual(C[*Ts1], C[*Ts2]) | 
					
						
							|  |  |  |         self.assertNotEqual(D[Unpack[Ts1]], D[Unpack[Ts2]]) | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-22 05:22:53 +01:00
										 |  |  | class TypeVarTuplePicklingTests(BaseTestCase): | 
					
						
							|  |  |  |     # These are slightly awkward tests to run, because TypeVarTuples are only | 
					
						
							|  |  |  |     # picklable if defined in the global scope. We therefore need to push | 
					
						
							|  |  |  |     # various things defined in these tests into the global scope with `global` | 
					
						
							|  |  |  |     # statements at the start of each test. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @all_pickle_protocols | 
					
						
							|  |  |  |     def test_pickling_then_unpickling_results_in_same_identity(self, proto): | 
					
						
							| 
									
										
										
										
											2022-04-29 23:18:38 -04:00
										 |  |  |         global global_Ts1  # See explanation at start of class. | 
					
						
							|  |  |  |         global_Ts1 = TypeVarTuple('global_Ts1') | 
					
						
							|  |  |  |         global_Ts2 = pickle.loads(pickle.dumps(global_Ts1, proto)) | 
					
						
							|  |  |  |         self.assertIs(global_Ts1, global_Ts2) | 
					
						
							| 
									
										
										
										
											2022-04-22 05:22:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @all_pickle_protocols | 
					
						
							|  |  |  |     def test_pickling_then_unpickling_unpacked_results_in_same_identity(self, proto): | 
					
						
							| 
									
										
										
										
											2022-04-29 23:18:38 -04:00
										 |  |  |         global global_Ts  # See explanation at start of class. | 
					
						
							|  |  |  |         global_Ts = TypeVarTuple('global_Ts') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         unpacked1 = (*global_Ts,)[0] | 
					
						
							| 
									
										
										
										
											2022-04-22 05:22:53 +01:00
										 |  |  |         unpacked2 = pickle.loads(pickle.dumps(unpacked1, proto)) | 
					
						
							|  |  |  |         self.assertIs(unpacked1, unpacked2) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         unpacked3 = Unpack[global_Ts] | 
					
						
							|  |  |  |         unpacked4 = pickle.loads(pickle.dumps(unpacked3, proto)) | 
					
						
							|  |  |  |         self.assertIs(unpacked3, unpacked4) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-22 05:22:53 +01:00
										 |  |  |     @all_pickle_protocols | 
					
						
							|  |  |  |     def test_pickling_then_unpickling_tuple_with_typevartuple_equality( | 
					
						
							|  |  |  |             self, proto | 
					
						
							|  |  |  |     ): | 
					
						
							| 
									
										
										
										
											2022-04-29 23:18:38 -04:00
										 |  |  |         global global_T, global_Ts  # See explanation at start of class. | 
					
						
							|  |  |  |         global_T = TypeVar('global_T') | 
					
						
							|  |  |  |         global_Ts = TypeVarTuple('global_Ts') | 
					
						
							| 
									
										
										
										
											2022-04-22 05:22:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         tuples = [ | 
					
						
							|  |  |  |             tuple[*global_Ts], | 
					
						
							|  |  |  |             Tuple[Unpack[global_Ts]], | 
					
						
							| 
									
										
										
										
											2022-04-22 05:22:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             tuple[T, *global_Ts], | 
					
						
							|  |  |  |             Tuple[T, Unpack[global_Ts]], | 
					
						
							| 
									
										
										
										
											2022-04-22 05:22:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             tuple[int, *global_Ts], | 
					
						
							|  |  |  |             Tuple[int, Unpack[global_Ts]], | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         for t in tuples: | 
					
						
							|  |  |  |             t2 = pickle.loads(pickle.dumps(t, proto)) | 
					
						
							|  |  |  |             self.assertEqual(t, t2) | 
					
						
							| 
									
										
										
										
											2022-04-22 05:22:53 +01: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(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]') | 
					
						
							| 
									
										
										
										
											2020-11-02 02:13:38 +08:00
										 |  |  |         u = Union[list[int], dict[str, float]] | 
					
						
							|  |  |  |         self.assertEqual(repr(u), 'typing.Union[list[int], dict[str, float]]') | 
					
						
							| 
									
										
										
										
											2021-07-17 06:33:40 +03:00
										 |  |  |         u = Union[int | float] | 
					
						
							|  |  |  |         self.assertEqual(repr(u), 'typing.Union[int, float]') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 13:13:02 +03:00
										 |  |  |         u = Union[None, str] | 
					
						
							|  |  |  |         self.assertEqual(repr(u), 'typing.Optional[str]') | 
					
						
							|  |  |  |         u = Union[str, None] | 
					
						
							|  |  |  |         self.assertEqual(repr(u), 'typing.Optional[str]') | 
					
						
							|  |  |  |         u = Union[None, str, int] | 
					
						
							|  |  |  |         self.assertEqual(repr(u), 'typing.Union[NoneType, str, int]') | 
					
						
							|  |  |  |         u = Optional[str] | 
					
						
							|  |  |  |         self.assertEqual(repr(u), 'typing.Optional[str]') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 14:09:19 +03:00
										 |  |  |     def test_dir(self): | 
					
						
							|  |  |  |         dir_items = set(dir(Union[str, int])) | 
					
						
							|  |  |  |         for required_item in [ | 
					
						
							|  |  |  |             '__args__', '__parameters__', '__origin__', | 
					
						
							|  |  |  |         ]: | 
					
						
							|  |  |  |             with self.subTest(required_item=required_item): | 
					
						
							|  |  |  |                 self.assertIn(required_item, dir_items) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 r'Cannot subclass typing\.Union'): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |             class C(Union): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |             class C(type(Union)): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 r'Cannot subclass typing\.Union\[int, str\]'): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |             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[()] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     def test_no_eval_union(self): | 
					
						
							|  |  |  |         u = Union[int, str] | 
					
						
							|  |  |  |         def f(x: u): ... | 
					
						
							| 
									
										
										
										
											2021-04-21 12:41:19 +01:00
										 |  |  |         self.assertIs(get_type_hints(f)['x'], u) | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-23 20:50:23 +03:00
										 |  |  |     def test_union_of_literals(self): | 
					
						
							|  |  |  |         self.assertEqual(Union[Literal[1], Literal[2]].__args__, | 
					
						
							|  |  |  |                          (Literal[1], Literal[2])) | 
					
						
							|  |  |  |         self.assertEqual(Union[Literal[1], Literal[1]], | 
					
						
							|  |  |  |                          Literal[1]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(Union[Literal[False], Literal[0]].__args__, | 
					
						
							|  |  |  |                          (Literal[False], Literal[0])) | 
					
						
							|  |  |  |         self.assertEqual(Union[Literal[True], Literal[1]].__args__, | 
					
						
							|  |  |  |                          (Literal[True], Literal[1])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         import enum | 
					
						
							|  |  |  |         class Ints(enum.IntEnum): | 
					
						
							|  |  |  |             A = 0 | 
					
						
							|  |  |  |             B = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 19:55:16 +03:00
										 |  |  |         self.assertEqual(Union[Literal[Ints.A], Literal[Ints.A]], | 
					
						
							|  |  |  |                          Literal[Ints.A]) | 
					
						
							|  |  |  |         self.assertEqual(Union[Literal[Ints.B], Literal[Ints.B]], | 
					
						
							|  |  |  |                          Literal[Ints.B]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-23 20:50:23 +03:00
										 |  |  |         self.assertEqual(Union[Literal[Ints.A], Literal[Ints.B]].__args__, | 
					
						
							|  |  |  |                          (Literal[Ints.A], Literal[Ints.B])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(Union[Literal[0], Literal[Ints.A], Literal[False]].__args__, | 
					
						
							|  |  |  |                          (Literal[0], Literal[Ints.A], Literal[False])) | 
					
						
							|  |  |  |         self.assertEqual(Union[Literal[1], Literal[Ints.B], Literal[True]].__args__, | 
					
						
							|  |  |  |                          (Literal[1], Literal[Ints.B], Literal[True])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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): ... | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         self.assertIsSubclass(tuple, Tuple) | 
					
						
							|  |  |  |         self.assertIsSubclass(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 | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         self.assertIsSubclass(MyTuple, Tuple) | 
					
						
							| 
									
										
										
										
											2022-02-07 04:35:48 +03:00
										 |  |  |         self.assertIsSubclass(Tuple, Tuple) | 
					
						
							|  |  |  |         self.assertIsSubclass(tuple, Tuple) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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, ...]') | 
					
						
							| 
									
										
										
										
											2020-11-02 02:13:38 +08:00
										 |  |  |         self.assertEqual(repr(Tuple[list[int]]), 'typing.Tuple[list[int]]') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_errors(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(42, Tuple) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(42, Tuple[int]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  | class BaseCallableTests: | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_self_subclass(self): | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         Callable = self.Callable | 
					
						
							| 
									
										
										
										
											2016-09-27 15:20:12 -07:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |             issubclass(types.FunctionType, Callable[[int], int]) | 
					
						
							|  |  |  |         self.assertIsSubclass(types.FunctionType, Callable) | 
					
						
							| 
									
										
										
										
											2022-02-07 04:35:48 +03:00
										 |  |  |         self.assertIsSubclass(Callable, Callable) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_eq_hash(self): | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         C = Callable[[int], int] | 
					
						
							|  |  |  |         self.assertEqual(C, Callable[[int], int]) | 
					
						
							|  |  |  |         self.assertEqual(len({C, Callable[[int], int]}), 1) | 
					
						
							|  |  |  |         self.assertNotEqual(C, Callable[[int], str]) | 
					
						
							|  |  |  |         self.assertNotEqual(C, Callable[[str], int]) | 
					
						
							|  |  |  |         self.assertNotEqual(C, Callable[[int, int], int]) | 
					
						
							|  |  |  |         self.assertNotEqual(C, Callable[[], int]) | 
					
						
							|  |  |  |         self.assertNotEqual(C, Callable[..., int]) | 
					
						
							|  |  |  |         self.assertNotEqual(C, Callable) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 14:09:19 +03:00
										 |  |  |     def test_dir(self): | 
					
						
							|  |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         dir_items = set(dir(Callable[..., int])) | 
					
						
							|  |  |  |         for required_item in [ | 
					
						
							|  |  |  |             '__args__', '__parameters__', '__origin__', | 
					
						
							|  |  |  |         ]: | 
					
						
							|  |  |  |             with self.subTest(required_item=required_item): | 
					
						
							|  |  |  |                 self.assertIn(required_item, dir_items) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_cannot_instantiate(self): | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         Callable = self.Callable | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         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): | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         Callable = self.Callable | 
					
						
							| 
									
										
										
										
											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): | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         Callable = self.Callable | 
					
						
							| 
									
										
										
										
											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): | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         Callable = self.Callable | 
					
						
							| 
									
										
										
										
											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): | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         fullname = f'{Callable.__module__}.Callable' | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         ct0 = Callable[[], bool] | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         self.assertEqual(repr(ct0), f'{fullname}[[], bool]') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         ct2 = Callable[[str, float], int] | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         self.assertEqual(repr(ct2), f'{fullname}[[str, float], int]') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |         ctv = Callable[..., str] | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         self.assertEqual(repr(ctv), f'{fullname}[..., str]') | 
					
						
							| 
									
										
										
										
											2020-11-02 02:13:38 +08:00
										 |  |  |         ct3 = Callable[[str, float], list[int]] | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         self.assertEqual(repr(ct3), f'{fullname}[[str, float], list[int]]') | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |     def test_callable_with_ellipsis(self): | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         Callable = self.Callable | 
					
						
							| 
									
										
										
										
											2015-08-05 12:11:06 +02:00
										 |  |  |         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): | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         Callable = self.Callable | 
					
						
							| 
									
										
										
										
											2016-08-23 11:01:50 -07:00
										 |  |  |         # Shouldn't crash; see https://github.com/python/typing/issues/259 | 
					
						
							|  |  |  |         typing.List[Callable[..., str]] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 18:32:25 +03:00
										 |  |  |     def test_or_and_ror(self): | 
					
						
							|  |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         self.assertEqual(Callable | Tuple, Union[Callable, Tuple]) | 
					
						
							|  |  |  |         self.assertEqual(Tuple | Callable, Union[Tuple, Callable]) | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |     def test_basic(self): | 
					
						
							|  |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         alias = Callable[[int, str], float] | 
					
						
							|  |  |  |         if Callable is collections.abc.Callable: | 
					
						
							|  |  |  |             self.assertIsInstance(alias, types.GenericAlias) | 
					
						
							|  |  |  |         self.assertIs(alias.__origin__, collections.abc.Callable) | 
					
						
							|  |  |  |         self.assertEqual(alias.__args__, (int, str, float)) | 
					
						
							|  |  |  |         self.assertEqual(alias.__parameters__, ()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_weakref(self): | 
					
						
							|  |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         alias = Callable[[int, str], float] | 
					
						
							|  |  |  |         self.assertEqual(weakref.ref(alias)(), alias) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_pickle(self): | 
					
						
							| 
									
										
										
										
											2023-03-16 17:47:30 +03:00
										 |  |  |         global T_pickle, P_pickle, TS_pickle  # needed for pickling | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         Callable = self.Callable | 
					
						
							| 
									
										
										
										
											2023-03-16 17:47:30 +03:00
										 |  |  |         T_pickle = TypeVar('T_pickle') | 
					
						
							|  |  |  |         P_pickle = ParamSpec('P_pickle') | 
					
						
							|  |  |  |         TS_pickle = TypeVarTuple('TS_pickle') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         samples = [ | 
					
						
							|  |  |  |             Callable[[int, str], float], | 
					
						
							|  |  |  |             Callable[P_pickle, int], | 
					
						
							|  |  |  |             Callable[P_pickle, T_pickle], | 
					
						
							|  |  |  |             Callable[Concatenate[int, P_pickle], int], | 
					
						
							|  |  |  |             Callable[Concatenate[*TS_pickle, P_pickle], int], | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         for alias in samples: | 
					
						
							|  |  |  |             for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |                 with self.subTest(alias=alias, proto=proto): | 
					
						
							|  |  |  |                     s = pickle.dumps(alias, proto) | 
					
						
							|  |  |  |                     loaded = pickle.loads(s) | 
					
						
							|  |  |  |                     self.assertEqual(alias.__origin__, loaded.__origin__) | 
					
						
							|  |  |  |                     self.assertEqual(alias.__args__, loaded.__args__) | 
					
						
							|  |  |  |                     self.assertEqual(alias.__parameters__, loaded.__parameters__) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         del T_pickle, P_pickle, TS_pickle  # cleaning up global state | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_var_substitution(self): | 
					
						
							|  |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         fullname = f"{Callable.__module__}.Callable" | 
					
						
							|  |  |  |         C1 = Callable[[int, T], T] | 
					
						
							|  |  |  |         C2 = Callable[[KT, T], VT] | 
					
						
							|  |  |  |         C3 = Callable[..., T] | 
					
						
							|  |  |  |         self.assertEqual(C1[str], Callable[[int, str], str]) | 
					
						
							| 
									
										
										
										
											2022-03-11 10:47:26 +02:00
										 |  |  |         self.assertEqual(C1[None], Callable[[int, type(None)], type(None)]) | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         self.assertEqual(C2[int, float, str], Callable[[int, float], str]) | 
					
						
							|  |  |  |         self.assertEqual(C3[int], Callable[..., int]) | 
					
						
							| 
									
										
										
										
											2022-02-06 21:52:39 +02:00
										 |  |  |         self.assertEqual(C3[NoReturn], Callable[..., NoReturn]) | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # multi chaining | 
					
						
							|  |  |  |         C4 = C2[int, VT, str] | 
					
						
							|  |  |  |         self.assertEqual(repr(C4), f"{fullname}[[int, ~VT], str]") | 
					
						
							|  |  |  |         self.assertEqual(repr(C4[dict]), f"{fullname}[[int, dict], str]") | 
					
						
							|  |  |  |         self.assertEqual(C4[dict], Callable[[int, dict], str]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # substitute a nested GenericAlias (both typing and the builtin | 
					
						
							|  |  |  |         # version) | 
					
						
							|  |  |  |         C5 = Callable[[typing.List[T], tuple[KT, T], VT], int] | 
					
						
							|  |  |  |         self.assertEqual(C5[int, str, float], | 
					
						
							|  |  |  |                          Callable[[typing.List[int], tuple[str, int], float], int]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-16 17:47:30 +03:00
										 |  |  |     def test_type_subst_error(self): | 
					
						
							|  |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         pat = "Expected a list of types, an ellipsis, ParamSpec, or Concatenate." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, pat): | 
					
						
							|  |  |  |             Callable[P, T][0, int] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |     def test_type_erasure(self): | 
					
						
							|  |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         class C1(Callable): | 
					
						
							|  |  |  |             def __call__(self): | 
					
						
							|  |  |  |                 return None | 
					
						
							|  |  |  |         a = C1[[int], T] | 
					
						
							|  |  |  |         self.assertIs(a().__class__, C1) | 
					
						
							|  |  |  |         self.assertEqual(a().__orig_class__, C1[[int], T]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_paramspec(self): | 
					
						
							|  |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         fullname = f"{Callable.__module__}.Callable" | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							| 
									
										
										
										
											2021-08-04 21:07:01 +03:00
										 |  |  |         P2 = ParamSpec('P2') | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         C1 = Callable[P, T] | 
					
						
							|  |  |  |         # substitution | 
					
						
							| 
									
										
										
										
											2021-08-04 21:07:01 +03:00
										 |  |  |         self.assertEqual(C1[[int], str], Callable[[int], str]) | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         self.assertEqual(C1[[int, str], str], Callable[[int, str], str]) | 
					
						
							| 
									
										
										
										
											2021-08-04 21:07:01 +03:00
										 |  |  |         self.assertEqual(C1[[], str], Callable[[], str]) | 
					
						
							|  |  |  |         self.assertEqual(C1[..., str], Callable[..., str]) | 
					
						
							|  |  |  |         self.assertEqual(C1[P2, str], Callable[P2, str]) | 
					
						
							|  |  |  |         self.assertEqual(C1[Concatenate[int, P2], str], | 
					
						
							|  |  |  |                          Callable[Concatenate[int, P2], str]) | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         self.assertEqual(repr(C1), f"{fullname}[~P, ~T]") | 
					
						
							| 
									
										
										
										
											2021-08-04 21:07:01 +03:00
										 |  |  |         self.assertEqual(repr(C1[[int, str], str]), f"{fullname}[[int, str], str]") | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             C1[int, str] | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         C2 = Callable[P, int] | 
					
						
							| 
									
										
										
										
											2021-08-04 21:07:01 +03:00
										 |  |  |         self.assertEqual(C2[[int]], Callable[[int], int]) | 
					
						
							|  |  |  |         self.assertEqual(C2[[int, str]], Callable[[int, str], int]) | 
					
						
							|  |  |  |         self.assertEqual(C2[[]], Callable[[], int]) | 
					
						
							|  |  |  |         self.assertEqual(C2[...], Callable[..., int]) | 
					
						
							|  |  |  |         self.assertEqual(C2[P2], Callable[P2, int]) | 
					
						
							|  |  |  |         self.assertEqual(C2[Concatenate[int, P2]], | 
					
						
							|  |  |  |                          Callable[Concatenate[int, P2], int]) | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         # special case in PEP 612 where | 
					
						
							|  |  |  |         # X[int, str, float] == X[[int, str, float]] | 
					
						
							| 
									
										
										
										
											2021-08-04 21:07:01 +03:00
										 |  |  |         self.assertEqual(C2[int], Callable[[int], int]) | 
					
						
							|  |  |  |         self.assertEqual(C2[int, str], Callable[[int, str], int]) | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         self.assertEqual(repr(C2), f"{fullname}[~P, int]") | 
					
						
							|  |  |  |         self.assertEqual(repr(C2[int, str]), f"{fullname}[[int, str], int]") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_concatenate(self): | 
					
						
							|  |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         fullname = f"{Callable.__module__}.Callable" | 
					
						
							| 
									
										
										
										
											2022-01-27 14:34:55 +02:00
										 |  |  |         T = TypeVar('T') | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |         P = ParamSpec('P') | 
					
						
							| 
									
										
										
										
											2022-01-27 14:34:55 +02:00
										 |  |  |         P2 = ParamSpec('P2') | 
					
						
							|  |  |  |         C = Callable[Concatenate[int, P], T] | 
					
						
							|  |  |  |         self.assertEqual(repr(C), | 
					
						
							|  |  |  |                          f"{fullname}[typing.Concatenate[int, ~P], ~T]") | 
					
						
							|  |  |  |         self.assertEqual(C[P2, int], Callable[Concatenate[int, P2], int]) | 
					
						
							|  |  |  |         self.assertEqual(C[[str, float], int], Callable[[int, str, float], int]) | 
					
						
							|  |  |  |         self.assertEqual(C[[], int], Callable[[int], int]) | 
					
						
							|  |  |  |         self.assertEqual(C[Concatenate[str, P2], int], | 
					
						
							|  |  |  |                          Callable[Concatenate[int, str, P2], int]) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:01:40 +03:00
										 |  |  |         self.assertEqual(C[..., int], Callable[Concatenate[int, ...], int]) | 
					
						
							| 
									
										
										
										
											2022-01-27 14:34:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         C = Callable[Concatenate[int, P], int] | 
					
						
							|  |  |  |         self.assertEqual(repr(C), | 
					
						
							|  |  |  |                          f"{fullname}[typing.Concatenate[int, ~P], int]") | 
					
						
							|  |  |  |         self.assertEqual(C[P2], Callable[Concatenate[int, P2], int]) | 
					
						
							|  |  |  |         self.assertEqual(C[[str, float]], Callable[[int, str, float], int]) | 
					
						
							|  |  |  |         self.assertEqual(C[str, float], Callable[[int, str, float], int]) | 
					
						
							|  |  |  |         self.assertEqual(C[[]], Callable[[int], int]) | 
					
						
							|  |  |  |         self.assertEqual(C[Concatenate[str, P2]], | 
					
						
							|  |  |  |                          Callable[Concatenate[int, str, P2], int]) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:01:40 +03:00
										 |  |  |         self.assertEqual(C[...], Callable[Concatenate[int, ...], int]) | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-29 06:04:26 +03:00
										 |  |  |     def test_nested_paramspec(self): | 
					
						
							|  |  |  |         # Since Callable has some special treatment, we want to be sure | 
					
						
							|  |  |  |         # that substituion works correctly, see gh-103054 | 
					
						
							|  |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         P2 = ParamSpec('P2') | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         T2 = TypeVar('T2') | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         class My(Generic[P, T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(My.__parameters__, (P, T)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         C1 = My[[int, T2], Callable[P2, T2]] | 
					
						
							|  |  |  |         self.assertEqual(C1.__args__, ((int, T2), Callable[P2, T2])) | 
					
						
							|  |  |  |         self.assertEqual(C1.__parameters__, (T2, P2)) | 
					
						
							|  |  |  |         self.assertEqual(C1[str, [list[int], bytes]], | 
					
						
							|  |  |  |                          My[[int, str], Callable[[list[int], bytes], str]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         C2 = My[[Callable[[T2], int], list[T2]], str] | 
					
						
							|  |  |  |         self.assertEqual(C2.__args__, ((Callable[[T2], int], list[T2]), str)) | 
					
						
							|  |  |  |         self.assertEqual(C2.__parameters__, (T2,)) | 
					
						
							|  |  |  |         self.assertEqual(C2[list[str]], | 
					
						
							|  |  |  |                          My[[Callable[[list[str]], int], list[list[str]]], str]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         C3 = My[[Callable[P2, T2], T2], T2] | 
					
						
							|  |  |  |         self.assertEqual(C3.__args__, ((Callable[P2, T2], T2), T2)) | 
					
						
							|  |  |  |         self.assertEqual(C3.__parameters__, (P2, T2)) | 
					
						
							|  |  |  |         self.assertEqual(C3[[], int], | 
					
						
							|  |  |  |                          My[[Callable[[], int], int], int]) | 
					
						
							|  |  |  |         self.assertEqual(C3[[str, bool], int], | 
					
						
							|  |  |  |                          My[[Callable[[str, bool], int], int], int]) | 
					
						
							|  |  |  |         self.assertEqual(C3[[str, bool], T][int], | 
					
						
							|  |  |  |                          My[[Callable[[str, bool], int], int], int]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         C4 = My[[Callable[[int, *Ts, str], T2], T2], T2] | 
					
						
							|  |  |  |         self.assertEqual(C4.__args__, ((Callable[[int, *Ts, str], T2], T2), T2)) | 
					
						
							|  |  |  |         self.assertEqual(C4.__parameters__, (Ts, T2)) | 
					
						
							|  |  |  |         self.assertEqual(C4[bool, bytes, float], | 
					
						
							|  |  |  |                          My[[Callable[[int, bool, bytes, str], float], float], float]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-31 20:05:45 +03:00
										 |  |  |     def test_errors(self): | 
					
						
							|  |  |  |         Callable = self.Callable | 
					
						
							|  |  |  |         alias = Callable[[int, str], float] | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, "is not a generic class"): | 
					
						
							|  |  |  |             alias[int] | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         C1 = Callable[P, T] | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, "many arguments for"): | 
					
						
							|  |  |  |             C1[int, str, str] | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, "few arguments for"): | 
					
						
							|  |  |  |             C1[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TypingCallableTests(BaseCallableTests, BaseTestCase): | 
					
						
							|  |  |  |     Callable = typing.Callable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_consistency(self): | 
					
						
							|  |  |  |         # bpo-42195 | 
					
						
							|  |  |  |         # Testing collections.abc.Callable's consistency with typing.Callable | 
					
						
							|  |  |  |         c1 = typing.Callable[[int, str], dict] | 
					
						
							|  |  |  |         c2 = collections.abc.Callable[[int, str], dict] | 
					
						
							|  |  |  |         self.assertEqual(c1.__args__, c2.__args__) | 
					
						
							|  |  |  |         self.assertEqual(hash(c1.__args__), hash(c2.__args__)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CollectionsCallableTests(BaseCallableTests, BaseTestCase): | 
					
						
							|  |  |  |     Callable = collections.abc.Callable | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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"] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-23 20:50:23 +03:00
										 |  |  |     def test_enum(self): | 
					
						
							|  |  |  |         import enum | 
					
						
							|  |  |  |         class My(enum.Enum): | 
					
						
							|  |  |  |             A = 'A' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(Literal[My.A].__args__, (My.A,)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:48 +01:00
										 |  |  |     def test_illegal_parameters_do_not_raise_runtime_errors(self): | 
					
						
							|  |  |  |         # Type checkers should reject these types, but we do not | 
					
						
							| 
									
										
										
										
											2021-06-23 07:42:28 +09:00
										 |  |  |         # raise errors at runtime to maintain maximum flexibility. | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:48 +01:00
										 |  |  |         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]") | 
					
						
							| 
									
										
										
										
											2020-11-17 04:23:19 +02:00
										 |  |  |         self.assertEqual(repr(Literal[1, 2, 3, 3]), "typing.Literal[1, 2, 3]") | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 14:09:19 +03:00
										 |  |  |     def test_dir(self): | 
					
						
							|  |  |  |         dir_items = set(dir(Literal[1, 2, 3])) | 
					
						
							|  |  |  |         for required_item in [ | 
					
						
							|  |  |  |             '__args__', '__parameters__', '__origin__', | 
					
						
							|  |  |  |         ]: | 
					
						
							|  |  |  |             with self.subTest(required_item=required_item): | 
					
						
							|  |  |  |                 self.assertIn(required_item, dir_items) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:48 +01:00
										 |  |  |     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] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-17 04:23:19 +02:00
										 |  |  |     def test_equal(self): | 
					
						
							|  |  |  |         self.assertNotEqual(Literal[0], Literal[False]) | 
					
						
							|  |  |  |         self.assertNotEqual(Literal[True], Literal[1]) | 
					
						
							|  |  |  |         self.assertNotEqual(Literal[1], Literal[2]) | 
					
						
							|  |  |  |         self.assertNotEqual(Literal[1, True], Literal[1]) | 
					
						
							| 
									
										
										
										
											2021-10-31 10:22:16 +02:00
										 |  |  |         self.assertNotEqual(Literal[1, True], Literal[1, 1]) | 
					
						
							|  |  |  |         self.assertNotEqual(Literal[1, 2], Literal[True, 2]) | 
					
						
							| 
									
										
										
										
											2020-11-17 04:23:19 +02:00
										 |  |  |         self.assertEqual(Literal[1], Literal[1]) | 
					
						
							|  |  |  |         self.assertEqual(Literal[1, 2], Literal[2, 1]) | 
					
						
							|  |  |  |         self.assertEqual(Literal[1, 2, 3], Literal[1, 2, 3, 3]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-19 18:17:38 +02:00
										 |  |  |     def test_hash(self): | 
					
						
							|  |  |  |         self.assertEqual(hash(Literal[1]), hash(Literal[1])) | 
					
						
							|  |  |  |         self.assertEqual(hash(Literal[1, 2]), hash(Literal[2, 1])) | 
					
						
							|  |  |  |         self.assertEqual(hash(Literal[1, 2, 3]), hash(Literal[1, 2, 3, 3])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-17 04:23:19 +02:00
										 |  |  |     def test_args(self): | 
					
						
							|  |  |  |         self.assertEqual(Literal[1, 2, 3].__args__, (1, 2, 3)) | 
					
						
							|  |  |  |         self.assertEqual(Literal[1, 2, 3, 3].__args__, (1, 2, 3)) | 
					
						
							|  |  |  |         self.assertEqual(Literal[1, Literal[2], Literal[3, 4]].__args__, (1, 2, 3, 4)) | 
					
						
							|  |  |  |         # Mutable arguments will not be deduplicated | 
					
						
							|  |  |  |         self.assertEqual(Literal[[], []].__args__, ([], [])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_flatten(self): | 
					
						
							|  |  |  |         l1 = Literal[Literal[1], Literal[2], Literal[3]] | 
					
						
							|  |  |  |         l2 = Literal[Literal[1, 2], 3] | 
					
						
							|  |  |  |         l3 = Literal[Literal[1, 2, 3]] | 
					
						
							|  |  |  |         for l in l1, l2, l3: | 
					
						
							|  |  |  |             self.assertEqual(l, Literal[1, 2, 3]) | 
					
						
							|  |  |  |             self.assertEqual(l.__args__, (1, 2, 3)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-23 20:50:23 +03:00
										 |  |  |     def test_does_not_flatten_enum(self): | 
					
						
							|  |  |  |         import enum | 
					
						
							|  |  |  |         class Ints(enum.IntEnum): | 
					
						
							|  |  |  |             A = 1 | 
					
						
							|  |  |  |             B = 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         l = Literal[ | 
					
						
							|  |  |  |             Literal[Ints.A], | 
					
						
							|  |  |  |             Literal[Ints.B], | 
					
						
							|  |  |  |             Literal[1], | 
					
						
							|  |  |  |             Literal[2], | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         self.assertEqual(l.__args__, (Ints.A, Ints.B, 1, 2)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							| 
									
										
										
										
											2021-08-02 19:23:22 +03:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             C(42) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |         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) | 
					
						
							| 
									
										
										
										
											2021-08-02 19:23:22 +03:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             CG[int](42) | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-11 09:51:25 -05:00
										 |  |  |     def test_protocol_defining_init_does_not_get_overridden(self): | 
					
						
							|  |  |  |         # check that P.__init__ doesn't get clobbered | 
					
						
							|  |  |  |         # see https://bugs.python.org/issue44807 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             x: int | 
					
						
							|  |  |  |             def __init__(self, x: int) -> None: | 
					
						
							|  |  |  |                 self.x = x | 
					
						
							|  |  |  |         class C: pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         c = C() | 
					
						
							|  |  |  |         P.__init__(c, 1) | 
					
						
							|  |  |  |         self.assertEqual(c.x, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_concrete_class_inheriting_init_from_protocol(self): | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             x: int | 
					
						
							|  |  |  |             def __init__(self, x: int) -> None: | 
					
						
							|  |  |  |                 self.x = x | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(P): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         c = C(1) | 
					
						
							|  |  |  |         self.assertIsInstance(c, C) | 
					
						
							|  |  |  |         self.assertEqual(c.x, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |     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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 00:43:12 +01:00
										 |  |  |     def test_no_weird_caching_with_issubclass_after_isinstance(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class Spam(Protocol): | 
					
						
							|  |  |  |             x: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Eggs: | 
					
						
							|  |  |  |             def __init__(self) -> None: | 
					
						
							|  |  |  |                 self.x = 42 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(Eggs(), Spam) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta, | 
					
						
							|  |  |  |         # TypeError wouldn't be raised here, | 
					
						
							|  |  |  |         # as the cached result of the isinstance() check immediately above | 
					
						
							|  |  |  |         # would mean the issubclass() call would short-circuit | 
					
						
							|  |  |  |         # before we got to the "raise TypeError" line | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Eggs, Spam) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_weird_caching_with_issubclass_after_isinstance_2(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class Spam(Protocol): | 
					
						
							|  |  |  |             x: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Eggs: ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotIsInstance(Eggs(), Spam) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta, | 
					
						
							|  |  |  |         # TypeError wouldn't be raised here, | 
					
						
							|  |  |  |         # as the cached result of the isinstance() check immediately above | 
					
						
							|  |  |  |         # would mean the issubclass() call would short-circuit | 
					
						
							|  |  |  |         # before we got to the "raise TypeError" line | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Eggs, Spam) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_weird_caching_with_issubclass_after_isinstance_3(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class Spam(Protocol): | 
					
						
							|  |  |  |             x: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Eggs: | 
					
						
							|  |  |  |             def __getattr__(self, attr): | 
					
						
							|  |  |  |                 if attr == "x": | 
					
						
							|  |  |  |                     return 42 | 
					
						
							|  |  |  |                 raise AttributeError(attr) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotIsInstance(Eggs(), Spam) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta, | 
					
						
							|  |  |  |         # TypeError wouldn't be raised here, | 
					
						
							|  |  |  |         # as the cached result of the isinstance() check immediately above | 
					
						
							|  |  |  |         # would mean the issubclass() call would short-circuit | 
					
						
							|  |  |  |         # before we got to the "raise TypeError" line | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Eggs, Spam) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_weird_caching_with_issubclass_after_isinstance_pep695(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class Spam[T](Protocol): | 
					
						
							|  |  |  |             x: T | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Eggs[T]: | 
					
						
							|  |  |  |             def __init__(self, x: T) -> None: | 
					
						
							|  |  |  |                 self.x = x | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(Eggs(42), Spam) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta, | 
					
						
							|  |  |  |         # TypeError wouldn't be raised here, | 
					
						
							|  |  |  |         # as the cached result of the isinstance() check immediately above | 
					
						
							|  |  |  |         # would mean the issubclass() call would short-circuit | 
					
						
							|  |  |  |         # before we got to the "raise TypeError" line | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Eggs, Spam) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |     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): ... | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 18:21:19 +01:00
										 |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class WeirdProto(Protocol): | 
					
						
							|  |  |  |             meth = str.maketrans | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class WeirdProto2(Protocol): | 
					
						
							|  |  |  |             meth = lambda *args, **kwargs: None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CustomCallable: | 
					
						
							|  |  |  |             def __call__(self, *args, **kwargs): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class WeirderProto(Protocol): | 
					
						
							|  |  |  |             meth = CustomCallable() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |         class BadP(Protocol): | 
					
						
							|  |  |  |             def meth(x): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class BadPG(Protocol[T]): | 
					
						
							|  |  |  |             def meth(x): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def meth(x): ... | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 18:21:19 +01:00
										 |  |  |         class C2: | 
					
						
							|  |  |  |             def __init__(self): | 
					
						
							|  |  |  |                 self.meth = lambda: None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for klass in C, C2: | 
					
						
							|  |  |  |             for proto in P, PG, WeirdProto, WeirdProto2, WeirderProto: | 
					
						
							|  |  |  |                 with self.subTest(klass=klass.__name__, proto=proto.__name__): | 
					
						
							|  |  |  |                     self.assertIsInstance(klass(), proto) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |         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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-11 01:20:20 +00:00
										 |  |  |     def test_protocols_isinstance_properties_and_descriptors(self): | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             def attr(self): | 
					
						
							|  |  |  |                 return 42 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CustomDescriptor: | 
					
						
							|  |  |  |             def __get__(self, obj, objtype=None): | 
					
						
							|  |  |  |                 return 42 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D: | 
					
						
							|  |  |  |             attr = CustomDescriptor() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Check that properties set on superclasses | 
					
						
							|  |  |  |         # are still found by the isinstance() logic | 
					
						
							|  |  |  |         class E(C): ... | 
					
						
							|  |  |  |         class F(D): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Empty: ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             def attr(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P1(Protocol): | 
					
						
							|  |  |  |             attr: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PG(Protocol[T]): | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             def attr(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PG1(Protocol[T]): | 
					
						
							|  |  |  |             attr: T | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-02 14:22:19 +01:00
										 |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class MethodP(Protocol): | 
					
						
							|  |  |  |             def attr(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class MethodPG(Protocol[T]): | 
					
						
							|  |  |  |             def attr(self) -> T: ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for protocol_class in P, P1, PG, PG1, MethodP, MethodPG: | 
					
						
							| 
									
										
										
										
											2023-03-11 01:20:20 +00:00
										 |  |  |             for klass in C, D, E, F: | 
					
						
							|  |  |  |                 with self.subTest( | 
					
						
							|  |  |  |                     klass=klass.__name__, | 
					
						
							|  |  |  |                     protocol_class=protocol_class.__name__ | 
					
						
							|  |  |  |                 ): | 
					
						
							|  |  |  |                     self.assertIsInstance(klass(), protocol_class) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             with self.subTest(klass="Empty", protocol_class=protocol_class.__name__): | 
					
						
							|  |  |  |                 self.assertNotIsInstance(Empty(), protocol_class) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class BadP(Protocol): | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             def attr(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class BadP1(Protocol): | 
					
						
							|  |  |  |             attr: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class BadPG(Protocol[T]): | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             def attr(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class BadPG1(Protocol[T]): | 
					
						
							|  |  |  |             attr: T | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-02 14:22:19 +01:00
										 |  |  |         cases = ( | 
					
						
							|  |  |  |             PG[T], PG[C], PG1[T], PG1[C], MethodPG[T], | 
					
						
							|  |  |  |             MethodPG[C], BadP, BadP1, BadPG, BadPG1 | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for obj in cases: | 
					
						
							| 
									
										
										
										
											2023-03-11 01:20:20 +00:00
										 |  |  |             for klass in C, D, E, F, Empty: | 
					
						
							|  |  |  |                 with self.subTest(klass=klass.__name__, obj=obj): | 
					
						
							|  |  |  |                     with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                         isinstance(klass(), obj) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_protocols_isinstance_not_fooled_by_custom_dir(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class HasX(Protocol): | 
					
						
							|  |  |  |             x: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CustomDirWithX: | 
					
						
							|  |  |  |             x = 10 | 
					
						
							|  |  |  |             def __dir__(self): | 
					
						
							|  |  |  |                 return [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CustomDirWithoutX: | 
					
						
							|  |  |  |             def __dir__(self): | 
					
						
							|  |  |  |                 return ["x"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(CustomDirWithX(), HasX) | 
					
						
							|  |  |  |         self.assertNotIsInstance(CustomDirWithoutX(), HasX) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-02 14:22:19 +01:00
										 |  |  |     def test_protocols_isinstance_attribute_access_with_side_effects(self): | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             def attr(self): | 
					
						
							|  |  |  |                 raise AttributeError('no') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CustomDescriptor: | 
					
						
							|  |  |  |             def __get__(self, obj, objtype=None): | 
					
						
							|  |  |  |                 raise RuntimeError("NO") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D: | 
					
						
							|  |  |  |             attr = CustomDescriptor() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Check that properties set on superclasses | 
					
						
							|  |  |  |         # are still found by the isinstance() logic | 
					
						
							|  |  |  |         class E(C): ... | 
					
						
							|  |  |  |         class F(D): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class WhyWouldYouDoThis: | 
					
						
							|  |  |  |             def __getattr__(self, name): | 
					
						
							|  |  |  |                 raise RuntimeError("wut") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             def attr(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class P1(Protocol): | 
					
						
							|  |  |  |             attr: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PG(Protocol[T]): | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             def attr(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class PG1(Protocol[T]): | 
					
						
							|  |  |  |             attr: T | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class MethodP(Protocol): | 
					
						
							|  |  |  |             def attr(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class MethodPG(Protocol[T]): | 
					
						
							|  |  |  |             def attr(self) -> T: ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for protocol_class in P, P1, PG, PG1, MethodP, MethodPG: | 
					
						
							|  |  |  |             for klass in C, D, E, F: | 
					
						
							|  |  |  |                 with self.subTest( | 
					
						
							|  |  |  |                     klass=klass.__name__, | 
					
						
							|  |  |  |                     protocol_class=protocol_class.__name__ | 
					
						
							|  |  |  |                 ): | 
					
						
							|  |  |  |                     self.assertIsInstance(klass(), protocol_class) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             with self.subTest( | 
					
						
							|  |  |  |                 klass="WhyWouldYouDoThis", | 
					
						
							|  |  |  |                 protocol_class=protocol_class.__name__ | 
					
						
							|  |  |  |             ): | 
					
						
							|  |  |  |                 self.assertNotIsInstance(WhyWouldYouDoThis(), protocol_class) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_protocols_isinstance___slots__(self): | 
					
						
							|  |  |  |         # As per the consensus in https://github.com/python/typing/issues/1367, | 
					
						
							|  |  |  |         # this is desirable behaviour | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class HasX(Protocol): | 
					
						
							|  |  |  |             x: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class HasNothingButSlots: | 
					
						
							|  |  |  |             __slots__ = ("x",) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(HasNothingButSlots(), HasX) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |     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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 18:21:19 +01:00
										 |  |  |     def test_protocols_isinstance_monkeypatching(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class HasX(Protocol): | 
					
						
							|  |  |  |             x: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Foo: ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         f = Foo() | 
					
						
							|  |  |  |         self.assertNotIsInstance(f, HasX) | 
					
						
							|  |  |  |         f.x = 42 | 
					
						
							|  |  |  |         self.assertIsInstance(f, HasX) | 
					
						
							|  |  |  |         del f.x | 
					
						
							|  |  |  |         self.assertNotIsInstance(f, HasX) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-21 01:13:37 +01:00
										 |  |  |         class C(metaclass=abc.ABCMeta): | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |             x = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-21 01:13:37 +01:00
										 |  |  |         class D(metaclass=abc.ABCMeta): | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |             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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 00:34:40 +01:00
										 |  |  |         self.assertNotIn("__protocol_attrs__", vars(NonP)) | 
					
						
							|  |  |  |         self.assertNotIn("__protocol_attrs__", vars(NonPR)) | 
					
						
							|  |  |  |         self.assertNotIn("__callable_proto_members_only__", vars(NonP)) | 
					
						
							|  |  |  |         self.assertNotIn("__callable_proto_members_only__", vars(NonPR)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         acceptable_extra_attrs = { | 
					
						
							|  |  |  |             '_is_protocol', '_is_runtime_protocol', '__parameters__', | 
					
						
							| 
									
										
										
										
											2023-05-21 01:13:37 +01:00
										 |  |  |             '__init__', '__annotations__', '__subclasshook__', | 
					
						
							| 
									
										
										
										
											2023-05-19 00:34:40 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         self.assertLessEqual(vars(NonP).keys(), vars(C).keys() | acceptable_extra_attrs) | 
					
						
							|  |  |  |         self.assertLessEqual( | 
					
						
							|  |  |  |             vars(NonPR).keys(), vars(D).keys() | acceptable_extra_attrs | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |     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] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-16 17:38:10 +01:00
										 |  |  |     def test_pep695_generic_protocol_callable_members(self): | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class Foo[T](Protocol): | 
					
						
							|  |  |  |             def meth(self, x: T) -> None: ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Bar[T]: | 
					
						
							|  |  |  |             def meth(self, x: T) -> None: ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(Bar(), Foo) | 
					
						
							|  |  |  |         self.assertIsSubclass(Bar, Foo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @runtime_checkable | 
					
						
							|  |  |  |         class SupportsTrunc[T](Protocol): | 
					
						
							|  |  |  |             def __trunc__(self) -> T: ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsInstance(0.0, SupportsTrunc) | 
					
						
							|  |  |  |         self.assertIsSubclass(float, SupportsTrunc) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |     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') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-02 19:23:22 +03:00
										 |  |  |         class B: | 
					
						
							|  |  |  |             def __init__(self): | 
					
						
							|  |  |  |                 self.test = 'OK' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D1(B, P[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(D1[int]().test, 'OK') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class D2(P[T], B): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(D2[int]().test, 'OK') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_new_called(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class P(Protocol[T]): pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(P[T]): | 
					
						
							|  |  |  |             def __new__(cls, *args): | 
					
						
							|  |  |  |                 self = super().__new__(cls, *args) | 
					
						
							|  |  |  |                 self.test = 'OK' | 
					
						
							|  |  |  |                 return self | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(C[int]().test, 'OK') | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             C[int](42) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             C[int](a=42) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |     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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-05 15:07:44 +00:00
										 |  |  |         self.assertIsInstance(CI(), P) | 
					
						
							|  |  |  |         self.assertIsInstance(DI(), P) | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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'}) | 
					
						
							| 
									
										
										
										
											2022-11-06 14:53:57 +03:00
										 |  |  |             s = pickle.dumps(P, proto) | 
					
						
							| 
									
										
										
										
											2019-05-28 08:40:15 +01:00
										 |  |  |             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): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             def __complex__(self): | 
					
						
							|  |  |  |                 return 0j | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-23 09:15:49 +01:00
										 |  |  |         self.assertIsSubclass(complex, typing.SupportsComplex) | 
					
						
							| 
									
										
										
										
											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): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class B: | 
					
						
							|  |  |  |             def __bytes__(self): | 
					
						
							|  |  |  |                 return b'' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-23 10:01:51 +00:00
										 |  |  |         self.assertIsSubclass(bytes, typing.SupportsBytes) | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-11 15:28:43 +02:00
										 |  |  |     def test_builtin_protocol_allowlist(self): | 
					
						
							| 
									
										
										
										
											2019-09-12 11:13:51 +01:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class CustomProtocol(TestCase, Protocol): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CustomContextManager(typing.ContextManager, Protocol): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-12 18:47:49 +03:00
										 |  |  |     def test_non_runtime_protocol_isinstance_check(self): | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             x: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, "@runtime_checkable"): | 
					
						
							|  |  |  |             isinstance(1, P) | 
					
						
							| 
									
										
										
										
											2021-09-08 13:25:09 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_super_call_init(self): | 
					
						
							|  |  |  |         class P(Protocol): | 
					
						
							|  |  |  |             x: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Foo(P): | 
					
						
							|  |  |  |             def __init__(self): | 
					
						
							|  |  |  |                 super().__init__() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Foo()  # Previously triggered RecursionError | 
					
						
							| 
									
										
										
										
											2021-05-12 18:47:49 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							| 
									
										
										
										
											2021-07-17 06:33:40 +03:00
										 |  |  |         T = TypeVar("T") | 
					
						
							|  |  |  |         self.assertEqual(List[list[T] | float].__parameters__, (T,)) | 
					
						
							| 
									
										
										
										
											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') | 
					
						
							|  |  |  |         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]): ... | 
					
						
							| 
									
										
										
										
											2022-03-08 04:02:55 +00:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Generic[()] | 
					
						
							|  |  |  |         class C(Generic[T]): pass | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             C[()] | 
					
						
							| 
									
										
										
										
											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]]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-13 16:09:40 +03:00
										 |  |  |         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]]')) | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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][()] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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
										 |  |  |         self.assertEqual(Callable[[T], T][KT], Callable[[KT], KT]) | 
					
						
							|  |  |  |         self.assertEqual(Callable[..., List[T]][int], Callable[..., List[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.', ''), | 
					
						
							| 
									
										
										
										
											2020-04-30 04:06:39 +03:00
										 |  |  |                          'Callable[..., Optional[int]]') | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |         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']]): ... | 
					
						
							| 
									
										
										
										
											2020-04-26 21:21:08 +03:00
										 |  |  |         def foobar2(x: list[list[ForwardRef('CC')]]): ... | 
					
						
							| 
									
										
										
										
											2021-07-17 06:33:40 +03:00
										 |  |  |         def foobar3(x: list[ForwardRef('CC | int')] | int): ... | 
					
						
							| 
									
										
										
										
											2016-11-09 13:18:59 -08:00
										 |  |  |         class CC: ... | 
					
						
							| 
									
										
										
										
											2017-01-22 17:43:53 -08:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(foobar, globals(), locals()), | 
					
						
							|  |  |  |             {'x': List[List[CC]]} | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-04-26 21:21:08 +03:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(foobar2, globals(), locals()), | 
					
						
							|  |  |  |             {'x': list[list[CC]]} | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-07-17 06:33:40 +03:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(foobar3, globals(), locals()), | 
					
						
							|  |  |  |             {'x': list[CC | int] | int} | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-04-26 21:21:08 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-07 19:02:59 +01:00
										 |  |  |     def test_generic_pep585_forward_ref(self): | 
					
						
							|  |  |  |         # See https://bugs.python.org/issue41370 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C1: | 
					
						
							|  |  |  |             a: list['C1'] | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(C1, globals(), locals()), | 
					
						
							|  |  |  |             {'a': list[C1]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C2: | 
					
						
							|  |  |  |             a: dict['C1', list[List[list['C2']]]] | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(C2, globals(), locals()), | 
					
						
							|  |  |  |             {'a': dict[C1, list[List[list[C2]]]]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Test stringified annotations | 
					
						
							|  |  |  |         scope = {} | 
					
						
							|  |  |  |         exec(textwrap.dedent('''
 | 
					
						
							|  |  |  |         from __future__ import annotations | 
					
						
							|  |  |  |         class C3: | 
					
						
							|  |  |  |             a: List[list["C2"]] | 
					
						
							|  |  |  |         '''), scope)
 | 
					
						
							|  |  |  |         C3 = scope['C3'] | 
					
						
							|  |  |  |         self.assertEqual(C3.__annotations__['a'], "List[list['C2']]") | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(C3, globals(), locals()), | 
					
						
							|  |  |  |             {'a': List[list[C2]]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Test recursive types | 
					
						
							|  |  |  |         X = list["X"] | 
					
						
							|  |  |  |         def f(x: X): ... | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(f, globals(), locals()), | 
					
						
							|  |  |  |             {'x': list[list[ForwardRef('X')]]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |     def test_extended_generic_rules_subclassing(self): | 
					
						
							|  |  |  |         class T1(Tuple[T, KT]): ... | 
					
						
							|  |  |  |         class T2(Tuple[T, ...]): ... | 
					
						
							| 
									
										
										
										
											2020-12-14 02:38:24 +08:00
										 |  |  |         class C1(typing.Container[T]): | 
					
						
							|  |  |  |             def __contains__(self, item): | 
					
						
							|  |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         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]') | 
					
						
							| 
									
										
										
										
											2020-12-14 02:38:24 +08:00
										 |  |  |         self.assertEqual(C1.__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertIsInstance(C1(), collections.abc.Container) | 
					
						
							|  |  |  |         self.assertIsSubclass(C1, collections.abc.Container) | 
					
						
							| 
									
										
										
										
											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): | 
					
						
							| 
									
										
										
										
											2022-01-28 08:58:39 -08:00
										 |  |  |             ClassVar[ClassVar[int]] | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |         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 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]) | 
					
						
							| 
									
										
										
										
											2022-01-13 16:09:40 +03:00
										 |  |  |         class MyChain(typing.ChainMap[str, T]): ... | 
					
						
							|  |  |  |         self.assertIs(MyChain[int]().__class__, MyChain) | 
					
						
							|  |  |  |         self.assertEqual(MyChain[int]().__orig_class__, MyChain[int]) | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_all_repr_eq_any(self): | 
					
						
							| 
									
										
										
										
											2023-05-13 09:55:35 +01:00
										 |  |  |         objs = (getattr(typing, el) for el in typing.__all__) | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |         for obj in objs: | 
					
						
							|  |  |  |             self.assertNotEqual(repr(obj), '') | 
					
						
							|  |  |  |             self.assertEqual(obj, obj) | 
					
						
							| 
									
										
										
										
											2022-03-11 10:47:26 +02:00
										 |  |  |             if (getattr(obj, '__parameters__', None) | 
					
						
							|  |  |  |                     and not isinstance(obj, typing.TypeVar) | 
					
						
							|  |  |  |                     and isinstance(obj.__parameters__, tuple) | 
					
						
							|  |  |  |                     and len(obj.__parameters__) == 1): | 
					
						
							| 
									
										
										
										
											2016-10-29 08:54:56 -07:00
										 |  |  |                 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, | 
					
						
							| 
									
										
										
										
											2022-06-25 18:46:33 +03:00
										 |  |  |                    Union[int, str], ClassVar[List], Tuple[int, ...], Tuple[()], | 
					
						
							|  |  |  |                    Callable[[str], bytes], | 
					
						
							| 
									
										
										
										
											2018-04-05 01:25:15 +01:00
										 |  |  |                    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]): ... | 
					
						
							| 
									
										
										
										
											2022-06-25 18:46:33 +03:00
										 |  |  |         things = [Union[T, int], Tuple[T, int], Tuple[()], | 
					
						
							|  |  |  |                   Callable[..., T], Callable[[int], int], | 
					
						
							| 
									
										
										
										
											2016-10-29 12:44:29 -07:00
										 |  |  |                   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. | 
					
						
							| 
									
										
										
										
											2022-01-16 10:32:11 +03:00
										 |  |  |         global TP, TPB, TPV, PP  # for pickle | 
					
						
							| 
									
										
										
										
											2018-03-26 23:01:12 +01:00
										 |  |  |         TP = TypeVar('TP') | 
					
						
							|  |  |  |         TPB = TypeVar('TPB', bound=int) | 
					
						
							|  |  |  |         TPV = TypeVar('TPV', bytes, str) | 
					
						
							| 
									
										
										
										
											2022-01-16 10:32:11 +03:00
										 |  |  |         PP = ParamSpec('PP') | 
					
						
							|  |  |  |         for X in [TP, TPB, TPV, PP, | 
					
						
							|  |  |  |                   List, typing.Mapping, ClassVar, typing.Iterable, | 
					
						
							| 
									
										
										
										
											2018-03-26 23:01:12 +01:00
										 |  |  |                   Union, Any, Tuple, Callable]: | 
					
						
							| 
									
										
										
										
											2022-01-16 10:32:11 +03:00
										 |  |  |             with self.subTest(thing=X): | 
					
						
							|  |  |  |                 self.assertIs(copy(X), X) | 
					
						
							|  |  |  |                 self.assertIs(deepcopy(X), X) | 
					
						
							|  |  |  |                 for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |                     self.assertIs(pickle.loads(pickle.dumps(X, proto)), X) | 
					
						
							|  |  |  |         del TP, TPB, TPV, PP | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-26 23:01:12 +01:00
										 |  |  |         # Check that local type variables are copyable. | 
					
						
							|  |  |  |         TL = TypeVar('TL') | 
					
						
							|  |  |  |         TLB = TypeVar('TLB', bound=int) | 
					
						
							|  |  |  |         TLV = TypeVar('TLV', bytes, str) | 
					
						
							| 
									
										
										
										
											2022-01-16 10:32:11 +03:00
										 |  |  |         PL = ParamSpec('PL') | 
					
						
							|  |  |  |         for X in [TL, TLB, TLV, PL]: | 
					
						
							|  |  |  |             with self.subTest(thing=X): | 
					
						
							|  |  |  |                 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], | 
					
						
							| 
									
										
										
										
											2021-06-19 19:31:18 +02:00
										 |  |  |                   typing.Match[bytes], typing.Iterable['whatever']] | 
					
						
							| 
									
										
										
										
											2017-01-17 20:43:28 -08:00
										 |  |  |         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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-15 12:33:41 +03:00
										 |  |  |     def test_repr_3(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         T1 = TypeVar('T1') | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         P2 = ParamSpec('P2') | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MyCallable(Generic[P, T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class DoubleSpec(Generic[P, P2, T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class TsP(Generic[*Ts, P]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         object_to_expected_repr = { | 
					
						
							|  |  |  |             MyCallable[P, T]:                         "MyCallable[~P, ~T]", | 
					
						
							|  |  |  |             MyCallable[Concatenate[T1, P], T]:        "MyCallable[typing.Concatenate[~T1, ~P], ~T]", | 
					
						
							|  |  |  |             MyCallable[[], bool]:                     "MyCallable[[], bool]", | 
					
						
							|  |  |  |             MyCallable[[int], bool]:                  "MyCallable[[int], bool]", | 
					
						
							|  |  |  |             MyCallable[[int, str], bool]:             "MyCallable[[int, str], bool]", | 
					
						
							|  |  |  |             MyCallable[[int, list[int]], bool]:       "MyCallable[[int, list[int]], bool]", | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |             MyCallable[Concatenate[*Ts, P], T]:       "MyCallable[typing.Concatenate[typing.Unpack[Ts], ~P], ~T]", | 
					
						
							| 
									
										
										
										
											2023-03-15 12:33:41 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |             DoubleSpec[P2, P, T]:                     "DoubleSpec[~P2, ~P, ~T]", | 
					
						
							|  |  |  |             DoubleSpec[[int], [str], bool]:           "DoubleSpec[[int], [str], bool]", | 
					
						
							|  |  |  |             DoubleSpec[[int, int], [str, str], bool]: "DoubleSpec[[int, int], [str, str], bool]", | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-01 19:58:50 +02:00
										 |  |  |             TsP[*Ts, P]:                              "TsP[typing.Unpack[Ts], ~P]", | 
					
						
							| 
									
										
										
										
											2023-03-15 12:33:41 +03:00
										 |  |  |             TsP[int, str, list[int], []]:             "TsP[int, str, list[int], []]", | 
					
						
							|  |  |  |             TsP[int, [str, list[int]]]:               "TsP[int, [str, list[int]]]", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # These lines are just too long to fit: | 
					
						
							|  |  |  |             MyCallable[Concatenate[*Ts, P], int][int, str, [bool, float]]: | 
					
						
							|  |  |  |                                                       "MyCallable[[int, str, bool, float], int]", | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for obj, expected_repr in object_to_expected_repr.items(): | 
					
						
							|  |  |  |             with self.subTest(obj=obj, expected_repr=expected_repr): | 
					
						
							|  |  |  |                 self.assertRegex( | 
					
						
							|  |  |  |                     repr(obj), | 
					
						
							|  |  |  |                     fr"^{re.escape(MyCallable.__module__)}.*\.{re.escape(expected_repr)}$", | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 16:33:34 +03:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |             D[int] | 
					
						
							| 
									
										
										
										
											2022-10-25 16:33:34 +03:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |             D[Any] | 
					
						
							| 
									
										
										
										
											2022-10-25 16:33:34 +03:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  |             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') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-18 22:08:32 +03:00
										 |  |  |     def test_subclass_special_form(self): | 
					
						
							|  |  |  |         for obj in ( | 
					
						
							|  |  |  |             ClassVar[int], | 
					
						
							|  |  |  |             Final[int], | 
					
						
							|  |  |  |             Union[int, float], | 
					
						
							|  |  |  |             Optional[int], | 
					
						
							|  |  |  |             Literal[1, 2], | 
					
						
							|  |  |  |             Concatenate[int, ParamSpec("P")], | 
					
						
							|  |  |  |             TypeGuard[int], | 
					
						
							|  |  |  |         ): | 
					
						
							|  |  |  |             with self.subTest(msg=obj): | 
					
						
							|  |  |  |                 with self.assertRaisesRegex( | 
					
						
							|  |  |  |                         TypeError, f'^{re.escape(f"Cannot subclass {obj!r}")}$' | 
					
						
							|  |  |  |                 ): | 
					
						
							|  |  |  |                     class Foo(obj): | 
					
						
							|  |  |  |                         pass | 
					
						
							| 
									
										
										
										
											2017-01-22 17:43:53 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-09 12:18:01 +08:00
										 |  |  |     def test_complex_subclasses(self): | 
					
						
							|  |  |  |         T_co = TypeVar("T_co", covariant=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Base(Generic[T_co]): | 
					
						
							|  |  |  |             ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         T = TypeVar("T") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # see gh-94607: this fails in that bug | 
					
						
							|  |  |  |         class Sub(Base, Generic[T]): | 
					
						
							|  |  |  |             ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_parameter_detection(self): | 
					
						
							|  |  |  |         self.assertEqual(List[T].__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(List[List[T]].__parameters__, (T,)) | 
					
						
							|  |  |  |         class A: | 
					
						
							|  |  |  |             __parameters__ = (T,) | 
					
						
							|  |  |  |         # Bare classes should be skipped | 
					
						
							|  |  |  |         for a in (List, list): | 
					
						
							|  |  |  |             for b in (A, int, TypeVar, TypeVarTuple, ParamSpec, types.GenericAlias, types.UnionType): | 
					
						
							|  |  |  |                 with self.subTest(generic=a, sub=b): | 
					
						
							|  |  |  |                     with self.assertRaisesRegex(TypeError, '.* is not a generic class'): | 
					
						
							|  |  |  |                         a[b][str] | 
					
						
							|  |  |  |         # Duck-typing anything that looks like it has __parameters__. | 
					
						
							|  |  |  |         # These tests are optional and failure is okay. | 
					
						
							|  |  |  |         self.assertEqual(List[A()].__parameters__, (T,)) | 
					
						
							|  |  |  |         # C version of GenericAlias | 
					
						
							|  |  |  |         self.assertEqual(list[A()].__parameters__, (T,)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-01 09:33:09 +02:00
										 |  |  |     def test_non_generic_subscript(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         class G(Generic[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         class A: | 
					
						
							|  |  |  |             __parameters__ = (T,) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for s in (int, G, A, List, list, | 
					
						
							|  |  |  |                   TypeVar, TypeVarTuple, ParamSpec, | 
					
						
							|  |  |  |                   types.GenericAlias, types.UnionType): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for t in Tuple, tuple: | 
					
						
							|  |  |  |                 with self.subTest(tuple=t, sub=s): | 
					
						
							|  |  |  |                     self.assertEqual(t[s, T][int], t[s, int]) | 
					
						
							|  |  |  |                     self.assertEqual(t[T, s][int], t[int, s]) | 
					
						
							|  |  |  |                     a = t[s] | 
					
						
							|  |  |  |                     with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                         a[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for c in Callable, collections.abc.Callable: | 
					
						
							|  |  |  |                 with self.subTest(callable=c, sub=s): | 
					
						
							|  |  |  |                     self.assertEqual(c[[s], T][int], c[[s], int]) | 
					
						
							|  |  |  |                     self.assertEqual(c[[T], s][int], c[[int], s]) | 
					
						
							|  |  |  |                     a = c[[s], s] | 
					
						
							|  |  |  |                     with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                         a[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | class ClassVarTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         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): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |             class C(type(ClassVar)): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  |             class C(type(ClassVar[int])): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:16 +03:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                                     r'Cannot subclass typing\.ClassVar'): | 
					
						
							|  |  |  |             class C(ClassVar): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                                     r'Cannot subclass typing\.ClassVar\[int\]'): | 
					
						
							|  |  |  |             class C(ClassVar[int]): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:07 +01:00
										 |  |  | class FinalTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         Final[int]  # OK | 
					
						
							|  |  |  |         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__) | 
					
						
							| 
									
										
										
										
											2020-11-02 02:13:38 +08:00
										 |  |  |         cv = Final[tuple[int]] | 
					
						
							|  |  |  |         self.assertEqual(repr(cv), 'typing.Final[tuple[int]]') | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:07 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:07 +01:00
										 |  |  |             class C(type(Final)): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:07 +01:00
										 |  |  |             class C(type(Final[int])): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:16 +03:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 r'Cannot subclass typing\.Final'): | 
					
						
							|  |  |  |             class C(Final): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 r'Cannot subclass typing\.Final\[int\]'): | 
					
						
							|  |  |  |             class C(Final[int]): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:07 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-12 11:38:25 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class FinalDecoratorTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:07 +01:00
										 |  |  |     def test_final_unmodified(self): | 
					
						
							|  |  |  |         def func(x): ... | 
					
						
							|  |  |  |         self.assertIs(func, final(func)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-12 11:38:25 -08:00
										 |  |  |     def test_dunder_final(self): | 
					
						
							|  |  |  |         @final | 
					
						
							|  |  |  |         def func(): ... | 
					
						
							|  |  |  |         @final | 
					
						
							|  |  |  |         class Cls: ... | 
					
						
							|  |  |  |         self.assertIs(True, func.__final__) | 
					
						
							|  |  |  |         self.assertIs(True, Cls.__final__) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Wrapper: | 
					
						
							|  |  |  |             __slots__ = ("func",) | 
					
						
							|  |  |  |             def __init__(self, func): | 
					
						
							|  |  |  |                 self.func = func | 
					
						
							|  |  |  |             def __call__(self, *args, **kwargs): | 
					
						
							|  |  |  |                 return self.func(*args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Check that no error is thrown if the attribute | 
					
						
							|  |  |  |         # is not writable. | 
					
						
							|  |  |  |         @final | 
					
						
							|  |  |  |         @Wrapper | 
					
						
							|  |  |  |         def wrapped(): ... | 
					
						
							|  |  |  |         self.assertIsInstance(wrapped, Wrapper) | 
					
						
							|  |  |  |         self.assertIs(False, hasattr(wrapped, "__final__")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Meta(type): | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             def __final__(self): return "can't set me" | 
					
						
							|  |  |  |         @final | 
					
						
							|  |  |  |         class WithMeta(metaclass=Meta): ... | 
					
						
							|  |  |  |         self.assertEqual(WithMeta.__final__, "can't set me") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Builtin classes throw TypeError if you try to set an | 
					
						
							|  |  |  |         # attribute. | 
					
						
							|  |  |  |         final(int) | 
					
						
							|  |  |  |         self.assertIs(False, hasattr(int, "__final__")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Make sure it works with common builtin decorators | 
					
						
							|  |  |  |         class Methods: | 
					
						
							|  |  |  |             @final | 
					
						
							|  |  |  |             @classmethod | 
					
						
							|  |  |  |             def clsmethod(cls): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @final | 
					
						
							|  |  |  |             @staticmethod | 
					
						
							|  |  |  |             def stmethod(): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # The other order doesn't work because property objects | 
					
						
							|  |  |  |             # don't allow attribute assignment. | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             @final | 
					
						
							|  |  |  |             def prop(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @final | 
					
						
							|  |  |  |             @lru_cache() | 
					
						
							|  |  |  |             def cached(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Use getattr_static because the descriptor returns the | 
					
						
							|  |  |  |         # underlying function, which doesn't have __final__. | 
					
						
							|  |  |  |         self.assertIs( | 
					
						
							|  |  |  |             True, | 
					
						
							|  |  |  |             inspect.getattr_static(Methods, "clsmethod").__final__ | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertIs( | 
					
						
							|  |  |  |             True, | 
					
						
							|  |  |  |             inspect.getattr_static(Methods, "stmethod").__final__ | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertIs(True, Methods.prop.fget.__final__) | 
					
						
							|  |  |  |         self.assertIs(True, Methods.cached.__final__) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:37:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-27 13:16:11 -08:00
										 |  |  | class OverrideDecoratorTests(BaseTestCase): | 
					
						
							|  |  |  |     def test_override(self): | 
					
						
							|  |  |  |         class Base: | 
					
						
							|  |  |  |             def normal_method(self): ... | 
					
						
							| 
									
										
										
										
											2023-03-03 06:59:05 +03:00
										 |  |  |             @classmethod | 
					
						
							|  |  |  |             def class_method_good_order(cls): ... | 
					
						
							|  |  |  |             @classmethod | 
					
						
							|  |  |  |             def class_method_bad_order(cls): ... | 
					
						
							| 
									
										
										
										
											2023-02-27 13:16:11 -08:00
										 |  |  |             @staticmethod | 
					
						
							|  |  |  |             def static_method_good_order(): ... | 
					
						
							|  |  |  |             @staticmethod | 
					
						
							|  |  |  |             def static_method_bad_order(): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Derived(Base): | 
					
						
							|  |  |  |             @override | 
					
						
							|  |  |  |             def normal_method(self): | 
					
						
							|  |  |  |                 return 42 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-03 06:59:05 +03:00
										 |  |  |             @classmethod | 
					
						
							|  |  |  |             @override | 
					
						
							|  |  |  |             def class_method_good_order(cls): | 
					
						
							|  |  |  |                 return 42 | 
					
						
							|  |  |  |             @override | 
					
						
							|  |  |  |             @classmethod | 
					
						
							|  |  |  |             def class_method_bad_order(cls): | 
					
						
							|  |  |  |                 return 42 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-27 13:16:11 -08:00
										 |  |  |             @staticmethod | 
					
						
							|  |  |  |             @override | 
					
						
							|  |  |  |             def static_method_good_order(): | 
					
						
							|  |  |  |                 return 42 | 
					
						
							|  |  |  |             @override | 
					
						
							|  |  |  |             @staticmethod | 
					
						
							|  |  |  |             def static_method_bad_order(): | 
					
						
							|  |  |  |                 return 42 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIsSubclass(Derived, Base) | 
					
						
							|  |  |  |         instance = Derived() | 
					
						
							|  |  |  |         self.assertEqual(instance.normal_method(), 42) | 
					
						
							| 
									
										
										
										
											2023-03-03 06:59:05 +03:00
										 |  |  |         self.assertIs(True, Derived.normal_method.__override__) | 
					
						
							| 
									
										
										
										
											2023-02-27 13:16:11 -08:00
										 |  |  |         self.assertIs(True, instance.normal_method.__override__) | 
					
						
							| 
									
										
										
										
											2023-03-03 06:59:05 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(Derived.class_method_good_order(), 42) | 
					
						
							|  |  |  |         self.assertIs(True, Derived.class_method_good_order.__override__) | 
					
						
							|  |  |  |         self.assertEqual(Derived.class_method_bad_order(), 42) | 
					
						
							|  |  |  |         self.assertIs(False, hasattr(Derived.class_method_bad_order, "__override__")) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-27 13:16:11 -08:00
										 |  |  |         self.assertEqual(Derived.static_method_good_order(), 42) | 
					
						
							|  |  |  |         self.assertIs(True, Derived.static_method_good_order.__override__) | 
					
						
							|  |  |  |         self.assertEqual(Derived.static_method_bad_order(), 42) | 
					
						
							|  |  |  |         self.assertIs(False, hasattr(Derived.static_method_bad_order, "__override__")) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-03 06:59:05 +03:00
										 |  |  |         # Base object is not changed: | 
					
						
							|  |  |  |         self.assertIs(False, hasattr(Base.normal_method, "__override__")) | 
					
						
							|  |  |  |         self.assertIs(False, hasattr(Base.class_method_good_order, "__override__")) | 
					
						
							|  |  |  |         self.assertIs(False, hasattr(Base.class_method_bad_order, "__override__")) | 
					
						
							|  |  |  |         self.assertIs(False, hasattr(Base.static_method_good_order, "__override__")) | 
					
						
							|  |  |  |         self.assertIs(False, hasattr(Base.static_method_bad_order, "__override__")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_property(self): | 
					
						
							|  |  |  |         class Base: | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             def correct(self) -> int: | 
					
						
							|  |  |  |                 return 1 | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             def wrong(self) -> int: | 
					
						
							|  |  |  |                 return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Child(Base): | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             @override | 
					
						
							|  |  |  |             def correct(self) -> int: | 
					
						
							|  |  |  |                 return 2 | 
					
						
							|  |  |  |             @override | 
					
						
							|  |  |  |             @property | 
					
						
							|  |  |  |             def wrong(self) -> int: | 
					
						
							|  |  |  |                 return 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         instance = Child() | 
					
						
							|  |  |  |         self.assertEqual(instance.correct, 2) | 
					
						
							|  |  |  |         self.assertTrue(Child.correct.fget.__override__) | 
					
						
							|  |  |  |         self.assertEqual(instance.wrong, 2) | 
					
						
							|  |  |  |         self.assertFalse(hasattr(Child.wrong, "__override__")) | 
					
						
							|  |  |  |         self.assertFalse(hasattr(Child.wrong.fset, "__override__")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_silent_failure(self): | 
					
						
							|  |  |  |         class CustomProp: | 
					
						
							|  |  |  |             __slots__ = ('fget',) | 
					
						
							|  |  |  |             def __init__(self, fget): | 
					
						
							|  |  |  |                 self.fget = fget | 
					
						
							|  |  |  |             def __get__(self, obj, objtype=None): | 
					
						
							|  |  |  |                 return self.fget(obj) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class WithOverride: | 
					
						
							|  |  |  |             @override  # must not fail on object with `__slots__` | 
					
						
							|  |  |  |             @CustomProp | 
					
						
							|  |  |  |             def some(self): | 
					
						
							|  |  |  |                 return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(WithOverride.some, 1) | 
					
						
							|  |  |  |         self.assertFalse(hasattr(WithOverride.some, "__override__")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_multiple_decorators(self): | 
					
						
							|  |  |  |         import functools | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def with_wraps(f):  # similar to `lru_cache` definition | 
					
						
							|  |  |  |             @functools.wraps(f) | 
					
						
							|  |  |  |             def wrapper(*args, **kwargs): | 
					
						
							|  |  |  |                 return f(*args, **kwargs) | 
					
						
							|  |  |  |             return wrapper | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class WithOverride: | 
					
						
							|  |  |  |             @override | 
					
						
							|  |  |  |             @with_wraps | 
					
						
							|  |  |  |             def on_top(self, a: int) -> int: | 
					
						
							|  |  |  |                 return a + 1 | 
					
						
							|  |  |  |             @with_wraps | 
					
						
							|  |  |  |             @override | 
					
						
							|  |  |  |             def on_bottom(self, a: int) -> int: | 
					
						
							|  |  |  |                 return a + 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         instance = WithOverride() | 
					
						
							|  |  |  |         self.assertEqual(instance.on_top(1), 2) | 
					
						
							|  |  |  |         self.assertTrue(instance.on_top.__override__) | 
					
						
							|  |  |  |         self.assertEqual(instance.on_bottom(1), 3) | 
					
						
							|  |  |  |         self.assertTrue(instance.on_bottom.__override__) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-27 13:16:11 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-16 20:02:26 -07:00
										 |  |  | class AssertTypeTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         arg = 42 | 
					
						
							|  |  |  |         self.assertIs(assert_type(arg, int), arg) | 
					
						
							|  |  |  |         self.assertIs(assert_type(arg, str | float), arg) | 
					
						
							|  |  |  |         self.assertIs(assert_type(arg, AnyStr), arg) | 
					
						
							|  |  |  |         self.assertIs(assert_type(arg, None), arg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_errors(self): | 
					
						
							|  |  |  |         # Bogus calls are not expected to fail. | 
					
						
							|  |  |  |         arg = 42 | 
					
						
							|  |  |  |         self.assertIs(assert_type(arg, 42), arg) | 
					
						
							|  |  |  |         self.assertIs(assert_type(arg, 'hello'), arg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 04:53:29 +03:00
										 |  |  | # We need this to make sure that `@no_type_check` respects `__module__` attr: | 
					
						
							|  |  |  | from test import ann_module8 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @no_type_check | 
					
						
							|  |  |  | class NoTypeCheck_Outer: | 
					
						
							|  |  |  |     Inner = ann_module8.NoTypeCheck_Outer.Inner | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @no_type_check | 
					
						
							|  |  |  | class NoTypeCheck_WithFunction: | 
					
						
							|  |  |  |     NoTypeCheck_function = ann_module8.NoTypeCheck_function | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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]]) | 
					
						
							| 
									
										
										
										
											2022-03-02 08:29:46 +03:00
										 |  |  |         self.assertEqual(both_hints['right'], Node[T]) | 
					
						
							|  |  |  |         self.assertEqual(both_hints['stuff'], int) | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         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()) | 
					
						
							| 
									
										
										
										
											2022-03-02 08:29:46 +03:00
										 |  |  |         self.assertEqual(right_hints['node'], 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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-09 17:23:07 +03:00
										 |  |  |     def test_forwardref_only_str_arg(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             typing.ForwardRef(1)  # only `str` type is allowed | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |     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]) | 
					
						
							| 
									
										
										
										
											2022-02-17 04:28:18 +01:00
										 |  |  |         self.assertNotEqual(fr, typing.ForwardRef('int', module=__name__)) | 
					
						
							|  |  |  |         frm = typing.ForwardRef('int', module=__name__) | 
					
						
							|  |  |  |         self.assertEqual(frm, typing.ForwardRef('int', module=__name__)) | 
					
						
							|  |  |  |         self.assertNotEqual(frm, typing.ForwardRef('int', module='__other_name__')) | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-17 04:28:18 +01:00
										 |  |  |         c3 = typing.ForwardRef('int', module=__name__) | 
					
						
							|  |  |  |         c4 = typing.ForwardRef('int', module='__other_name__') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertNotEqual(hash(c3), hash(c1)) | 
					
						
							|  |  |  |         self.assertNotEqual(hash(c3), hash(c1_gth)) | 
					
						
							|  |  |  |         self.assertNotEqual(hash(c3), hash(c4)) | 
					
						
							|  |  |  |         self.assertEqual(hash(c3), hash(typing.ForwardRef('int', module=__name__))) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-13 20:40:54 +01:00
										 |  |  |     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')]") | 
					
						
							| 
									
										
										
										
											2022-03-05 17:47:00 +02:00
										 |  |  |         self.assertEqual(repr(List[ForwardRef('int', module='mod')]), | 
					
						
							|  |  |  |                          "typing.List[ForwardRef('int', module='mod')]") | 
					
						
							| 
									
										
										
										
											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]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-17 06:33:40 +03:00
										 |  |  |         def foo(a: tuple[ForwardRef('T')] | int): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(foo, globals(), locals()), | 
					
						
							|  |  |  |                          {'a': tuple[T] | int}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |     def test_tuple_forward(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(a: Tuple['T']): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(foo, globals(), locals()), | 
					
						
							|  |  |  |                          {'a': Tuple[T]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-26 21:21:08 +03:00
										 |  |  |         def foo(a: tuple[ForwardRef('T')]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(foo, globals(), locals()), | 
					
						
							|  |  |  |                          {'a': tuple[T]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-22 21:47:28 +02:00
										 |  |  |     def test_double_forward(self): | 
					
						
							|  |  |  |         def foo(a: 'List[\'int\']'): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(foo, globals(), locals()), | 
					
						
							|  |  |  |                          {'a': List[int]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 19:11:51 -08:00
										 |  |  |     def test_special_forms_forward(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             a: Annotated['ClassVar[int]', (3, 5)] = 4 | 
					
						
							|  |  |  |             b: Annotated['Final[int]', "const"] = 4 | 
					
						
							| 
									
										
										
										
											2022-01-28 08:58:39 -08:00
										 |  |  |             x: 'ClassVar' = 4 | 
					
						
							|  |  |  |             y: 'Final' = 4 | 
					
						
							| 
									
										
										
										
											2022-01-26 19:11:51 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         class CF: | 
					
						
							|  |  |  |             b: List['Final[int]'] = 4 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(C, globals())['a'], ClassVar[int]) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(C, globals())['b'], Final[int]) | 
					
						
							| 
									
										
										
										
											2022-01-28 08:58:39 -08:00
										 |  |  |         self.assertEqual(get_type_hints(C, globals())['x'], ClassVar) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(C, globals())['y'], Final) | 
					
						
							| 
									
										
										
										
											2022-01-26 19:11:51 -08:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             get_type_hints(CF, globals()), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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_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 | 
					
						
							| 
									
										
										
										
											2022-02-19 04:53:29 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-13 22:50:14 +01:00
										 |  |  |         # verify that @no_type_check never affects bases | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(C.meth), {'x': int}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 04:53:29 +03:00
										 |  |  |         # and never child classes: | 
					
						
							|  |  |  |         class Child(D): | 
					
						
							|  |  |  |             def foo(self, x: int): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(Child.foo), {'x': int}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_type_check_nested_types(self): | 
					
						
							|  |  |  |         # See https://bugs.python.org/issue46571 | 
					
						
							|  |  |  |         class Other: | 
					
						
							|  |  |  |             o: int | 
					
						
							|  |  |  |         class B:  # Has the same `__name__`` as `A.B` and different `__qualname__` | 
					
						
							|  |  |  |             o: int | 
					
						
							|  |  |  |         @no_type_check | 
					
						
							|  |  |  |         class A: | 
					
						
							|  |  |  |             a: int | 
					
						
							|  |  |  |             class B: | 
					
						
							|  |  |  |                 b: int | 
					
						
							|  |  |  |                 class C: | 
					
						
							|  |  |  |                     c: int | 
					
						
							|  |  |  |             class D: | 
					
						
							|  |  |  |                 d: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             Other = Other | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for klass in [A, A.B, A.B.C, A.D]: | 
					
						
							|  |  |  |             with self.subTest(klass=klass): | 
					
						
							|  |  |  |                 self.assertTrue(klass.__no_type_check__) | 
					
						
							|  |  |  |                 self.assertEqual(get_type_hints(klass), {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for not_modified in [Other, B]: | 
					
						
							|  |  |  |             with self.subTest(not_modified=not_modified): | 
					
						
							|  |  |  |                 with self.assertRaises(AttributeError): | 
					
						
							|  |  |  |                     not_modified.__no_type_check__ | 
					
						
							|  |  |  |                 self.assertNotEqual(get_type_hints(not_modified), {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_type_check_class_and_static_methods(self): | 
					
						
							|  |  |  |         @no_type_check | 
					
						
							|  |  |  |         class Some: | 
					
						
							|  |  |  |             @staticmethod | 
					
						
							|  |  |  |             def st(x: int) -> int: ... | 
					
						
							|  |  |  |             @classmethod | 
					
						
							|  |  |  |             def cl(cls, y: int) -> int: ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertTrue(Some.st.__no_type_check__) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(Some.st), {}) | 
					
						
							|  |  |  |         self.assertTrue(Some.cl.__no_type_check__) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(Some.cl), {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_type_check_other_module(self): | 
					
						
							|  |  |  |         self.assertTrue(NoTypeCheck_Outer.__no_type_check__) | 
					
						
							|  |  |  |         with self.assertRaises(AttributeError): | 
					
						
							|  |  |  |             ann_module8.NoTypeCheck_Outer.__no_type_check__ | 
					
						
							|  |  |  |         with self.assertRaises(AttributeError): | 
					
						
							|  |  |  |             ann_module8.NoTypeCheck_Outer.Inner.__no_type_check__ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertTrue(NoTypeCheck_WithFunction.__no_type_check__) | 
					
						
							|  |  |  |         with self.assertRaises(AttributeError): | 
					
						
							|  |  |  |             ann_module8.NoTypeCheck_function.__no_type_check__ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_type_check_foreign_functions(self): | 
					
						
							|  |  |  |         # We should not modify this function: | 
					
						
							|  |  |  |         def some(*args: int) -> int: | 
					
						
							|  |  |  |             ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @no_type_check | 
					
						
							|  |  |  |         class A: | 
					
						
							|  |  |  |             some_alias = some | 
					
						
							|  |  |  |             some_class = classmethod(some) | 
					
						
							|  |  |  |             some_static = staticmethod(some) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(AttributeError): | 
					
						
							|  |  |  |             some.__no_type_check__ | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(some), {'args': int, 'return': int}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_type_check_lambda(self): | 
					
						
							|  |  |  |         @no_type_check | 
					
						
							|  |  |  |         class A: | 
					
						
							|  |  |  |             # Corner case: `lambda` is both an assignment and a function: | 
					
						
							|  |  |  |             bar: Callable[[int], int] = lambda arg: arg | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertTrue(A.bar.__no_type_check__) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(A.bar), {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_type_check_TypeError(self): | 
					
						
							|  |  |  |         # This simply should not fail with | 
					
						
							|  |  |  |         # `TypeError: can't set attributes of built-in/extension type 'dict'` | 
					
						
							|  |  |  |         no_type_check(dict) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-17 00:12:58 +09:00
										 |  |  |     def test_or(self): | 
					
						
							|  |  |  |         X = ForwardRef('X') | 
					
						
							|  |  |  |         # __or__/__ror__ itself | 
					
						
							|  |  |  |         self.assertEqual(X | "x", Union[X, "x"]) | 
					
						
							|  |  |  |         self.assertEqual("x" | X, Union["x", X]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-16 09:01:43 -07:00
										 |  |  | @lru_cache() | 
					
						
							|  |  |  | def cached_func(x, y): | 
					
						
							|  |  |  |     return 3 * x + y | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MethodHolder: | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def clsmethod(cls): ... | 
					
						
							|  |  |  |     @staticmethod | 
					
						
							|  |  |  |     def stmethod(): ... | 
					
						
							|  |  |  |     def method(self): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  | class OverloadTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_overload_fails(self): | 
					
						
							| 
									
										
										
										
											2022-10-20 03:53:36 +03:00
										 |  |  |         with self.assertRaises(NotImplementedError): | 
					
						
							| 
									
										
										
										
											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): | 
					
						
							|  |  |  |         @overload | 
					
						
							|  |  |  |         def blah(): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def blah(): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         blah() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-26 16:15:39 +03:00
										 |  |  |     @cpython_only  # gh-98713 | 
					
						
							| 
									
										
										
										
											2022-09-06 00:35:05 +03:00
										 |  |  |     def test_overload_on_compiled_functions(self): | 
					
						
							| 
									
										
										
										
											2022-09-06 09:33:09 -07:00
										 |  |  |         with patch("typing._overload_registry", | 
					
						
							|  |  |  |                    defaultdict(lambda: defaultdict(dict))): | 
					
						
							|  |  |  |             # The registry starts out empty: | 
					
						
							|  |  |  |             self.assertEqual(typing._overload_registry, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # This should just not fail: | 
					
						
							|  |  |  |             overload(sum) | 
					
						
							|  |  |  |             overload(print) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # No overloads are recorded (but, it still has a side-effect): | 
					
						
							|  |  |  |             self.assertEqual(typing.get_overloads(sum), []) | 
					
						
							|  |  |  |             self.assertEqual(typing.get_overloads(print), []) | 
					
						
							| 
									
										
										
										
											2022-09-06 00:35:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-16 09:01:43 -07:00
										 |  |  |     def set_up_overloads(self): | 
					
						
							|  |  |  |         def blah(): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         overload1 = blah | 
					
						
							|  |  |  |         overload(blah) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def blah(): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         overload2 = blah | 
					
						
							|  |  |  |         overload(blah) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def blah(): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return blah, [overload1, overload2] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Make sure we don't clear the global overload registry | 
					
						
							|  |  |  |     @patch("typing._overload_registry", | 
					
						
							|  |  |  |         defaultdict(lambda: defaultdict(dict))) | 
					
						
							|  |  |  |     def test_overload_registry(self): | 
					
						
							|  |  |  |         # The registry starts out empty | 
					
						
							|  |  |  |         self.assertEqual(typing._overload_registry, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         impl, overloads = self.set_up_overloads() | 
					
						
							|  |  |  |         self.assertNotEqual(typing._overload_registry, {}) | 
					
						
							|  |  |  |         self.assertEqual(list(get_overloads(impl)), overloads) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def some_other_func(): pass | 
					
						
							|  |  |  |         overload(some_other_func) | 
					
						
							|  |  |  |         other_overload = some_other_func | 
					
						
							|  |  |  |         def some_other_func(): pass | 
					
						
							|  |  |  |         self.assertEqual(list(get_overloads(some_other_func)), [other_overload]) | 
					
						
							| 
									
										
										
										
											2022-08-29 03:45:24 +03:00
										 |  |  |         # Unrelated function still has no overloads: | 
					
						
							|  |  |  |         def not_overloaded(): pass | 
					
						
							|  |  |  |         self.assertEqual(list(get_overloads(not_overloaded)), []) | 
					
						
							| 
									
										
										
										
											2022-04-16 09:01:43 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Make sure that after we clear all overloads, the registry is | 
					
						
							|  |  |  |         # completely empty. | 
					
						
							|  |  |  |         clear_overloads() | 
					
						
							|  |  |  |         self.assertEqual(typing._overload_registry, {}) | 
					
						
							|  |  |  |         self.assertEqual(get_overloads(impl), []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Querying a function with no overloads shouldn't change the registry. | 
					
						
							|  |  |  |         def the_only_one(): pass | 
					
						
							|  |  |  |         self.assertEqual(get_overloads(the_only_one), []) | 
					
						
							|  |  |  |         self.assertEqual(typing._overload_registry, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_overload_registry_repeated(self): | 
					
						
							|  |  |  |         for _ in range(2): | 
					
						
							|  |  |  |             impl, overloads = self.set_up_overloads() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.assertEqual(list(get_overloads(impl)), overloads) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-12 19:48:10 +03:00
										 |  |  | # Definitions needed for features introduced in Python 3.6 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from test import ann_module, ann_module2, ann_module3, ann_module5, ann_module6 | 
					
						
							| 
									
										
										
										
											2016-04-05 08:28:52 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 18:51:42 +05:30
										 |  |  | class Point2DGeneric(Generic[T], TypedDict): | 
					
						
							|  |  |  |     a: T | 
					
						
							|  |  |  |     b: T | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-16 20:49:30 -07:00
										 |  |  | class Bar(_typed_dict_helper.Foo, total=False): | 
					
						
							|  |  |  |     b: int | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 18:51:42 +05:30
										 |  |  | class BarGeneric(_typed_dict_helper.FooGeneric[T], total=False): | 
					
						
							|  |  |  |     b: int | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  | class LabelPoint2D(Point2D, Label): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Options(TypedDict, total=False): | 
					
						
							|  |  |  |     log_level: int | 
					
						
							|  |  |  |     log_path: str | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  | class TotalMovie(TypedDict): | 
					
						
							|  |  |  |     title: str | 
					
						
							|  |  |  |     year: NotRequired[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NontotalMovie(TypedDict, total=False): | 
					
						
							|  |  |  |     title: Required[str] | 
					
						
							|  |  |  |     year: int | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-06 22:28:24 +03:00
										 |  |  | class ParentNontotalMovie(TypedDict, total=False): | 
					
						
							|  |  |  |     title: Required[str] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ChildTotalMovie(ParentNontotalMovie): | 
					
						
							|  |  |  |     year: NotRequired[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ParentDeeplyAnnotatedMovie(TypedDict): | 
					
						
							|  |  |  |     title: Annotated[Annotated[Required[str], "foobar"], "another level"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ChildDeeplyAnnotatedMovie(ParentDeeplyAnnotatedMovie): | 
					
						
							|  |  |  |     year: NotRequired[Annotated[int, 2000]] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  | class AnnotatedMovie(TypedDict): | 
					
						
							|  |  |  |     title: Annotated[Required[str], "foobar"] | 
					
						
							|  |  |  |     year: NotRequired[Annotated[int, 2000]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class DeeplyAnnotatedMovie(TypedDict): | 
					
						
							|  |  |  |     title: Annotated[Annotated[Required[str], "foobar"], "another level"] | 
					
						
							|  |  |  |     year: NotRequired[Annotated[int, 2000]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WeirdlyQuotedMovie(TypedDict): | 
					
						
							|  |  |  |     title: Annotated['Annotated[Required[str], "foobar"]', "another level"] | 
					
						
							|  |  |  |     year: NotRequired['Annotated[int, 2000]'] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-14 14:33:00 -04:00
										 |  |  | class HasForeignBaseClass(mod_generics_cache.A): | 
					
						
							|  |  |  |     some_xrepr: 'XRepr' | 
					
						
							|  |  |  |     other_a: 'mod_generics_cache.A' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-12 19:48:10 +03:00
										 |  |  | async def g_with(am: typing.AsyncContextManager[int]): | 
					
						
							| 
									
										
										
										
											2017-06-10 21:57:56 +02:00
										 |  |  |     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): | 
					
						
							| 
									
										
										
										
											2021-07-17 06:33:40 +03:00
										 |  |  |         ann_module_type_hints = {1: 2, 'f': Tuple[int, int], 'x': int, 'y': str, 'u': int | float} | 
					
						
							| 
									
										
										
										
											2017-01-22 17:43:53 -08:00
										 |  |  |         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}) | 
					
						
							| 
									
										
										
										
											2021-04-21 12:41:19 +01:00
										 |  |  |         self.assertEqual(gth(XRepr.__new__), | 
					
						
							| 
									
										
										
										
											2018-05-09 02:23:46 +01:00
										 |  |  |                          {'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, | 
					
						
							| 
									
										
										
										
											2021-04-13 01:23:12 +08:00
										 |  |  |                           'my_inner_a2': mod_generics_cache.B.A, | 
					
						
							| 
									
										
										
										
											2017-09-14 14:33:00 -04:00
										 |  |  |                           'my_outer_a': mod_generics_cache.A}) | 
					
						
							| 
									
										
										
										
											2016-09-11 15:34:56 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-13 02:35:44 +03:00
										 |  |  |     def test_get_type_hints_classes_no_implicit_optional(self): | 
					
						
							|  |  |  |         class WithNoneDefault: | 
					
						
							|  |  |  |             field: int = None  # most type-checkers won't be happy with it | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(gth(WithNoneDefault), {'field': int}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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)]]} | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-04-26 21:21:08 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def foobar(x: list[ForwardRef('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)]]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |         BA = Tuple[Annotated[T, (1, 0)], ...] | 
					
						
							|  |  |  |         def barfoo(x: BA): ... | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], Tuple[T, ...]) | 
					
						
							| 
									
										
										
										
											2022-03-07 19:02:59 +01:00
										 |  |  |         self.assertEqual( | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |             get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'], | 
					
						
							|  |  |  |             BA | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-04-26 21:21:08 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         BA = tuple[Annotated[T, (1, 0)], ...] | 
					
						
							|  |  |  |         def barfoo(x: BA): ... | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(barfoo, globals(), locals())['x'], tuple[T, ...]) | 
					
						
							| 
									
										
										
										
											2022-03-07 19:02:59 +01:00
										 |  |  |         self.assertEqual( | 
					
						
							| 
									
										
										
										
											2020-04-26 21:21:08 +03:00
										 |  |  |             get_type_hints(barfoo, globals(), locals(), include_extras=True)['x'], | 
					
						
							|  |  |  |             BA | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |         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]} | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-04-26 21:21:08 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |         BA2 = typing.Callable[..., List[T]] | 
					
						
							|  |  |  |         def barfoo3(x: BA2): ... | 
					
						
							|  |  |  |         self.assertIs( | 
					
						
							|  |  |  |             get_type_hints(barfoo3, globals(), locals(), include_extras=True)["x"], | 
					
						
							|  |  |  |             BA2 | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-07-29 22:44:48 +03:00
										 |  |  |         BA3 = typing.Annotated[int | float, "const"] | 
					
						
							|  |  |  |         def barfoo4(x: BA3): ... | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(barfoo4, globals(), locals()), | 
					
						
							|  |  |  |             {"x": int | float} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(barfoo4, globals(), locals(), include_extras=True), | 
					
						
							|  |  |  |             {"x": typing.Annotated[int | float, "const"]} | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-19 04:54:01 +03:00
										 |  |  |     def test_get_type_hints_annotated_in_union(self):  # bpo-46603 | 
					
						
							|  |  |  |         def with_union(x: int | list[Annotated[str, 'meta']]): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(with_union), {'x': int | list[str]}) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(with_union, include_extras=True), | 
					
						
							|  |  |  |             {'x': int | list[Annotated[str, 'meta']]}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |     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]} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-02 08:29:46 +03:00
										 |  |  |     def test_get_type_hints_annotated_with_none_default(self): | 
					
						
							|  |  |  |         # See: https://bugs.python.org/issue46195 | 
					
						
							|  |  |  |         def annotated_with_none_default(x: Annotated[int, 'data'] = None): ... | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(annotated_with_none_default), | 
					
						
							|  |  |  |             {'x': int}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(annotated_with_none_default, include_extras=True), | 
					
						
							|  |  |  |             {'x': Annotated[int, 'data']}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-27 01:31:21 +08:00
										 |  |  |     def test_get_type_hints_classes_str_annotations(self): | 
					
						
							| 
									
										
										
										
											2021-04-13 01:23:12 +08:00
										 |  |  |         class Foo: | 
					
						
							|  |  |  |             y = str | 
					
						
							| 
									
										
										
										
											2021-04-27 01:31:21 +08:00
										 |  |  |             x: 'y' | 
					
						
							| 
									
										
										
										
											2021-04-13 01:23:12 +08:00
										 |  |  |         # This previously raised an error under PEP 563. | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(Foo), {'x': str}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-26 23:31:32 +00:00
										 |  |  |     def test_get_type_hints_bad_module(self): | 
					
						
							|  |  |  |         # bpo-41515 | 
					
						
							|  |  |  |         class BadModule: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         BadModule.__module__ = 'bad' # Something not in sys.modules | 
					
						
							|  |  |  |         self.assertNotIn('bad', sys.modules) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(BadModule), {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_get_type_hints_annotated_bad_module(self): | 
					
						
							|  |  |  |         # See https://bugs.python.org/issue44468 | 
					
						
							|  |  |  |         class BadBase: | 
					
						
							|  |  |  |             foo: tuple | 
					
						
							|  |  |  |         class BadType(BadBase): | 
					
						
							|  |  |  |             bar: list | 
					
						
							|  |  |  |         BadType.__module__ = BadBase.__module__ = 'bad' | 
					
						
							|  |  |  |         self.assertNotIn('bad', sys.modules) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(BadType), {'foo': tuple, 'bar': list}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-21 23:16:50 +03:00
										 |  |  |     def test_forward_ref_and_final(self): | 
					
						
							|  |  |  |         # https://bugs.python.org/issue45166 | 
					
						
							|  |  |  |         hints = get_type_hints(ann_module5) | 
					
						
							|  |  |  |         self.assertEqual(hints, {'name': Final[str]}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         hints = get_type_hints(ann_module5.MyClass) | 
					
						
							|  |  |  |         self.assertEqual(hints, {'value': Final}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_top_level_class_var(self): | 
					
						
							|  |  |  |         # https://bugs.python.org/issue45166 | 
					
						
							|  |  |  |         with self.assertRaisesRegex( | 
					
						
							|  |  |  |             TypeError, | 
					
						
							|  |  |  |             r'typing.ClassVar\[int\] is not valid as type argument', | 
					
						
							|  |  |  |         ): | 
					
						
							|  |  |  |             get_type_hints(ann_module6) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  |     def test_get_type_hints_typeddict(self): | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(TotalMovie), {'title': str, 'year': int}) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(TotalMovie, include_extras=True), { | 
					
						
							|  |  |  |             'title': str, | 
					
						
							|  |  |  |             'year': NotRequired[int], | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(AnnotatedMovie), {'title': str, 'year': int}) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(AnnotatedMovie, include_extras=True), { | 
					
						
							|  |  |  |             'title': Annotated[Required[str], "foobar"], | 
					
						
							|  |  |  |             'year': NotRequired[Annotated[int, 2000]], | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(DeeplyAnnotatedMovie), {'title': str, 'year': int}) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(DeeplyAnnotatedMovie, include_extras=True), { | 
					
						
							|  |  |  |             'title': Annotated[Required[str], "foobar", "another level"], | 
					
						
							|  |  |  |             'year': NotRequired[Annotated[int, 2000]], | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(WeirdlyQuotedMovie), {'title': str, 'year': int}) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(WeirdlyQuotedMovie, include_extras=True), { | 
					
						
							|  |  |  |             'title': Annotated[Required[str], "foobar", "another level"], | 
					
						
							|  |  |  |             'year': NotRequired[Annotated[int, 2000]], | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(_typed_dict_helper.VeryAnnotated), {'a': int}) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(_typed_dict_helper.VeryAnnotated, include_extras=True), { | 
					
						
							|  |  |  |             'a': Annotated[Required[int], "a", "b", "c"] | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-06 22:28:24 +03:00
										 |  |  |         self.assertEqual(get_type_hints(ChildTotalMovie), {"title": str, "year": int}) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(ChildTotalMovie, include_extras=True), { | 
					
						
							|  |  |  |             "title": Required[str], "year": NotRequired[int] | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(ChildDeeplyAnnotatedMovie), {"title": str, "year": int}) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(ChildDeeplyAnnotatedMovie, include_extras=True), { | 
					
						
							|  |  |  |             "title": Annotated[Required[str], "foobar", "another level"], | 
					
						
							|  |  |  |             "year": NotRequired[Annotated[int, 2000]] | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-02 17:08:28 -06:00
										 |  |  |     def test_get_type_hints_collections_abc_callable(self): | 
					
						
							|  |  |  |         # https://github.com/python/cpython/issues/91621 | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         def f(x: collections.abc.Callable[[int], int]): ... | 
					
						
							|  |  |  |         def g(x: collections.abc.Callable[..., int]): ... | 
					
						
							|  |  |  |         def h(x: collections.abc.Callable[P, int]): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(f), {'x': collections.abc.Callable[[int], int]}) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(g), {'x': collections.abc.Callable[..., int]}) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(h), {'x': collections.abc.Callable[P, int]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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') | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							| 
									
										
										
										
											2021-04-10 19:57:05 -07:00
										 |  |  |         P = ParamSpec('P') | 
					
						
							| 
									
										
										
										
											2019-05-31 00:10:07 +01:00
										 |  |  |         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) | 
					
						
							| 
									
										
										
										
											2020-04-26 21:21:08 +03:00
										 |  |  |         self.assertIs(get_origin(List), list) | 
					
						
							| 
									
										
										
										
											2020-04-27 10:27:21 +03:00
										 |  |  |         self.assertIs(get_origin(Tuple), tuple) | 
					
						
							|  |  |  |         self.assertIs(get_origin(Callable), collections.abc.Callable) | 
					
						
							| 
									
										
										
										
											2020-04-26 21:21:08 +03:00
										 |  |  |         self.assertIs(get_origin(list[int]), list) | 
					
						
							|  |  |  |         self.assertIs(get_origin(list), None) | 
					
						
							| 
									
										
										
										
											2021-07-26 20:00:21 +04:00
										 |  |  |         self.assertIs(get_origin(list | str), types.UnionType) | 
					
						
							| 
									
										
										
										
											2021-04-10 19:57:05 -07:00
										 |  |  |         self.assertIs(get_origin(P.args), P) | 
					
						
							|  |  |  |         self.assertIs(get_origin(P.kwargs), P) | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  |         self.assertIs(get_origin(Required[int]), Required) | 
					
						
							|  |  |  |         self.assertIs(get_origin(NotRequired[int]), NotRequired) | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertIs(get_origin((*Ts,)[0]), Unpack) | 
					
						
							|  |  |  |         self.assertIs(get_origin(Unpack[Ts]), Unpack) | 
					
						
							|  |  |  |         self.assertIs(get_origin((*tuple[*Ts],)[0]), tuple) | 
					
						
							|  |  |  |         self.assertIs(get_origin(Unpack[Tuple[Unpack[Ts]]]), Unpack) | 
					
						
							| 
									
										
										
										
											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,)) | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:52 +03:00
										 |  |  |         self.assertEqual(get_args(typing.SupportsAbs[int]), (int,))  # Protocol | 
					
						
							|  |  |  |         self.assertEqual(get_args(typing.SupportsAbs[T]), (T,)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Point2DGeneric[int]), (int,))  # TypedDict | 
					
						
							|  |  |  |         self.assertEqual(get_args(Point2DGeneric[T]), (T,)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(T), ()) | 
					
						
							| 
									
										
										
										
											2019-05-31 00:10:07 +01:00
										 |  |  |         self.assertEqual(get_args(int), ()) | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:52 +03:00
										 |  |  |         self.assertEqual(get_args(Any), ()) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Self), ()) | 
					
						
							|  |  |  |         self.assertEqual(get_args(LiteralString), ()) | 
					
						
							| 
									
										
										
										
											2019-05-31 00:10:07 +01:00
										 |  |  |         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],)) | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:52 +03:00
										 |  |  |         self.assertEqual(get_args(Optional[int]), (int, type(None))) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Union[int, None]), (int, type(None))) | 
					
						
							| 
									
										
										
										
											2019-05-31 00:10:07 +01:00
										 |  |  |         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]])) | 
					
						
							| 
									
										
										
										
											2020-04-27 10:27:21 +03:00
										 |  |  |         self.assertEqual(get_args(Callable[[], T][int]), ([], int)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Callable[..., int]), (..., int)) | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:52 +03:00
										 |  |  |         self.assertEqual(get_args(Callable[[int], str]), ([int], str)) | 
					
						
							| 
									
										
										
										
											2019-05-31 00:10:07 +01:00
										 |  |  |         self.assertEqual(get_args(Union[int, Callable[[Tuple[T, ...]], str]]), | 
					
						
							|  |  |  |                          (int, Callable[[Tuple[T, ...]], str])) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Tuple[int, ...]), (int, ...)) | 
					
						
							| 
									
										
										
										
											2022-03-17 09:52:24 +02:00
										 |  |  |         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'])) | 
					
						
							| 
									
										
										
										
											2020-04-27 10:27:21 +03:00
										 |  |  |         self.assertEqual(get_args(List), ()) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Tuple), ()) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Callable), ()) | 
					
						
							| 
									
										
										
										
											2020-04-26 21:21:08 +03:00
										 |  |  |         self.assertEqual(get_args(list[int]), (int,)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(list), ()) | 
					
						
							| 
									
										
										
										
											2020-12-29 04:06:19 +08:00
										 |  |  |         self.assertEqual(get_args(collections.abc.Callable[[int], str]), ([int], str)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(collections.abc.Callable[..., str]), (..., str)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(collections.abc.Callable[[], str]), ([], str)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(collections.abc.Callable[[int], str]), | 
					
						
							|  |  |  |                          get_args(Callable[[int], str])) | 
					
						
							| 
									
										
										
										
											2020-12-29 10:26:19 +08:00
										 |  |  |         P = ParamSpec('P') | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:52 +03:00
										 |  |  |         self.assertEqual(get_args(P), ()) | 
					
						
							|  |  |  |         self.assertEqual(get_args(P.args), ()) | 
					
						
							|  |  |  |         self.assertEqual(get_args(P.kwargs), ()) | 
					
						
							| 
									
										
										
										
											2020-12-29 10:26:19 +08:00
										 |  |  |         self.assertEqual(get_args(Callable[P, int]), (P, int)) | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:52 +03:00
										 |  |  |         self.assertEqual(get_args(collections.abc.Callable[P, int]), (P, int)) | 
					
						
							| 
									
										
										
										
											2020-12-29 10:26:19 +08:00
										 |  |  |         self.assertEqual(get_args(Callable[Concatenate[int, P], int]), | 
					
						
							|  |  |  |                          (Concatenate[int, P], int)) | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:52 +03:00
										 |  |  |         self.assertEqual(get_args(collections.abc.Callable[Concatenate[int, P], int]), | 
					
						
							|  |  |  |                          (Concatenate[int, P], int)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Concatenate[int, str, P]), (int, str, P)) | 
					
						
							| 
									
										
										
										
											2020-12-29 10:26:19 +08:00
										 |  |  |         self.assertEqual(get_args(list | str), (list, str)) | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  |         self.assertEqual(get_args(Required[int]), (int,)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(NotRequired[int]), (int,)) | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:52 +03:00
										 |  |  |         self.assertEqual(get_args(TypeAlias), ()) | 
					
						
							|  |  |  |         self.assertEqual(get_args(TypeGuard[int]), (int,)) | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         self.assertEqual(get_args(Ts), ()) | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual(get_args((*Ts,)[0]), (Ts,)) | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:52 +03:00
										 |  |  |         self.assertEqual(get_args(Unpack[Ts]), (Ts,)) | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual(get_args(tuple[*Ts]), (*Ts,)) | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:52 +03:00
										 |  |  |         self.assertEqual(get_args(tuple[Unpack[Ts]]), (Unpack[Ts],)) | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual(get_args((*tuple[*Ts],)[0]), (*Ts,)) | 
					
						
							|  |  |  |         self.assertEqual(get_args(Unpack[tuple[Unpack[Ts]]]), (tuple[Unpack[Ts]],)) | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  |     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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							|  |  |  |     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): | 
					
						
							| 
									
										
										
										
											2022-01-20 00:24:27 +03:00
										 |  |  |         self.assertIsInstance(tuple(), typing.Collection) | 
					
						
							|  |  |  |         self.assertIsInstance(frozenset(), typing.Collection) | 
					
						
							|  |  |  |         self.assertIsSubclass(dict, typing.Collection) | 
					
						
							|  |  |  |         self.assertNotIsInstance(42, typing.Collection) | 
					
						
							| 
									
										
										
										
											2016-08-23 11:01:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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): | 
					
						
							| 
									
										
										
										
											2023-05-12 07:01:31 +01:00
										 |  |  |         with self.assertWarns(DeprecationWarning): | 
					
						
							| 
									
										
										
										
											2023-05-13 09:55:35 +01:00
										 |  |  |             self.assertIsInstance(b'', typing.ByteString) | 
					
						
							| 
									
										
										
										
											2023-05-12 07:01:31 +01:00
										 |  |  |         with self.assertWarns(DeprecationWarning): | 
					
						
							| 
									
										
										
										
											2023-05-13 09:55:35 +01:00
										 |  |  |             self.assertIsInstance(bytearray(b''), typing.ByteString) | 
					
						
							| 
									
										
										
										
											2023-05-12 07:01:31 +01:00
										 |  |  |         with self.assertWarns(DeprecationWarning): | 
					
						
							| 
									
										
										
										
											2023-05-13 09:55:35 +01:00
										 |  |  |             class Foo(typing.ByteString): ... | 
					
						
							| 
									
										
										
										
											2023-05-12 07:01:31 +01:00
										 |  |  |         with self.assertWarns(DeprecationWarning): | 
					
						
							| 
									
										
										
										
											2023-05-13 09:55:35 +01:00
										 |  |  |             class Bar(typing.ByteString, typing.Awaitable): ... | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-10 13:39:40 +03:00
										 |  |  |     def test_dict_subscribe(self): | 
					
						
							|  |  |  |         K = TypeVar('K') | 
					
						
							|  |  |  |         V = TypeVar('V') | 
					
						
							|  |  |  |         self.assertEqual(Dict[K, V][str, int], Dict[str, int]) | 
					
						
							|  |  |  |         self.assertEqual(Dict[K, int][str], Dict[str, int]) | 
					
						
							|  |  |  |         self.assertEqual(Dict[str, V][int], Dict[str, int]) | 
					
						
							|  |  |  |         self.assertEqual(Dict[K, List[V]][str, int], Dict[str, List[int]]) | 
					
						
							|  |  |  |         self.assertEqual(Dict[K, List[int]][str], Dict[str, List[int]]) | 
					
						
							|  |  |  |         self.assertEqual(Dict[K, list[V]][str, int], Dict[str, list[int]]) | 
					
						
							|  |  |  |         self.assertEqual(Dict[K, list[int]][str], Dict[str, list[int]]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  |     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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-19 18:32:25 +03:00
										 |  |  |     def test_or_and_ror(self): | 
					
						
							|  |  |  |         self.assertEqual(typing.Sized | typing.Awaitable, Union[typing.Sized, typing.Awaitable]) | 
					
						
							|  |  |  |         self.assertEqual(typing.Coroutine | typing.Hashable, Union[typing.Coroutine, typing.Hashable]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  |     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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-23 00:06:54 +03:00
										 |  |  | class TestModules(TestCase): | 
					
						
							|  |  |  |     func_names = ['_idfunc'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_c_functions(self): | 
					
						
							|  |  |  |         for fname in self.func_names: | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |             self.assertEqual(getattr(typing, fname).__module__, '_typing') | 
					
						
							| 
									
										
										
										
											2021-07-23 00:06:54 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  | class NewTypeTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2021-07-23 17:28:05 +03:00
										 |  |  |     def cleanup(self): | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |         for f in typing._cleanups: | 
					
						
							| 
									
										
										
										
											2021-07-23 17:28:05 +03:00
										 |  |  |             f() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  |     @classmethod | 
					
						
							|  |  |  |     def setUpClass(cls): | 
					
						
							|  |  |  |         global UserId | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |         UserId = typing.NewType('UserId', int) | 
					
						
							|  |  |  |         cls.UserName = typing.NewType(cls.__qualname__ + '.UserName', str) | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def tearDownClass(cls): | 
					
						
							|  |  |  |         global UserId | 
					
						
							|  |  |  |         del UserId | 
					
						
							|  |  |  |         del cls.UserName | 
					
						
							| 
									
										
										
										
											2021-07-23 00:06:54 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self): | 
					
						
							| 
									
										
										
										
											2021-07-23 17:28:05 +03:00
										 |  |  |         self.cleanup() | 
					
						
							| 
									
										
										
										
											2016-06-08 11:19:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							|  |  |  |         self.assertIsInstance(UserId(5), int) | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  |         self.assertIsInstance(self.UserName('Joe'), str) | 
					
						
							| 
									
										
										
										
											2016-06-08 11:19:11 -07:00
										 |  |  |         self.assertEqual(UserId(5) + 1, 6) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_errors(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(UserId, int) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  |             class D(UserId): | 
					
						
							| 
									
										
										
										
											2016-06-08 11:19:11 -07:00
										 |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-20 16:20:38 +03:00
										 |  |  |     def test_or(self): | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  |         for cls in (int, self.UserName): | 
					
						
							| 
									
										
										
										
											2021-07-20 17:48:05 +03:00
										 |  |  |             with self.subTest(cls=cls): | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |                 self.assertEqual(UserId | cls, typing.Union[UserId, cls]) | 
					
						
							|  |  |  |                 self.assertEqual(cls | UserId, typing.Union[cls, UserId]) | 
					
						
							| 
									
										
										
										
											2021-07-20 16:20:38 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |                 self.assertEqual(typing.get_args(UserId | cls), (UserId, cls)) | 
					
						
							|  |  |  |                 self.assertEqual(typing.get_args(cls | UserId), (cls, UserId)) | 
					
						
							| 
									
										
										
										
											2021-07-20 16:20:38 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_special_attrs(self): | 
					
						
							|  |  |  |         self.assertEqual(UserId.__name__, 'UserId') | 
					
						
							|  |  |  |         self.assertEqual(UserId.__qualname__, 'UserId') | 
					
						
							|  |  |  |         self.assertEqual(UserId.__module__, __name__) | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  |         self.assertEqual(UserId.__supertype__, int) | 
					
						
							| 
									
										
										
										
											2021-07-20 16:20:38 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  |         UserName = self.UserName | 
					
						
							|  |  |  |         self.assertEqual(UserName.__name__, 'UserName') | 
					
						
							|  |  |  |         self.assertEqual(UserName.__qualname__, | 
					
						
							|  |  |  |                          self.__class__.__qualname__ + '.UserName') | 
					
						
							|  |  |  |         self.assertEqual(UserName.__module__, __name__) | 
					
						
							|  |  |  |         self.assertEqual(UserName.__supertype__, str) | 
					
						
							| 
									
										
										
										
											2021-07-20 16:20:38 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  |     def test_repr(self): | 
					
						
							| 
									
										
										
										
											2021-07-20 16:20:38 +03:00
										 |  |  |         self.assertEqual(repr(UserId), f'{__name__}.UserId') | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  |         self.assertEqual(repr(self.UserName), | 
					
						
							|  |  |  |                          f'{__name__}.{self.__class__.__qualname__}.UserName') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_pickle(self): | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |         UserAge = typing.NewType('UserAge', float) | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  |         for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							| 
									
										
										
										
											2021-07-24 12:53:40 +03:00
										 |  |  |             with self.subTest(proto=proto): | 
					
						
							|  |  |  |                 pickled = pickle.dumps(UserId, proto) | 
					
						
							|  |  |  |                 loaded = pickle.loads(pickled) | 
					
						
							|  |  |  |                 self.assertIs(loaded, UserId) | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-24 12:53:40 +03:00
										 |  |  |                 pickled = pickle.dumps(self.UserName, proto) | 
					
						
							|  |  |  |                 loaded = pickle.loads(pickled) | 
					
						
							|  |  |  |                 self.assertIs(loaded, self.UserName) | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-24 12:53:40 +03:00
										 |  |  |                 with self.assertRaises(pickle.PicklingError): | 
					
						
							|  |  |  |                     pickle.dumps(UserAge, proto) | 
					
						
							| 
									
										
										
										
											2021-07-24 10:40:08 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-30 15:56:12 +03:00
										 |  |  |     def test_missing__name__(self): | 
					
						
							|  |  |  |         code = ("import typing\n" | 
					
						
							|  |  |  |                 "NT = typing.NewType('NT', int)\n" | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |         exec(code, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-08 03:50:46 +00:00
										 |  |  |     def test_error_message_when_subclassing(self): | 
					
						
							|  |  |  |         with self.assertRaisesRegex( | 
					
						
							|  |  |  |             TypeError, | 
					
						
							|  |  |  |             re.escape( | 
					
						
							|  |  |  |                 "Cannot subclass an instance of NewType. Perhaps you were looking for: " | 
					
						
							|  |  |  |                 "`ProUserId = NewType('ProUserId', UserId)`" | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ): | 
					
						
							|  |  |  |             class ProUserId(UserId): | 
					
						
							|  |  |  |                 ... | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 11:19:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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')) | 
					
						
							| 
									
										
										
										
											2021-04-21 12:41:19 +01:00
										 |  |  |         self.assertEqual(CoolEmployee.__annotations__, | 
					
						
							| 
									
										
										
										
											2017-01-17 20:43:28 -08:00
										 |  |  |                          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')) | 
					
						
							| 
									
										
										
										
											2021-04-21 12:41:19 +01:00
										 |  |  |         self.assertEqual(CoolEmployeeWithDefault.__annotations__, | 
					
						
							| 
									
										
										
										
											2020-04-05 00:43:20 +03:00
										 |  |  |                          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 | 
					
						
							| 
									
										
										
										
											2022-05-03 01:41:23 +03:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class X(NamedTuple, tuple): | 
					
						
							|  |  |  |                 x: int | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class X(NamedTuple, NamedTuple): | 
					
						
							|  |  |  |                 x: int | 
					
						
							|  |  |  |         class A(NamedTuple): | 
					
						
							|  |  |  |             x: int | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class X(NamedTuple, A): | 
					
						
							|  |  |  |                 y: str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_generic(self): | 
					
						
							|  |  |  |         class X(NamedTuple, Generic[T]): | 
					
						
							|  |  |  |             x: T | 
					
						
							|  |  |  |         self.assertEqual(X.__bases__, (tuple, Generic)) | 
					
						
							|  |  |  |         self.assertEqual(X.__orig_bases__, (NamedTuple, Generic[T])) | 
					
						
							|  |  |  |         self.assertEqual(X.__mro__, (X, tuple, Generic, object)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Y(Generic[T], NamedTuple): | 
					
						
							|  |  |  |             x: T | 
					
						
							|  |  |  |         self.assertEqual(Y.__bases__, (Generic, tuple)) | 
					
						
							|  |  |  |         self.assertEqual(Y.__orig_bases__, (Generic[T], NamedTuple)) | 
					
						
							|  |  |  |         self.assertEqual(Y.__mro__, (Y, Generic, tuple, object)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for G in X, Y: | 
					
						
							|  |  |  |             with self.subTest(type=G): | 
					
						
							|  |  |  |                 self.assertEqual(G.__parameters__, (T,)) | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:52 +03:00
										 |  |  |                 self.assertEqual(G[T].__args__, (T,)) | 
					
						
							|  |  |  |                 self.assertEqual(get_args(G[T]), (T,)) | 
					
						
							| 
									
										
										
										
											2022-05-03 01:41:23 +03:00
										 |  |  |                 A = G[int] | 
					
						
							|  |  |  |                 self.assertIs(A.__origin__, G) | 
					
						
							|  |  |  |                 self.assertEqual(A.__args__, (int,)) | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:52 +03:00
										 |  |  |                 self.assertEqual(get_args(A), (int,)) | 
					
						
							| 
									
										
										
										
											2022-05-03 01:41:23 +03:00
										 |  |  |                 self.assertEqual(A.__parameters__, ()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 a = A(3) | 
					
						
							|  |  |  |                 self.assertIs(type(a), G) | 
					
						
							|  |  |  |                 self.assertEqual(a.x, 3) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                     G[int, str] | 
					
						
							| 
									
										
										
										
											2020-04-04 21:31:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 09:04:47 -07:00
										 |  |  |     def test_generic_pep695(self): | 
					
						
							|  |  |  |         class X[T](NamedTuple): | 
					
						
							|  |  |  |             x: T | 
					
						
							|  |  |  |         T, = X.__type_params__ | 
					
						
							|  |  |  |         self.assertIsInstance(T, TypeVar) | 
					
						
							|  |  |  |         self.assertEqual(T.__name__, 'T') | 
					
						
							|  |  |  |         self.assertEqual(X.__bases__, (tuple, Generic)) | 
					
						
							|  |  |  |         self.assertEqual(X.__orig_bases__, (NamedTuple, Generic[T])) | 
					
						
							|  |  |  |         self.assertEqual(X.__mro__, (X, tuple, Generic, object)) | 
					
						
							|  |  |  |         self.assertEqual(X.__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(X[str].__args__, (str,)) | 
					
						
							|  |  |  |         self.assertEqual(X[str].__parameters__, ()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-04 17:06:50 +03:00
										 |  |  |     def test_non_generic_subscript(self): | 
					
						
							|  |  |  |         # For backward compatibility, subscription works | 
					
						
							|  |  |  |         # on arbitrary NamedTuple types. | 
					
						
							|  |  |  |         class Group(NamedTuple): | 
					
						
							|  |  |  |             key: T | 
					
						
							|  |  |  |             group: list[T] | 
					
						
							|  |  |  |         A = Group[int] | 
					
						
							|  |  |  |         self.assertEqual(A.__origin__, Group) | 
					
						
							|  |  |  |         self.assertEqual(A.__parameters__, ()) | 
					
						
							|  |  |  |         self.assertEqual(A.__args__, (int,)) | 
					
						
							|  |  |  |         a = A(1, [2]) | 
					
						
							|  |  |  |         self.assertIs(type(a), Group) | 
					
						
							|  |  |  |         self.assertEqual(a, (1, [2])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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)]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-26 19:32:18 +03:00
										 |  |  |     def test_empty_namedtuple(self): | 
					
						
							|  |  |  |         NT = NamedTuple('NT') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CNT(NamedTuple): | 
					
						
							|  |  |  |             pass  # empty body | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for struct in [NT, CNT]: | 
					
						
							|  |  |  |             with self.subTest(struct=struct): | 
					
						
							|  |  |  |                 self.assertEqual(struct._fields, ()) | 
					
						
							|  |  |  |                 self.assertEqual(struct._field_defaults, {}) | 
					
						
							|  |  |  |                 self.assertEqual(struct.__annotations__, {}) | 
					
						
							|  |  |  |                 self.assertIsInstance(struct(), struct) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-17 21:22:00 +03:00
										 |  |  |     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) | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-23 08:33:39 -06:00
										 |  |  |     def test_orig_bases(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class SimpleNamedTuple(NamedTuple): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class GenericNamedTuple(NamedTuple, Generic[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(SimpleNamedTuple.__orig_bases__, (NamedTuple,)) | 
					
						
							|  |  |  |         self.assertEqual(GenericNamedTuple.__orig_bases__, (NamedTuple, Generic[T])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         CallNamedTuple = NamedTuple('CallNamedTuple', []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(CallNamedTuple.__orig_bases__, (NamedTuple,)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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): | 
					
						
							| 
									
										
										
										
											2022-02-17 11:26:07 +08:00
										 |  |  |         with self.assertWarns(DeprecationWarning): | 
					
						
							|  |  |  |             Emp = TypedDict('Emp', name=str, id=int) | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  |         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): | 
					
						
							| 
									
										
										
										
											2022-02-17 11:26:07 +08:00
										 |  |  |         with self.assertWarns(DeprecationWarning): | 
					
						
							|  |  |  |             TD = TypedDict("TD", cls=type, self=object, typename=str, _typename=int, fields=list, _fields=dict) | 
					
						
							| 
									
										
										
										
											2019-09-17 21:22:00 +03:00
										 |  |  |         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) | 
					
						
							| 
									
										
										
										
											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', int)], y=int) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_py36_class_syntax_usage(self): | 
					
						
							|  |  |  |         self.assertEqual(LabelPoint2D.__name__, 'LabelPoint2D') | 
					
						
							|  |  |  |         self.assertEqual(LabelPoint2D.__module__, __name__) | 
					
						
							| 
									
										
										
										
											2021-04-21 12:41:19 +01:00
										 |  |  |         self.assertEqual(LabelPoint2D.__annotations__, {'x': int, 'y': int, 'label': str}) | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											2022-02-17 11:26:07 +08:00
										 |  |  |         EmpD = TypedDict('EmpD', {'name': str, 'id': int}) | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  |         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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 18:51:42 +05:30
										 |  |  |     def test_pickle_generic(self): | 
					
						
							|  |  |  |         point = Point2DGeneric(a=5.0, b=3.0) | 
					
						
							|  |  |  |         for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |             z = pickle.dumps(point, proto) | 
					
						
							|  |  |  |             point2 = pickle.loads(z) | 
					
						
							|  |  |  |             self.assertEqual(point2, point) | 
					
						
							|  |  |  |             self.assertEqual(point2, {'a': 5.0, 'b': 3.0}) | 
					
						
							|  |  |  |             ZZ = pickle.dumps(Point2DGeneric, proto) | 
					
						
							|  |  |  |             Point2DGenericNew = pickle.loads(ZZ) | 
					
						
							|  |  |  |             self.assertEqual(Point2DGenericNew({'a': 5.0, 'b': 3.0}), point) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  |     def test_optional(self): | 
					
						
							| 
									
										
										
										
											2022-02-17 11:26:07 +08:00
										 |  |  |         EmpD = TypedDict('EmpD', {'name': str, 'id': int}) | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         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) | 
					
						
							| 
									
										
										
										
											2020-12-10 23:49:05 +02:00
										 |  |  |         self.assertEqual(D.__required_keys__, frozenset()) | 
					
						
							|  |  |  |         self.assertEqual(D.__optional_keys__, {'x'}) | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(Options(), {}) | 
					
						
							|  |  |  |         self.assertEqual(Options(log_level=2), {'log_level': 2}) | 
					
						
							|  |  |  |         self.assertEqual(Options.__total__, False) | 
					
						
							| 
									
										
										
										
											2020-12-10 23:49:05 +02:00
										 |  |  |         self.assertEqual(Options.__required_keys__, frozenset()) | 
					
						
							|  |  |  |         self.assertEqual(Options.__optional_keys__, {'log_level', 'log_path'}) | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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([]) | 
					
						
							| 
									
										
										
										
											2021-04-21 12:41:19 +01:00
										 |  |  |         assert BaseAnimal.__annotations__ == {'name': str} | 
					
						
							| 
									
										
										
										
											2020-02-13 20:53:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         assert Animal.__required_keys__ == frozenset(['name']) | 
					
						
							|  |  |  |         assert Animal.__optional_keys__ == frozenset(['tail', 'voice']) | 
					
						
							| 
									
										
										
										
											2021-04-21 12:41:19 +01:00
										 |  |  |         assert Animal.__annotations__ == { | 
					
						
							| 
									
										
										
										
											2020-02-13 20:53:29 +01:00
										 |  |  |             'name': str, | 
					
						
							|  |  |  |             'tail': bool, | 
					
						
							|  |  |  |             'voice': str, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         assert Cat.__required_keys__ == frozenset(['name', 'fur_color']) | 
					
						
							|  |  |  |         assert Cat.__optional_keys__ == frozenset(['tail', 'voice']) | 
					
						
							| 
									
										
										
										
											2021-04-21 12:41:19 +01:00
										 |  |  |         assert Cat.__annotations__ == { | 
					
						
							| 
									
										
										
										
											2020-02-13 20:53:29 +01:00
										 |  |  |             'fur_color': str, | 
					
						
							|  |  |  |             'name': str, | 
					
						
							|  |  |  |             'tail': bool, | 
					
						
							|  |  |  |             'voice': str, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  |     def test_required_notrequired_keys(self): | 
					
						
							|  |  |  |         self.assertEqual(NontotalMovie.__required_keys__, | 
					
						
							|  |  |  |                          frozenset({"title"})) | 
					
						
							|  |  |  |         self.assertEqual(NontotalMovie.__optional_keys__, | 
					
						
							|  |  |  |                          frozenset({"year"})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(TotalMovie.__required_keys__, | 
					
						
							|  |  |  |                          frozenset({"title"})) | 
					
						
							|  |  |  |         self.assertEqual(TotalMovie.__optional_keys__, | 
					
						
							|  |  |  |                          frozenset({"year"})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(_typed_dict_helper.VeryAnnotated.__required_keys__, | 
					
						
							|  |  |  |                          frozenset()) | 
					
						
							|  |  |  |         self.assertEqual(_typed_dict_helper.VeryAnnotated.__optional_keys__, | 
					
						
							|  |  |  |                          frozenset({"a"})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(AnnotatedMovie.__required_keys__, | 
					
						
							|  |  |  |                          frozenset({"title"})) | 
					
						
							|  |  |  |         self.assertEqual(AnnotatedMovie.__optional_keys__, | 
					
						
							|  |  |  |                          frozenset({"year"})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(WeirdlyQuotedMovie.__required_keys__, | 
					
						
							|  |  |  |                          frozenset({"title"})) | 
					
						
							|  |  |  |         self.assertEqual(WeirdlyQuotedMovie.__optional_keys__, | 
					
						
							|  |  |  |                          frozenset({"year"})) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-06 22:28:24 +03:00
										 |  |  |         self.assertEqual(ChildTotalMovie.__required_keys__, | 
					
						
							|  |  |  |                          frozenset({"title"})) | 
					
						
							|  |  |  |         self.assertEqual(ChildTotalMovie.__optional_keys__, | 
					
						
							|  |  |  |                          frozenset({"year"})) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(ChildDeeplyAnnotatedMovie.__required_keys__, | 
					
						
							|  |  |  |                          frozenset({"title"})) | 
					
						
							|  |  |  |         self.assertEqual(ChildDeeplyAnnotatedMovie.__optional_keys__, | 
					
						
							|  |  |  |                          frozenset({"year"})) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-22 00:38:23 +03:00
										 |  |  |     def test_multiple_inheritance(self): | 
					
						
							|  |  |  |         class One(TypedDict): | 
					
						
							|  |  |  |             one: int | 
					
						
							|  |  |  |         class Two(TypedDict): | 
					
						
							|  |  |  |             two: str | 
					
						
							|  |  |  |         class Untotal(TypedDict, total=False): | 
					
						
							|  |  |  |             untotal: str | 
					
						
							|  |  |  |         Inline = TypedDict('Inline', {'inline': bool}) | 
					
						
							|  |  |  |         class Regular: | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Child(One, Two): | 
					
						
							|  |  |  |             child: bool | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             Child.__required_keys__, | 
					
						
							|  |  |  |             frozenset(['one', 'two', 'child']), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             Child.__optional_keys__, | 
					
						
							|  |  |  |             frozenset([]), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             Child.__annotations__, | 
					
						
							|  |  |  |             {'one': int, 'two': str, 'child': bool}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class ChildWithOptional(One, Untotal): | 
					
						
							|  |  |  |             child: bool | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             ChildWithOptional.__required_keys__, | 
					
						
							|  |  |  |             frozenset(['one', 'child']), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             ChildWithOptional.__optional_keys__, | 
					
						
							|  |  |  |             frozenset(['untotal']), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             ChildWithOptional.__annotations__, | 
					
						
							|  |  |  |             {'one': int, 'untotal': str, 'child': bool}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class ChildWithTotalFalse(One, Untotal, total=False): | 
					
						
							|  |  |  |             child: bool | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             ChildWithTotalFalse.__required_keys__, | 
					
						
							|  |  |  |             frozenset(['one']), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             ChildWithTotalFalse.__optional_keys__, | 
					
						
							|  |  |  |             frozenset(['untotal', 'child']), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             ChildWithTotalFalse.__annotations__, | 
					
						
							|  |  |  |             {'one': int, 'untotal': str, 'child': bool}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class ChildWithInlineAndOptional(Untotal, Inline): | 
					
						
							|  |  |  |             child: bool | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             ChildWithInlineAndOptional.__required_keys__, | 
					
						
							|  |  |  |             frozenset(['inline', 'child']), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             ChildWithInlineAndOptional.__optional_keys__, | 
					
						
							|  |  |  |             frozenset(['untotal']), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             ChildWithInlineAndOptional.__annotations__, | 
					
						
							|  |  |  |             {'inline': bool, 'untotal': str, 'child': bool}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         wrong_bases = [ | 
					
						
							|  |  |  |             (One, Regular), | 
					
						
							|  |  |  |             (Regular, One), | 
					
						
							|  |  |  |             (One, Two, Regular), | 
					
						
							|  |  |  |             (Inline, Regular), | 
					
						
							|  |  |  |             (Untotal, Regular), | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         for bases in wrong_bases: | 
					
						
							|  |  |  |             with self.subTest(bases=bases): | 
					
						
							|  |  |  |                 with self.assertRaisesRegex( | 
					
						
							|  |  |  |                     TypeError, | 
					
						
							|  |  |  |                     'cannot inherit from both a TypedDict type and a non-TypedDict', | 
					
						
							|  |  |  |                 ): | 
					
						
							|  |  |  |                     class Wrong(*bases): | 
					
						
							|  |  |  |                         pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-16 05:58:32 +01:00
										 |  |  |     def test_is_typeddict(self): | 
					
						
							|  |  |  |         assert is_typeddict(Point2D) is True | 
					
						
							|  |  |  |         assert is_typeddict(Union[str, int]) is False | 
					
						
							|  |  |  |         # classes, not instances | 
					
						
							|  |  |  |         assert is_typeddict(Point2D()) is False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-16 20:49:30 -07:00
										 |  |  |     def test_get_type_hints(self): | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(Bar), | 
					
						
							|  |  |  |             {'a': typing.Optional[int], 'b': int} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 18:51:42 +05:30
										 |  |  |     def test_get_type_hints_generic(self): | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(BarGeneric), | 
					
						
							|  |  |  |             {'a': typing.Optional[T], 'b': int} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class FooBarGeneric(BarGeneric[int]): | 
					
						
							|  |  |  |             c: str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             get_type_hints(FooBarGeneric), | 
					
						
							|  |  |  |             {'a': typing.Optional[T], 'b': int, 'c': str} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 09:04:47 -07:00
										 |  |  |     def test_pep695_generic_typeddict(self): | 
					
						
							|  |  |  |         class A[T](TypedDict): | 
					
						
							|  |  |  |             a: T | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         T, = A.__type_params__ | 
					
						
							|  |  |  |         self.assertIsInstance(T, TypeVar) | 
					
						
							|  |  |  |         self.assertEqual(T.__name__, 'T') | 
					
						
							|  |  |  |         self.assertEqual(A.__bases__, (Generic, dict)) | 
					
						
							|  |  |  |         self.assertEqual(A.__orig_bases__, (TypedDict, Generic[T])) | 
					
						
							|  |  |  |         self.assertEqual(A.__mro__, (A, Generic, dict, object)) | 
					
						
							|  |  |  |         self.assertEqual(A.__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(A[str].__parameters__, ()) | 
					
						
							|  |  |  |         self.assertEqual(A[str].__args__, (str,)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 18:51:42 +05:30
										 |  |  |     def test_generic_inheritance(self): | 
					
						
							|  |  |  |         class A(TypedDict, Generic[T]): | 
					
						
							|  |  |  |             a: T | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(A.__bases__, (Generic, dict)) | 
					
						
							|  |  |  |         self.assertEqual(A.__orig_bases__, (TypedDict, Generic[T])) | 
					
						
							|  |  |  |         self.assertEqual(A.__mro__, (A, Generic, dict, object)) | 
					
						
							|  |  |  |         self.assertEqual(A.__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(A[str].__parameters__, ()) | 
					
						
							|  |  |  |         self.assertEqual(A[str].__args__, (str,)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class A2(Generic[T], TypedDict): | 
					
						
							|  |  |  |             a: T | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(A2.__bases__, (Generic, dict)) | 
					
						
							|  |  |  |         self.assertEqual(A2.__orig_bases__, (Generic[T], TypedDict)) | 
					
						
							|  |  |  |         self.assertEqual(A2.__mro__, (A2, Generic, dict, object)) | 
					
						
							|  |  |  |         self.assertEqual(A2.__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(A2[str].__parameters__, ()) | 
					
						
							|  |  |  |         self.assertEqual(A2[str].__args__, (str,)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class B(A[KT], total=False): | 
					
						
							|  |  |  |             b: KT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(B.__bases__, (Generic, dict)) | 
					
						
							|  |  |  |         self.assertEqual(B.__orig_bases__, (A[KT],)) | 
					
						
							|  |  |  |         self.assertEqual(B.__mro__, (B, Generic, dict, object)) | 
					
						
							|  |  |  |         self.assertEqual(B.__parameters__, (KT,)) | 
					
						
							|  |  |  |         self.assertEqual(B.__total__, False) | 
					
						
							|  |  |  |         self.assertEqual(B.__optional_keys__, frozenset(['b'])) | 
					
						
							|  |  |  |         self.assertEqual(B.__required_keys__, frozenset(['a'])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(B[str].__parameters__, ()) | 
					
						
							|  |  |  |         self.assertEqual(B[str].__args__, (str,)) | 
					
						
							|  |  |  |         self.assertEqual(B[str].__origin__, B) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class C(B[int]): | 
					
						
							|  |  |  |             c: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(C.__bases__, (Generic, dict)) | 
					
						
							|  |  |  |         self.assertEqual(C.__orig_bases__, (B[int],)) | 
					
						
							|  |  |  |         self.assertEqual(C.__mro__, (C, Generic, dict, object)) | 
					
						
							|  |  |  |         self.assertEqual(C.__parameters__, ()) | 
					
						
							|  |  |  |         self.assertEqual(C.__total__, True) | 
					
						
							|  |  |  |         self.assertEqual(C.__optional_keys__, frozenset(['b'])) | 
					
						
							|  |  |  |         self.assertEqual(C.__required_keys__, frozenset(['a', 'c'])) | 
					
						
							|  |  |  |         assert C.__annotations__ == { | 
					
						
							|  |  |  |             'a': T, | 
					
						
							|  |  |  |             'b': KT, | 
					
						
							|  |  |  |             'c': int, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             C[str] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Point3D(Point2DGeneric[T], Generic[T, KT]): | 
					
						
							|  |  |  |             c: KT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(Point3D.__bases__, (Generic, dict)) | 
					
						
							|  |  |  |         self.assertEqual(Point3D.__orig_bases__, (Point2DGeneric[T], Generic[T, KT])) | 
					
						
							|  |  |  |         self.assertEqual(Point3D.__mro__, (Point3D, Generic, dict, object)) | 
					
						
							|  |  |  |         self.assertEqual(Point3D.__parameters__, (T, KT)) | 
					
						
							|  |  |  |         self.assertEqual(Point3D.__total__, True) | 
					
						
							|  |  |  |         self.assertEqual(Point3D.__optional_keys__, frozenset()) | 
					
						
							|  |  |  |         self.assertEqual(Point3D.__required_keys__, frozenset(['a', 'b', 'c'])) | 
					
						
							|  |  |  |         assert Point3D.__annotations__ == { | 
					
						
							|  |  |  |             'a': T, | 
					
						
							|  |  |  |             'b': T, | 
					
						
							|  |  |  |             'c': KT, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         self.assertEqual(Point3D[int, str].__origin__, Point3D) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Point3D[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class Point3D(Point2DGeneric[T], Generic[KT]): | 
					
						
							|  |  |  |                 c: KT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_implicit_any_inheritance(self): | 
					
						
							|  |  |  |         class A(TypedDict, Generic[T]): | 
					
						
							|  |  |  |             a: T | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class B(A[KT], total=False): | 
					
						
							|  |  |  |             b: KT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class WithImplicitAny(B): | 
					
						
							|  |  |  |             c: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(WithImplicitAny.__bases__, (Generic, dict,)) | 
					
						
							|  |  |  |         self.assertEqual(WithImplicitAny.__mro__, (WithImplicitAny, Generic, dict, object)) | 
					
						
							|  |  |  |         # Consistent with GenericTests.test_implicit_any | 
					
						
							|  |  |  |         self.assertEqual(WithImplicitAny.__parameters__, ()) | 
					
						
							|  |  |  |         self.assertEqual(WithImplicitAny.__total__, True) | 
					
						
							|  |  |  |         self.assertEqual(WithImplicitAny.__optional_keys__, frozenset(['b'])) | 
					
						
							|  |  |  |         self.assertEqual(WithImplicitAny.__required_keys__, frozenset(['a', 'c'])) | 
					
						
							|  |  |  |         assert WithImplicitAny.__annotations__ == { | 
					
						
							|  |  |  |             'a': T, | 
					
						
							|  |  |  |             'b': KT, | 
					
						
							|  |  |  |             'c': int, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             WithImplicitAny[str] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-03 01:38:39 +03:00
										 |  |  |     def test_non_generic_subscript(self): | 
					
						
							|  |  |  |         # For backward compatibility, subscription works | 
					
						
							|  |  |  |         # on arbitrary TypedDict types. | 
					
						
							|  |  |  |         class TD(TypedDict): | 
					
						
							|  |  |  |             a: T | 
					
						
							|  |  |  |         A = TD[int] | 
					
						
							|  |  |  |         self.assertEqual(A.__origin__, TD) | 
					
						
							|  |  |  |         self.assertEqual(A.__parameters__, ()) | 
					
						
							|  |  |  |         self.assertEqual(A.__args__, (int,)) | 
					
						
							|  |  |  |         a = A(a = 1) | 
					
						
							|  |  |  |         self.assertIs(type(a), dict) | 
					
						
							|  |  |  |         self.assertEqual(a, {'a': 1}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-23 08:33:39 -06:00
										 |  |  |     def test_orig_bases(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Parent(TypedDict): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Child(Parent): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class OtherChild(Parent): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MixedChild(Child, OtherChild, Parent): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class GenericParent(TypedDict, Generic[T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class GenericChild(GenericParent[int]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class OtherGenericChild(GenericParent[str]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MixedGenericChild(GenericChild, OtherGenericChild, GenericParent[float]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class MultipleGenericBases(GenericParent[int], GenericParent[float]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         CallTypedDict = TypedDict('CallTypedDict', {}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(Parent.__orig_bases__, (TypedDict,)) | 
					
						
							|  |  |  |         self.assertEqual(Child.__orig_bases__, (Parent,)) | 
					
						
							|  |  |  |         self.assertEqual(OtherChild.__orig_bases__, (Parent,)) | 
					
						
							|  |  |  |         self.assertEqual(MixedChild.__orig_bases__, (Child, OtherChild, Parent,)) | 
					
						
							|  |  |  |         self.assertEqual(GenericParent.__orig_bases__, (TypedDict, Generic[T])) | 
					
						
							|  |  |  |         self.assertEqual(GenericChild.__orig_bases__, (GenericParent[int],)) | 
					
						
							|  |  |  |         self.assertEqual(OtherGenericChild.__orig_bases__, (GenericParent[str],)) | 
					
						
							|  |  |  |         self.assertEqual(MixedGenericChild.__orig_bases__, (GenericChild, OtherGenericChild, GenericParent[float])) | 
					
						
							|  |  |  |         self.assertEqual(MultipleGenericBases.__orig_bases__, (GenericParent[int], GenericParent[float])) | 
					
						
							|  |  |  |         self.assertEqual(CallTypedDict.__orig_bases__, (TypedDict,)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-26 09:39:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  | class RequiredTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Required[NotRequired] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Required[int, str] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Required[int][str] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(Required), 'typing.Required') | 
					
						
							|  |  |  |         cv = Required[int] | 
					
						
							|  |  |  |         self.assertEqual(repr(cv), 'typing.Required[int]') | 
					
						
							|  |  |  |         cv = Required[Employee] | 
					
						
							|  |  |  |         self.assertEqual(repr(cv), f'typing.Required[{__name__}.Employee]') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  |             class C(type(Required)): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  |             class C(type(Required[int])): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 r'Cannot subclass typing\.Required'): | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  |             class C(Required): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 r'Cannot subclass typing\.Required\[int\]'): | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  |             class C(Required[int]): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_init(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Required() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(Required)() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(Required[Optional[int]])() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_isinstance(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(1, Required[int]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, Required) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NotRequiredTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NotRequired[Required] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NotRequired[int, str] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NotRequired[int][str] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(NotRequired), 'typing.NotRequired') | 
					
						
							|  |  |  |         cv = NotRequired[int] | 
					
						
							|  |  |  |         self.assertEqual(repr(cv), 'typing.NotRequired[int]') | 
					
						
							|  |  |  |         cv = NotRequired[Employee] | 
					
						
							|  |  |  |         self.assertEqual(repr(cv), f'typing.NotRequired[{__name__}.Employee]') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  |             class C(type(NotRequired)): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  |             class C(type(NotRequired[int])): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 r'Cannot subclass typing\.NotRequired'): | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  |             class C(NotRequired): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 r'Cannot subclass typing\.NotRequired\[int\]'): | 
					
						
							| 
									
										
										
										
											2022-04-12 12:31:02 -07:00
										 |  |  |             class C(NotRequired[int]): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_init(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             NotRequired() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(NotRequired)() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(NotRequired[Optional[int]])() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_isinstance(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(1, NotRequired[int]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, NotRequired) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-21 12:41:19 +01:00
										 |  |  |         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() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-21 12:41:19 +01:00
										 |  |  |         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() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-21 12:41:19 +01:00
										 |  |  |         a = stuff.__annotations__['a'] | 
					
						
							| 
									
										
										
										
											2016-04-19 11:49:37 -05:00
										 |  |  |         self.assertEqual(a.__parameters__, ()) | 
					
						
							| 
									
										
										
										
											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_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:16 +03:00
										 |  |  |         with self.assertRaisesRegex( | 
					
						
							|  |  |  |             TypeError, | 
					
						
							|  |  |  |             r"type 're\.Match' is not an acceptable base type", | 
					
						
							|  |  |  |         ): | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  |             class A(typing.Match): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:16 +03:00
										 |  |  |         with self.assertRaisesRegex( | 
					
						
							|  |  |  |             TypeError, | 
					
						
							|  |  |  |             r"type 're\.Pattern' is not an acceptable base type", | 
					
						
							|  |  |  |         ): | 
					
						
							|  |  |  |             class A(typing.Pattern): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  | class AnnotatedTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-01 12:58:41 +03:00
										 |  |  |     def test_new(self): | 
					
						
							|  |  |  |         with self.assertRaisesRegex( | 
					
						
							|  |  |  |             TypeError, | 
					
						
							|  |  |  |             'Type Annotated cannot be instantiated', | 
					
						
							|  |  |  |         ): | 
					
						
							|  |  |  |             Annotated() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |     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]" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 14:09:19 +03:00
										 |  |  |     def test_dir(self): | 
					
						
							|  |  |  |         dir_items = set(dir(Annotated[int, 4])) | 
					
						
							|  |  |  |         for required_item in [ | 
					
						
							|  |  |  |             '__args__', '__parameters__', '__origin__', | 
					
						
							|  |  |  |             '__metadata__', | 
					
						
							|  |  |  |         ]: | 
					
						
							|  |  |  |             with self.subTest(required_item=required_item): | 
					
						
							|  |  |  |                 self.assertIn(required_item, dir_items) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |     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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-24 22:37:15 -08:00
										 |  |  |     def test_special_form_containment(self): | 
					
						
							|  |  |  |         class C: | 
					
						
							|  |  |  |             classvar: Annotated[ClassVar[int], "a decoration"] = 4 | 
					
						
							|  |  |  |             const: Annotated[Final[int], "Const"] = 4 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(C, globals())['classvar'], ClassVar[int]) | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(C, globals())['const'], Final[int]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |     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"]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-18 17:43:51 +03:00
										 |  |  |     def test_too_few_type_args(self): | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, 'at least two arguments'): | 
					
						
							|  |  |  |             Annotated[int] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |     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] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |     def test_typevar_subst(self): | 
					
						
							|  |  |  |         dec = "a decoration" | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         T1 = TypeVar('T1') | 
					
						
							|  |  |  |         T2 = TypeVar('T2') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         A = Annotated[tuple[*Ts], dec] | 
					
						
							|  |  |  |         self.assertEqual(A[int], Annotated[tuple[int], dec]) | 
					
						
							|  |  |  |         self.assertEqual(A[str, int], Annotated[tuple[str, int], dec]) | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             Annotated[*Ts, dec] | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         B = Annotated[Tuple[Unpack[Ts]], dec] | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |         self.assertEqual(B[int], Annotated[Tuple[int], dec]) | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         self.assertEqual(B[str, int], Annotated[Tuple[str, int], dec]) | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             Annotated[Unpack[Ts], dec] | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         C = Annotated[tuple[T, *Ts], dec] | 
					
						
							|  |  |  |         self.assertEqual(C[int], Annotated[tuple[int], dec]) | 
					
						
							|  |  |  |         self.assertEqual(C[int, str], Annotated[tuple[int, str], dec]) | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             C[int, str, float], | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             Annotated[tuple[int, str, float], dec] | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |         ) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             C[()] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         D = Annotated[Tuple[T, Unpack[Ts]], dec] | 
					
						
							|  |  |  |         self.assertEqual(D[int], Annotated[Tuple[int], dec]) | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |         self.assertEqual(D[int, str], Annotated[Tuple[int, str], dec]) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             D[int, str, float], | 
					
						
							|  |  |  |             Annotated[Tuple[int, str, float], dec] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             D[()] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         E = Annotated[tuple[*Ts, T], dec] | 
					
						
							|  |  |  |         self.assertEqual(E[int], Annotated[tuple[int], dec]) | 
					
						
							|  |  |  |         self.assertEqual(E[int, str], Annotated[tuple[int, str], dec]) | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |         self.assertEqual( | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             E[int, str, float], | 
					
						
							|  |  |  |             Annotated[tuple[int, str, float], dec] | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |         ) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             E[()] | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         F = Annotated[Tuple[Unpack[Ts], T], dec] | 
					
						
							|  |  |  |         self.assertEqual(F[int], Annotated[Tuple[int], dec]) | 
					
						
							|  |  |  |         self.assertEqual(F[int, str], Annotated[Tuple[int, str], dec]) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             F[int, str, float], | 
					
						
							|  |  |  |             Annotated[Tuple[int, str, float], dec] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             F[()] | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         G = Annotated[tuple[T1, *Ts, T2], dec] | 
					
						
							|  |  |  |         self.assertEqual(G[int, str], Annotated[tuple[int, str], dec]) | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |         self.assertEqual( | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             G[int, str, float], | 
					
						
							|  |  |  |             Annotated[tuple[int, str, float], dec] | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             G[int, str, bool, float], | 
					
						
							|  |  |  |             Annotated[tuple[int, str, bool, float], dec] | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             G[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         H = Annotated[Tuple[T1, Unpack[Ts], T2], dec] | 
					
						
							|  |  |  |         self.assertEqual(H[int, str], Annotated[Tuple[int, str], dec]) | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |         self.assertEqual( | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             H[int, str, float], | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |             Annotated[Tuple[int, str, float], dec] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             H[int, str, bool, float], | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  |             Annotated[Tuple[int, str, bool, float], dec] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2022-10-25 15:44:30 +01:00
										 |  |  |             H[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Now let's try creating an alias from an alias. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Ts2 = TypeVarTuple('Ts2') | 
					
						
							|  |  |  |         T3 = TypeVar('T3') | 
					
						
							|  |  |  |         T4 = TypeVar('T4') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # G is Annotated[tuple[T1, *Ts, T2], dec]. | 
					
						
							|  |  |  |         I = G[T3, *Ts2, T4] | 
					
						
							|  |  |  |         J = G[T3, Unpack[Ts2], T4] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for x, y in [ | 
					
						
							|  |  |  |             (I,                  Annotated[tuple[T3, *Ts2, T4], dec]), | 
					
						
							|  |  |  |             (J,                  Annotated[tuple[T3, Unpack[Ts2], T4], dec]), | 
					
						
							|  |  |  |             (I[int, str],        Annotated[tuple[int, str], dec]), | 
					
						
							|  |  |  |             (J[int, str],        Annotated[tuple[int, str], dec]), | 
					
						
							|  |  |  |             (I[int, str, float], Annotated[tuple[int, str, float], dec]), | 
					
						
							|  |  |  |             (J[int, str, float], Annotated[tuple[int, str, float], dec]), | 
					
						
							|  |  |  |             (I[int, str, bool, float], | 
					
						
							|  |  |  |                                  Annotated[tuple[int, str, bool, float], dec]), | 
					
						
							|  |  |  |             (J[int, str, bool, float], | 
					
						
							|  |  |  |                                  Annotated[tuple[int, str, bool, float], dec]), | 
					
						
							|  |  |  |         ]: | 
					
						
							|  |  |  |             self.assertEqual(x, y) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             I[int] | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             J[int] | 
					
						
							| 
									
										
										
										
											2022-04-16 05:24:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  |     def test_annotated_in_other_types(self): | 
					
						
							|  |  |  |         X = List[Annotated[T, 5]] | 
					
						
							|  |  |  |         self.assertEqual(X[int], List[Annotated[int, 5]]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-26 02:13:59 +08:00
										 |  |  |     def test_annotated_mro(self): | 
					
						
							|  |  |  |         class X(Annotated[int, (1, 10)]): ... | 
					
						
							|  |  |  |         self.assertEqual(X.__mro__, (X, int, object), | 
					
						
							|  |  |  |                          "Annotated should be transparent.") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 02:10:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-08 00:44:31 +03:00
										 |  |  | class TypeAliasTests(BaseTestCase): | 
					
						
							|  |  |  |     def test_canonical_usage_with_variable_annotation(self): | 
					
						
							|  |  |  |         Alias: TypeAlias = Employee | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_canonical_usage_with_type_comment(self): | 
					
						
							|  |  |  |         Alias = Employee  # type: TypeAlias | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_instantiate(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypeAlias() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_isinstance(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(42, TypeAlias) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-06 15:16:22 -08:00
										 |  |  |     def test_stringized_usage(self): | 
					
						
							|  |  |  |         class A: | 
					
						
							|  |  |  |             a: "TypeAlias" | 
					
						
							|  |  |  |         self.assertEqual(get_type_hints(A), {'a': TypeAlias}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-08 00:44:31 +03:00
										 |  |  |     def test_no_issubclass(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(Employee, TypeAlias) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(TypeAlias, Employee) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 r'Cannot subclass typing\.TypeAlias'): | 
					
						
							| 
									
										
										
										
											2020-10-08 00:44:31 +03:00
										 |  |  |             class C(TypeAlias): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             class C(type(TypeAlias)): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(TypeAlias), 'typing.TypeAlias') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subscript(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypeAlias[int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-24 12:33:48 +08:00
										 |  |  | class ParamSpecTests(BaseTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic_plain(self): | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         self.assertEqual(P, P) | 
					
						
							|  |  |  |         self.assertIsInstance(P, ParamSpec) | 
					
						
							| 
									
										
										
										
											2023-05-17 06:08:21 -07:00
										 |  |  |         self.assertEqual(P.__name__, 'P') | 
					
						
							| 
									
										
										
										
											2020-12-24 12:33:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_valid_uses(self): | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         C1 = Callable[P, int] | 
					
						
							|  |  |  |         self.assertEqual(C1.__args__, (P, int)) | 
					
						
							|  |  |  |         self.assertEqual(C1.__parameters__, (P,)) | 
					
						
							|  |  |  |         C2 = Callable[P, T] | 
					
						
							|  |  |  |         self.assertEqual(C2.__args__, (P, T)) | 
					
						
							|  |  |  |         self.assertEqual(C2.__parameters__, (P, T)) | 
					
						
							|  |  |  |         # Test collections.abc.Callable too. | 
					
						
							|  |  |  |         C3 = collections.abc.Callable[P, int] | 
					
						
							|  |  |  |         self.assertEqual(C3.__args__, (P, int)) | 
					
						
							|  |  |  |         self.assertEqual(C3.__parameters__, (P,)) | 
					
						
							|  |  |  |         C4 = collections.abc.Callable[P, T] | 
					
						
							|  |  |  |         self.assertEqual(C4.__args__, (P, T)) | 
					
						
							|  |  |  |         self.assertEqual(C4.__parameters__, (P, T)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-10 19:57:05 -07:00
										 |  |  |     def test_args_kwargs(self): | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							| 
									
										
										
										
											2022-02-07 23:46:58 -08:00
										 |  |  |         P_2 = ParamSpec('P_2') | 
					
						
							| 
									
										
										
										
											2020-12-24 12:33:48 +08:00
										 |  |  |         self.assertIn('args', dir(P)) | 
					
						
							|  |  |  |         self.assertIn('kwargs', dir(P)) | 
					
						
							| 
									
										
										
										
											2021-04-10 19:57:05 -07:00
										 |  |  |         self.assertIsInstance(P.args, ParamSpecArgs) | 
					
						
							|  |  |  |         self.assertIsInstance(P.kwargs, ParamSpecKwargs) | 
					
						
							|  |  |  |         self.assertIs(P.args.__origin__, P) | 
					
						
							|  |  |  |         self.assertIs(P.kwargs.__origin__, P) | 
					
						
							| 
									
										
										
										
											2022-02-07 23:46:58 -08:00
										 |  |  |         self.assertEqual(P.args, P.args) | 
					
						
							|  |  |  |         self.assertEqual(P.kwargs, P.kwargs) | 
					
						
							|  |  |  |         self.assertNotEqual(P.args, P_2.args) | 
					
						
							|  |  |  |         self.assertNotEqual(P.kwargs, P_2.kwargs) | 
					
						
							|  |  |  |         self.assertNotEqual(P.args, P.kwargs) | 
					
						
							|  |  |  |         self.assertNotEqual(P.kwargs, P.args) | 
					
						
							|  |  |  |         self.assertNotEqual(P.args, P_2.kwargs) | 
					
						
							| 
									
										
										
										
											2021-04-10 19:57:05 -07:00
										 |  |  |         self.assertEqual(repr(P.args), "P.args") | 
					
						
							|  |  |  |         self.assertEqual(repr(P.kwargs), "P.kwargs") | 
					
						
							| 
									
										
										
										
											2020-12-24 12:33:48 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-02 17:14:52 -08:00
										 |  |  |     def test_stringized(self): | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         class C(Generic[P]): | 
					
						
							|  |  |  |             func: Callable["P", int] | 
					
						
							|  |  |  |             def foo(self, *args: "P.args", **kwargs: "P.kwargs"): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(gth(C, globals(), locals()), {"func": Callable[P, int]}) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             gth(C.foo, globals(), locals()), {"args": P.args, "kwargs": P.kwargs} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-24 12:33:48 +08:00
										 |  |  |     def test_user_generics(self): | 
					
						
							|  |  |  |         T = TypeVar("T") | 
					
						
							|  |  |  |         P = ParamSpec("P") | 
					
						
							|  |  |  |         P_2 = ParamSpec("P_2") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class X(Generic[T, P]): | 
					
						
							|  |  |  |             f: Callable[P, int] | 
					
						
							|  |  |  |             x: T | 
					
						
							|  |  |  |         G1 = X[int, P_2] | 
					
						
							|  |  |  |         self.assertEqual(G1.__args__, (int, P_2)) | 
					
						
							|  |  |  |         self.assertEqual(G1.__parameters__, (P_2,)) | 
					
						
							| 
									
										
										
										
											2021-08-02 09:17:46 +03:00
										 |  |  |         with self.assertRaisesRegex(TypeError, "few arguments for"): | 
					
						
							|  |  |  |             X[int] | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, "many arguments for"): | 
					
						
							|  |  |  |             X[int, P_2, str] | 
					
						
							| 
									
										
										
										
											2020-12-24 12:33:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         G2 = X[int, Concatenate[int, P_2]] | 
					
						
							|  |  |  |         self.assertEqual(G2.__args__, (int, Concatenate[int, P_2])) | 
					
						
							|  |  |  |         self.assertEqual(G2.__parameters__, (P_2,)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         G3 = X[int, [int, bool]] | 
					
						
							|  |  |  |         self.assertEqual(G3.__args__, (int, (int, bool))) | 
					
						
							|  |  |  |         self.assertEqual(G3.__parameters__, ()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         G4 = X[int, ...] | 
					
						
							|  |  |  |         self.assertEqual(G4.__args__, (int, Ellipsis)) | 
					
						
							|  |  |  |         self.assertEqual(G4.__parameters__, ()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Z(Generic[P]): | 
					
						
							|  |  |  |             f: Callable[P, int] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         G5 = Z[[int, str, bool]] | 
					
						
							|  |  |  |         self.assertEqual(G5.__args__, ((int, str, bool),)) | 
					
						
							|  |  |  |         self.assertEqual(G5.__parameters__, ()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         G6 = Z[int, str, bool] | 
					
						
							|  |  |  |         self.assertEqual(G6.__args__, ((int, str, bool),)) | 
					
						
							|  |  |  |         self.assertEqual(G6.__parameters__, ()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # G5 and G6 should be equivalent according to the PEP | 
					
						
							|  |  |  |         self.assertEqual(G5.__args__, G6.__args__) | 
					
						
							|  |  |  |         self.assertEqual(G5.__origin__, G6.__origin__) | 
					
						
							|  |  |  |         self.assertEqual(G5.__parameters__, G6.__parameters__) | 
					
						
							|  |  |  |         self.assertEqual(G5, G6) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-04 21:07:01 +03:00
										 |  |  |         G7 = Z[int] | 
					
						
							|  |  |  |         self.assertEqual(G7.__args__, ((int,),)) | 
					
						
							|  |  |  |         self.assertEqual(G7.__parameters__, ()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, "many arguments for"): | 
					
						
							|  |  |  |             Z[[int, str], bool] | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, "many arguments for"): | 
					
						
							|  |  |  |             Z[P_2, bool] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_multiple_paramspecs_in_user_generics(self): | 
					
						
							|  |  |  |         P = ParamSpec("P") | 
					
						
							|  |  |  |         P2 = ParamSpec("P2") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class X(Generic[P, P2]): | 
					
						
							|  |  |  |             f: Callable[P, int] | 
					
						
							|  |  |  |             g: Callable[P2, str] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         G1 = X[[int, str], [bytes]] | 
					
						
							|  |  |  |         G2 = X[[int], [str, bytes]] | 
					
						
							|  |  |  |         self.assertNotEqual(G1, G2) | 
					
						
							|  |  |  |         self.assertEqual(G1.__args__, ((int, str), (bytes,))) | 
					
						
							|  |  |  |         self.assertEqual(G2.__args__, ((int,), (str, bytes))) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-29 09:46:52 +02:00
										 |  |  |     def test_typevartuple_and_paramspecs_in_user_generics(self): | 
					
						
							|  |  |  |         Ts = TypeVarTuple("Ts") | 
					
						
							|  |  |  |         P = ParamSpec("P") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class X(Generic[*Ts, P]): | 
					
						
							|  |  |  |             f: Callable[P, int] | 
					
						
							|  |  |  |             g: Tuple[*Ts] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         G1 = X[int, [bytes]] | 
					
						
							|  |  |  |         self.assertEqual(G1.__args__, (int, (bytes,))) | 
					
						
							|  |  |  |         G2 = X[int, str, [bytes]] | 
					
						
							|  |  |  |         self.assertEqual(G2.__args__, (int, str, (bytes,))) | 
					
						
							|  |  |  |         G3 = X[[bytes]] | 
					
						
							|  |  |  |         self.assertEqual(G3.__args__, ((bytes,),)) | 
					
						
							|  |  |  |         G4 = X[[]] | 
					
						
							|  |  |  |         self.assertEqual(G4.__args__, ((),)) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             X[()] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Y(Generic[P, *Ts]): | 
					
						
							|  |  |  |             f: Callable[P, int] | 
					
						
							|  |  |  |             g: Tuple[*Ts] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         G1 = Y[[bytes], int] | 
					
						
							|  |  |  |         self.assertEqual(G1.__args__, ((bytes,), int)) | 
					
						
							|  |  |  |         G2 = Y[[bytes], int, str] | 
					
						
							|  |  |  |         self.assertEqual(G2.__args__, ((bytes,), int, str)) | 
					
						
							|  |  |  |         G3 = Y[[bytes]] | 
					
						
							|  |  |  |         self.assertEqual(G3.__args__, ((bytes,),)) | 
					
						
							|  |  |  |         G4 = Y[[]] | 
					
						
							|  |  |  |         self.assertEqual(G4.__args__, ((),)) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             Y[()] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_typevartuple_and_paramspecs_in_generic_aliases(self): | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for C in Callable, collections.abc.Callable: | 
					
						
							|  |  |  |             with self.subTest(generic=C): | 
					
						
							|  |  |  |                 A = C[P, Tuple[*Ts]] | 
					
						
							|  |  |  |                 B = A[[int, str], bytes, float] | 
					
						
							|  |  |  |                 self.assertEqual(B.__args__, (int, str, Tuple[bytes, float])) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class X(Generic[T, P]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A = X[Tuple[*Ts], P] | 
					
						
							|  |  |  |         B = A[bytes, float, [int, str]] | 
					
						
							|  |  |  |         self.assertEqual(B.__args__, (Tuple[bytes, float], (int, str,))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Y(Generic[P, T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A = Y[P, Tuple[*Ts]] | 
					
						
							|  |  |  |         B = A[[int, str], bytes, float] | 
					
						
							|  |  |  |         self.assertEqual(B.__args__, ((int, str,), Tuple[bytes, float])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 10:47:26 +02:00
										 |  |  |     def test_var_substitution(self): | 
					
						
							|  |  |  |         P = ParamSpec("P") | 
					
						
							|  |  |  |         subst = P.__typing_subst__ | 
					
						
							|  |  |  |         self.assertEqual(subst((int, str)), (int, str)) | 
					
						
							|  |  |  |         self.assertEqual(subst([int, str]), (int, str)) | 
					
						
							|  |  |  |         self.assertEqual(subst([None]), (type(None),)) | 
					
						
							|  |  |  |         self.assertIs(subst(...), ...) | 
					
						
							|  |  |  |         self.assertIs(subst(P), P) | 
					
						
							|  |  |  |         self.assertEqual(subst(Concatenate[int, P]), Concatenate[int, P]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-06 21:52:39 +02:00
										 |  |  |     def test_bad_var_substitution(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         bad_args = (42, int, None, T, int|str, Union[int, str]) | 
					
						
							|  |  |  |         for arg in bad_args: | 
					
						
							|  |  |  |             with self.subTest(arg=arg): | 
					
						
							| 
									
										
										
										
											2022-03-11 10:47:26 +02:00
										 |  |  |                 with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                     P.__typing_subst__(arg) | 
					
						
							| 
									
										
										
										
											2022-02-06 21:52:39 +02:00
										 |  |  |                 with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                     typing.Callable[P, T][arg, str] | 
					
						
							|  |  |  |                 with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                     collections.abc.Callable[P, T][arg, str] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-23 19:26:11 +03:00
										 |  |  |     def test_type_var_subst_for_other_type_vars(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         T2 = TypeVar('T2') | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         P2 = ParamSpec('P2') | 
					
						
							|  |  |  |         Ts = TypeVarTuple('Ts') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class Base(Generic[P]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A1 = Base[T] | 
					
						
							|  |  |  |         self.assertEqual(A1.__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(A1.__args__, ((T,),)) | 
					
						
							|  |  |  |         self.assertEqual(A1[int], Base[int]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A2 = Base[[T]] | 
					
						
							|  |  |  |         self.assertEqual(A2.__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(A2.__args__, ((T,),)) | 
					
						
							|  |  |  |         self.assertEqual(A2[int], Base[int]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A3 = Base[[int, T]] | 
					
						
							|  |  |  |         self.assertEqual(A3.__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(A3.__args__, ((int, T),)) | 
					
						
							|  |  |  |         self.assertEqual(A3[str], Base[[int, str]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A4 = Base[[T, int, T2]] | 
					
						
							|  |  |  |         self.assertEqual(A4.__parameters__, (T, T2)) | 
					
						
							|  |  |  |         self.assertEqual(A4.__args__, ((T, int, T2),)) | 
					
						
							|  |  |  |         self.assertEqual(A4[str, bool], Base[[str, int, bool]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A5 = Base[[*Ts, int]] | 
					
						
							|  |  |  |         self.assertEqual(A5.__parameters__, (Ts,)) | 
					
						
							|  |  |  |         self.assertEqual(A5.__args__, ((*Ts, int),)) | 
					
						
							|  |  |  |         self.assertEqual(A5[str, bool], Base[[str, bool, int]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A5_2 = Base[[int, *Ts]] | 
					
						
							|  |  |  |         self.assertEqual(A5_2.__parameters__, (Ts,)) | 
					
						
							|  |  |  |         self.assertEqual(A5_2.__args__, ((int, *Ts),)) | 
					
						
							|  |  |  |         self.assertEqual(A5_2[str, bool], Base[[int, str, bool]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A6 = Base[[T, *Ts]] | 
					
						
							|  |  |  |         self.assertEqual(A6.__parameters__, (T, Ts)) | 
					
						
							|  |  |  |         self.assertEqual(A6.__args__, ((T, *Ts),)) | 
					
						
							|  |  |  |         self.assertEqual(A6[int, str, bool], Base[[int, str, bool]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A7 = Base[[T, T]] | 
					
						
							|  |  |  |         self.assertEqual(A7.__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(A7.__args__, ((T, T),)) | 
					
						
							|  |  |  |         self.assertEqual(A7[int], Base[[int, int]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A8 = Base[[T, list[T]]] | 
					
						
							|  |  |  |         self.assertEqual(A8.__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(A8.__args__, ((T, list[T]),)) | 
					
						
							|  |  |  |         self.assertEqual(A8[int], Base[[int, list[int]]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A9 = Base[[Tuple[*Ts], *Ts]] | 
					
						
							|  |  |  |         self.assertEqual(A9.__parameters__, (Ts,)) | 
					
						
							|  |  |  |         self.assertEqual(A9.__args__, ((Tuple[*Ts], *Ts),)) | 
					
						
							|  |  |  |         self.assertEqual(A9[int, str], Base[Tuple[int, str], int, str]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         A10 = Base[P2] | 
					
						
							|  |  |  |         self.assertEqual(A10.__parameters__, (P2,)) | 
					
						
							|  |  |  |         self.assertEqual(A10.__args__, (P2,)) | 
					
						
							|  |  |  |         self.assertEqual(A10[[int, str]], Base[[int, str]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class DoubleP(Generic[P, P2]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         B1 = DoubleP[P, P2] | 
					
						
							|  |  |  |         self.assertEqual(B1.__parameters__, (P, P2)) | 
					
						
							|  |  |  |         self.assertEqual(B1.__args__, (P, P2)) | 
					
						
							|  |  |  |         self.assertEqual(B1[[int, str], [bool]], DoubleP[[int,  str], [bool]]) | 
					
						
							|  |  |  |         self.assertEqual(B1[[], []], DoubleP[[], []]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         B2 = DoubleP[[int, str], P2] | 
					
						
							|  |  |  |         self.assertEqual(B2.__parameters__, (P2,)) | 
					
						
							|  |  |  |         self.assertEqual(B2.__args__, ((int, str), P2)) | 
					
						
							|  |  |  |         self.assertEqual(B2[[bool, bool]], DoubleP[[int,  str], [bool, bool]]) | 
					
						
							|  |  |  |         self.assertEqual(B2[[]], DoubleP[[int,  str], []]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         B3 = DoubleP[P, [bool, bool]] | 
					
						
							|  |  |  |         self.assertEqual(B3.__parameters__, (P,)) | 
					
						
							|  |  |  |         self.assertEqual(B3.__args__, (P, (bool, bool))) | 
					
						
							|  |  |  |         self.assertEqual(B3[[int, str]], DoubleP[[int,  str], [bool, bool]]) | 
					
						
							|  |  |  |         self.assertEqual(B3[[]], DoubleP[[], [bool, bool]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         B4 = DoubleP[[T, int], [bool, T2]] | 
					
						
							|  |  |  |         self.assertEqual(B4.__parameters__, (T, T2)) | 
					
						
							|  |  |  |         self.assertEqual(B4.__args__, ((T, int), (bool, T2))) | 
					
						
							|  |  |  |         self.assertEqual(B4[str, float], DoubleP[[str, int], [bool, float]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         B5 = DoubleP[[*Ts, int], [bool, T2]] | 
					
						
							|  |  |  |         self.assertEqual(B5.__parameters__, (Ts, T2)) | 
					
						
							|  |  |  |         self.assertEqual(B5.__args__, ((*Ts, int), (bool, T2))) | 
					
						
							|  |  |  |         self.assertEqual(B5[str, bytes, float], | 
					
						
							|  |  |  |                          DoubleP[[str, bytes, int], [bool, float]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         B6 = DoubleP[[T, int], [bool, *Ts]] | 
					
						
							|  |  |  |         self.assertEqual(B6.__parameters__, (T, Ts)) | 
					
						
							|  |  |  |         self.assertEqual(B6.__args__, ((T, int), (bool, *Ts))) | 
					
						
							|  |  |  |         self.assertEqual(B6[str, bytes, float], | 
					
						
							|  |  |  |                          DoubleP[[str, int], [bool, bytes, float]]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class PandT(Generic[P, T]): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         C1 = PandT[P, T] | 
					
						
							|  |  |  |         self.assertEqual(C1.__parameters__, (P, T)) | 
					
						
							|  |  |  |         self.assertEqual(C1.__args__, (P, T)) | 
					
						
							|  |  |  |         self.assertEqual(C1[[int, str], bool], PandT[[int, str], bool]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         C2 = PandT[[int, T], T] | 
					
						
							|  |  |  |         self.assertEqual(C2.__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(C2.__args__, ((int, T), T)) | 
					
						
							|  |  |  |         self.assertEqual(C2[str], PandT[[int, str], str]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         C3 = PandT[[int, *Ts], T] | 
					
						
							|  |  |  |         self.assertEqual(C3.__parameters__, (Ts, T)) | 
					
						
							|  |  |  |         self.assertEqual(C3.__args__, ((int, *Ts), T)) | 
					
						
							|  |  |  |         self.assertEqual(C3[str, bool, bytes], PandT[[int, str, bool], bytes]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-13 13:24:35 +08:00
										 |  |  |     def test_paramspec_in_nested_generics(self): | 
					
						
							|  |  |  |         # Although ParamSpec should not be found in __parameters__ of most | 
					
						
							|  |  |  |         # generics, they probably should be found when nested in | 
					
						
							|  |  |  |         # a valid location. | 
					
						
							|  |  |  |         T = TypeVar("T") | 
					
						
							|  |  |  |         P = ParamSpec("P") | 
					
						
							|  |  |  |         C1 = Callable[P, T] | 
					
						
							|  |  |  |         G1 = List[C1] | 
					
						
							|  |  |  |         G2 = list[C1] | 
					
						
							| 
									
										
										
										
											2021-07-17 06:33:40 +03:00
										 |  |  |         G3 = list[C1] | int | 
					
						
							| 
									
										
										
										
											2021-05-13 13:24:35 +08:00
										 |  |  |         self.assertEqual(G1.__parameters__, (P, T)) | 
					
						
							|  |  |  |         self.assertEqual(G2.__parameters__, (P, T)) | 
					
						
							| 
									
										
										
										
											2021-07-17 06:33:40 +03:00
										 |  |  |         self.assertEqual(G3.__parameters__, (P, T)) | 
					
						
							| 
									
										
										
										
											2022-02-06 21:52:39 +02:00
										 |  |  |         C = Callable[[int, str], float] | 
					
						
							|  |  |  |         self.assertEqual(G1[[int, str], float], List[C]) | 
					
						
							|  |  |  |         self.assertEqual(G2[[int, str], float], list[C]) | 
					
						
							|  |  |  |         self.assertEqual(G3[[int, str], float], list[C] | int) | 
					
						
							| 
									
										
										
										
											2021-05-13 13:24:35 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-10 08:42:15 -06:00
										 |  |  |     def test_paramspec_gets_copied(self): | 
					
						
							|  |  |  |         # bpo-46581 | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         P2 = ParamSpec('P2') | 
					
						
							|  |  |  |         C1 = Callable[P, int] | 
					
						
							|  |  |  |         self.assertEqual(C1.__parameters__, (P,)) | 
					
						
							|  |  |  |         self.assertEqual(C1[P2].__parameters__, (P2,)) | 
					
						
							|  |  |  |         self.assertEqual(C1[str].__parameters__, ()) | 
					
						
							|  |  |  |         self.assertEqual(C1[str, T].__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(C1[Concatenate[str, P2]].__parameters__, (P2,)) | 
					
						
							|  |  |  |         self.assertEqual(C1[Concatenate[T, P2]].__parameters__, (T, P2)) | 
					
						
							|  |  |  |         self.assertEqual(C1[...].__parameters__, ()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         C2 = Callable[Concatenate[str, P], int] | 
					
						
							|  |  |  |         self.assertEqual(C2.__parameters__, (P,)) | 
					
						
							|  |  |  |         self.assertEqual(C2[P2].__parameters__, (P2,)) | 
					
						
							|  |  |  |         self.assertEqual(C2[str].__parameters__, ()) | 
					
						
							|  |  |  |         self.assertEqual(C2[str, T].__parameters__, (T,)) | 
					
						
							|  |  |  |         self.assertEqual(C2[Concatenate[str, P2]].__parameters__, (P2,)) | 
					
						
							|  |  |  |         self.assertEqual(C2[Concatenate[T, P2]].__parameters__, (T, P2)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |     def test_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |         with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpec'): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |             class C(ParamSpec): pass | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |         with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpecArgs'): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |             class C(ParamSpecArgs): pass | 
					
						
							| 
									
										
										
										
											2023-05-15 20:36:23 -07:00
										 |  |  |         with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpecKwargs'): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |             class C(ParamSpecKwargs): pass | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 CANNOT_SUBCLASS_INSTANCE % 'ParamSpec'): | 
					
						
							|  |  |  |             class C(P): pass | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 CANNOT_SUBCLASS_INSTANCE % 'ParamSpecArgs'): | 
					
						
							|  |  |  |             class C(P.args): pass | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                 CANNOT_SUBCLASS_INSTANCE % 'ParamSpecKwargs'): | 
					
						
							|  |  |  |             class C(P.kwargs): pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-24 12:33:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class ConcatenateTests(BaseTestCase): | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         class MyClass: ... | 
					
						
							|  |  |  |         c = Concatenate[MyClass, P] | 
					
						
							|  |  |  |         self.assertNotEqual(c, Concatenate) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 14:09:19 +03:00
										 |  |  |     def test_dir(self): | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         dir_items = set(dir(Concatenate[int, P])) | 
					
						
							|  |  |  |         for required_item in [ | 
					
						
							|  |  |  |             '__args__', '__parameters__', '__origin__', | 
					
						
							|  |  |  |         ]: | 
					
						
							|  |  |  |             with self.subTest(required_item=required_item): | 
					
						
							|  |  |  |                 self.assertIn(required_item, dir_items) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-24 12:33:48 +08:00
										 |  |  |     def test_valid_uses(self): | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         C1 = Callable[Concatenate[int, P], int] | 
					
						
							|  |  |  |         self.assertEqual(C1.__args__, (Concatenate[int, P], int)) | 
					
						
							|  |  |  |         self.assertEqual(C1.__parameters__, (P,)) | 
					
						
							|  |  |  |         C2 = Callable[Concatenate[int, T, P], T] | 
					
						
							|  |  |  |         self.assertEqual(C2.__args__, (Concatenate[int, T, P], T)) | 
					
						
							|  |  |  |         self.assertEqual(C2.__parameters__, (T, P)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Test collections.abc.Callable too. | 
					
						
							|  |  |  |         C3 = collections.abc.Callable[Concatenate[int, P], int] | 
					
						
							|  |  |  |         self.assertEqual(C3.__args__, (Concatenate[int, P], int)) | 
					
						
							|  |  |  |         self.assertEqual(C3.__parameters__, (P,)) | 
					
						
							|  |  |  |         C4 = collections.abc.Callable[Concatenate[int, T, P], T] | 
					
						
							|  |  |  |         self.assertEqual(C4.__args__, (Concatenate[int, T, P], T)) | 
					
						
							|  |  |  |         self.assertEqual(C4.__parameters__, (T, P)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-27 14:34:55 +02:00
										 |  |  |     def test_var_substitution(self): | 
					
						
							|  |  |  |         T = TypeVar('T') | 
					
						
							|  |  |  |         P = ParamSpec('P') | 
					
						
							|  |  |  |         P2 = ParamSpec('P2') | 
					
						
							|  |  |  |         C = Concatenate[T, P] | 
					
						
							|  |  |  |         self.assertEqual(C[int, P2], Concatenate[int, P2]) | 
					
						
							|  |  |  |         self.assertEqual(C[int, [str, float]], (int, str, float)) | 
					
						
							|  |  |  |         self.assertEqual(C[int, []], (int,)) | 
					
						
							|  |  |  |         self.assertEqual(C[int, Concatenate[str, P2]], | 
					
						
							|  |  |  |                          Concatenate[int, str, P2]) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:01:40 +03:00
										 |  |  |         self.assertEqual(C[int, ...], Concatenate[int, ...]) | 
					
						
							| 
									
										
										
										
											2022-01-27 14:34:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         C = Concatenate[int, P] | 
					
						
							|  |  |  |         self.assertEqual(C[P2], Concatenate[int, P2]) | 
					
						
							|  |  |  |         self.assertEqual(C[[str, float]], (int, str, float)) | 
					
						
							|  |  |  |         self.assertEqual(C[str, float], (int, str, float)) | 
					
						
							|  |  |  |         self.assertEqual(C[[]], (int,)) | 
					
						
							|  |  |  |         self.assertEqual(C[Concatenate[str, P2]], Concatenate[int, str, P2]) | 
					
						
							| 
									
										
										
										
											2022-04-30 00:01:40 +03:00
										 |  |  |         self.assertEqual(C[...], Concatenate[int, ...]) | 
					
						
							| 
									
										
										
										
											2020-12-24 12:33:48 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-27 22:31:04 +08:00
										 |  |  | class TypeGuardTests(BaseTestCase): | 
					
						
							|  |  |  |     def test_basics(self): | 
					
						
							|  |  |  |         TypeGuard[int]  # OK | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         def foo(arg) -> TypeGuard[int]: ... | 
					
						
							|  |  |  |         self.assertEqual(gth(foo), {'return': TypeGuard[int]}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 17:12:17 -08:00
										 |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypeGuard[int, str] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-27 22:31:04 +08:00
										 |  |  |     def test_repr(self): | 
					
						
							|  |  |  |         self.assertEqual(repr(TypeGuard), 'typing.TypeGuard') | 
					
						
							|  |  |  |         cv = TypeGuard[int] | 
					
						
							|  |  |  |         self.assertEqual(repr(cv), 'typing.TypeGuard[int]') | 
					
						
							|  |  |  |         cv = TypeGuard[Employee] | 
					
						
							|  |  |  |         self.assertEqual(repr(cv), 'typing.TypeGuard[%s.Employee]' % __name__) | 
					
						
							|  |  |  |         cv = TypeGuard[tuple[int]] | 
					
						
							|  |  |  |         self.assertEqual(repr(cv), 'typing.TypeGuard[tuple[int]]') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_subclass(self): | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2021-04-27 22:31:04 +08:00
										 |  |  |             class C(type(TypeGuard)): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-06-25 01:35:33 -05:00
										 |  |  |         with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): | 
					
						
							| 
									
										
										
										
											2021-04-27 22:31:04 +08:00
										 |  |  |             class C(type(TypeGuard[int])): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2022-09-14 05:35:16 +03:00
										 |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                                     r'Cannot subclass typing\.TypeGuard'): | 
					
						
							|  |  |  |             class C(TypeGuard): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         with self.assertRaisesRegex(TypeError, | 
					
						
							|  |  |  |                                     r'Cannot subclass typing\.TypeGuard\[int\]'): | 
					
						
							|  |  |  |             class C(TypeGuard[int]): | 
					
						
							|  |  |  |                 pass | 
					
						
							| 
									
										
										
										
											2021-04-27 22:31:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_init(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             TypeGuard() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(TypeGuard)() | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             type(TypeGuard[Optional[int]])() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_isinstance(self): | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             isinstance(1, TypeGuard[int]) | 
					
						
							|  |  |  |         with self.assertRaises(TypeError): | 
					
						
							|  |  |  |             issubclass(int, TypeGuard) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  | SpecialAttrsP = typing.ParamSpec('SpecialAttrsP') | 
					
						
							|  |  |  | SpecialAttrsT = typing.TypeVar('SpecialAttrsT', int, float, complex) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-19 20:22:12 +03:00
										 |  |  | class SpecialAttrsTests(BaseTestCase): | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-19 20:22:12 +03:00
										 |  |  |     def test_special_attrs(self): | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |         cls_to_check = { | 
					
						
							| 
									
										
										
										
											2021-07-19 20:22:12 +03:00
										 |  |  |             # ABC classes | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |             typing.AbstractSet: 'AbstractSet', | 
					
						
							|  |  |  |             typing.AsyncContextManager: 'AsyncContextManager', | 
					
						
							|  |  |  |             typing.AsyncGenerator: 'AsyncGenerator', | 
					
						
							|  |  |  |             typing.AsyncIterable: 'AsyncIterable', | 
					
						
							|  |  |  |             typing.AsyncIterator: 'AsyncIterator', | 
					
						
							|  |  |  |             typing.Awaitable: 'Awaitable', | 
					
						
							| 
									
										
										
										
											2023-05-13 09:55:35 +01:00
										 |  |  |             typing.ByteString: 'ByteString', | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |             typing.Callable: 'Callable', | 
					
						
							|  |  |  |             typing.ChainMap: 'ChainMap', | 
					
						
							|  |  |  |             typing.Collection: 'Collection', | 
					
						
							|  |  |  |             typing.Container: 'Container', | 
					
						
							|  |  |  |             typing.ContextManager: 'ContextManager', | 
					
						
							|  |  |  |             typing.Coroutine: 'Coroutine', | 
					
						
							|  |  |  |             typing.Counter: 'Counter', | 
					
						
							|  |  |  |             typing.DefaultDict: 'DefaultDict', | 
					
						
							|  |  |  |             typing.Deque: 'Deque', | 
					
						
							|  |  |  |             typing.Dict: 'Dict', | 
					
						
							|  |  |  |             typing.FrozenSet: 'FrozenSet', | 
					
						
							|  |  |  |             typing.Generator: 'Generator', | 
					
						
							|  |  |  |             typing.Hashable: 'Hashable', | 
					
						
							|  |  |  |             typing.ItemsView: 'ItemsView', | 
					
						
							|  |  |  |             typing.Iterable: 'Iterable', | 
					
						
							|  |  |  |             typing.Iterator: 'Iterator', | 
					
						
							|  |  |  |             typing.KeysView: 'KeysView', | 
					
						
							|  |  |  |             typing.List: 'List', | 
					
						
							|  |  |  |             typing.Mapping: 'Mapping', | 
					
						
							|  |  |  |             typing.MappingView: 'MappingView', | 
					
						
							|  |  |  |             typing.MutableMapping: 'MutableMapping', | 
					
						
							|  |  |  |             typing.MutableSequence: 'MutableSequence', | 
					
						
							|  |  |  |             typing.MutableSet: 'MutableSet', | 
					
						
							|  |  |  |             typing.OrderedDict: 'OrderedDict', | 
					
						
							|  |  |  |             typing.Reversible: 'Reversible', | 
					
						
							|  |  |  |             typing.Sequence: 'Sequence', | 
					
						
							|  |  |  |             typing.Set: 'Set', | 
					
						
							|  |  |  |             typing.Sized: 'Sized', | 
					
						
							|  |  |  |             typing.Tuple: 'Tuple', | 
					
						
							|  |  |  |             typing.Type: 'Type', | 
					
						
							|  |  |  |             typing.ValuesView: 'ValuesView', | 
					
						
							|  |  |  |             # Subscribed ABC classes | 
					
						
							|  |  |  |             typing.AbstractSet[Any]: 'AbstractSet', | 
					
						
							|  |  |  |             typing.AsyncContextManager[Any]: 'AsyncContextManager', | 
					
						
							|  |  |  |             typing.AsyncGenerator[Any, Any]: 'AsyncGenerator', | 
					
						
							|  |  |  |             typing.AsyncIterable[Any]: 'AsyncIterable', | 
					
						
							|  |  |  |             typing.AsyncIterator[Any]: 'AsyncIterator', | 
					
						
							|  |  |  |             typing.Awaitable[Any]: 'Awaitable', | 
					
						
							|  |  |  |             typing.Callable[[], Any]: 'Callable', | 
					
						
							|  |  |  |             typing.Callable[..., Any]: 'Callable', | 
					
						
							|  |  |  |             typing.ChainMap[Any, Any]: 'ChainMap', | 
					
						
							|  |  |  |             typing.Collection[Any]: 'Collection', | 
					
						
							|  |  |  |             typing.Container[Any]: 'Container', | 
					
						
							|  |  |  |             typing.ContextManager[Any]: 'ContextManager', | 
					
						
							|  |  |  |             typing.Coroutine[Any, Any, Any]: 'Coroutine', | 
					
						
							|  |  |  |             typing.Counter[Any]: 'Counter', | 
					
						
							|  |  |  |             typing.DefaultDict[Any, Any]: 'DefaultDict', | 
					
						
							|  |  |  |             typing.Deque[Any]: 'Deque', | 
					
						
							|  |  |  |             typing.Dict[Any, Any]: 'Dict', | 
					
						
							|  |  |  |             typing.FrozenSet[Any]: 'FrozenSet', | 
					
						
							|  |  |  |             typing.Generator[Any, Any, Any]: 'Generator', | 
					
						
							|  |  |  |             typing.ItemsView[Any, Any]: 'ItemsView', | 
					
						
							|  |  |  |             typing.Iterable[Any]: 'Iterable', | 
					
						
							|  |  |  |             typing.Iterator[Any]: 'Iterator', | 
					
						
							|  |  |  |             typing.KeysView[Any]: 'KeysView', | 
					
						
							|  |  |  |             typing.List[Any]: 'List', | 
					
						
							|  |  |  |             typing.Mapping[Any, Any]: 'Mapping', | 
					
						
							|  |  |  |             typing.MappingView[Any]: 'MappingView', | 
					
						
							|  |  |  |             typing.MutableMapping[Any, Any]: 'MutableMapping', | 
					
						
							|  |  |  |             typing.MutableSequence[Any]: 'MutableSequence', | 
					
						
							|  |  |  |             typing.MutableSet[Any]: 'MutableSet', | 
					
						
							|  |  |  |             typing.OrderedDict[Any, Any]: 'OrderedDict', | 
					
						
							|  |  |  |             typing.Reversible[Any]: 'Reversible', | 
					
						
							|  |  |  |             typing.Sequence[Any]: 'Sequence', | 
					
						
							|  |  |  |             typing.Set[Any]: 'Set', | 
					
						
							|  |  |  |             typing.Tuple[Any]: 'Tuple', | 
					
						
							|  |  |  |             typing.Tuple[Any, ...]: 'Tuple', | 
					
						
							|  |  |  |             typing.Type[Any]: 'Type', | 
					
						
							|  |  |  |             typing.ValuesView[Any]: 'ValuesView', | 
					
						
							| 
									
										
										
										
											2021-07-19 20:22:12 +03:00
										 |  |  |             # Special Forms | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |             typing.Annotated: 'Annotated', | 
					
						
							|  |  |  |             typing.Any: 'Any', | 
					
						
							|  |  |  |             typing.ClassVar: 'ClassVar', | 
					
						
							|  |  |  |             typing.Concatenate: 'Concatenate', | 
					
						
							|  |  |  |             typing.Final: 'Final', | 
					
						
							|  |  |  |             typing.ForwardRef: 'ForwardRef', | 
					
						
							|  |  |  |             typing.Literal: 'Literal', | 
					
						
							|  |  |  |             typing.NewType: 'NewType', | 
					
						
							|  |  |  |             typing.NoReturn: 'NoReturn', | 
					
						
							| 
									
										
										
										
											2022-02-19 04:56:30 +03:00
										 |  |  |             typing.Never: 'Never', | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |             typing.Optional: 'Optional', | 
					
						
							|  |  |  |             typing.TypeAlias: 'TypeAlias', | 
					
						
							|  |  |  |             typing.TypeGuard: 'TypeGuard', | 
					
						
							|  |  |  |             typing.TypeVar: 'TypeVar', | 
					
						
							|  |  |  |             typing.Union: 'Union', | 
					
						
							| 
									
										
										
										
											2022-02-19 04:56:30 +03:00
										 |  |  |             typing.Self: 'Self', | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |             # Subscribed special forms | 
					
						
							|  |  |  |             typing.Annotated[Any, "Annotation"]: 'Annotated', | 
					
						
							| 
									
										
										
										
											2022-09-01 07:02:24 +08:00
										 |  |  |             typing.Annotated[int, 'Annotation']: 'Annotated', | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |             typing.ClassVar[Any]: 'ClassVar', | 
					
						
							|  |  |  |             typing.Concatenate[Any, SpecialAttrsP]: 'Concatenate', | 
					
						
							|  |  |  |             typing.Final[Any]: 'Final', | 
					
						
							|  |  |  |             typing.Literal[Any]: 'Literal', | 
					
						
							| 
									
										
										
										
											2021-10-31 10:22:16 +02:00
										 |  |  |             typing.Literal[1, 2]: 'Literal', | 
					
						
							|  |  |  |             typing.Literal[True, 2]: 'Literal', | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |             typing.Optional[Any]: 'Optional', | 
					
						
							|  |  |  |             typing.TypeGuard[Any]: 'TypeGuard', | 
					
						
							|  |  |  |             typing.Union[Any]: 'Any', | 
					
						
							|  |  |  |             typing.Union[int, float]: 'Union', | 
					
						
							|  |  |  |             # Incompatible special forms (tested in test_special_attrs2) | 
					
						
							|  |  |  |             # - typing.ForwardRef('set[Any]') | 
					
						
							|  |  |  |             # - typing.NewType('TypeName', Any) | 
					
						
							|  |  |  |             # - typing.ParamSpec('SpecialAttrsP') | 
					
						
							|  |  |  |             # - typing.TypeVar('T') | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-07-19 20:22:12 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |         for cls, name in cls_to_check.items(): | 
					
						
							| 
									
										
										
										
											2021-07-19 20:22:12 +03:00
										 |  |  |             with self.subTest(cls=cls): | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |                 self.assertEqual(cls.__name__, name, str(cls)) | 
					
						
							|  |  |  |                 self.assertEqual(cls.__qualname__, name, str(cls)) | 
					
						
							|  |  |  |                 self.assertEqual(cls.__module__, 'typing', str(cls)) | 
					
						
							|  |  |  |                 for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |                     s = pickle.dumps(cls, proto) | 
					
						
							|  |  |  |                     loaded = pickle.loads(s) | 
					
						
							|  |  |  |                     self.assertIs(cls, loaded) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     TypeName = typing.NewType('SpecialAttrsTests.TypeName', Any) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_special_attrs2(self): | 
					
						
							|  |  |  |         # Forward refs provide a different introspection API. __name__ and | 
					
						
							|  |  |  |         # __qualname__ make little sense for forward refs as they can store | 
					
						
							|  |  |  |         # complex typing expressions. | 
					
						
							|  |  |  |         fr = typing.ForwardRef('set[Any]') | 
					
						
							|  |  |  |         self.assertFalse(hasattr(fr, '__name__')) | 
					
						
							|  |  |  |         self.assertFalse(hasattr(fr, '__qualname__')) | 
					
						
							|  |  |  |         self.assertEqual(fr.__module__, 'typing') | 
					
						
							|  |  |  |         # Forward refs are currently unpicklable. | 
					
						
							|  |  |  |         for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							| 
									
										
										
										
											2023-03-05 21:37:29 +00:00
										 |  |  |             with self.assertRaises(TypeError): | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |                 pickle.dumps(fr, proto) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(SpecialAttrsTests.TypeName.__name__, 'TypeName') | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             SpecialAttrsTests.TypeName.__qualname__, | 
					
						
							|  |  |  |             'SpecialAttrsTests.TypeName', | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             SpecialAttrsTests.TypeName.__module__, | 
					
						
							| 
									
										
										
										
											2022-01-19 17:13:38 +03:00
										 |  |  |             __name__, | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |         ) | 
					
						
							|  |  |  |         # NewTypes are picklable assuming correct qualname information. | 
					
						
							|  |  |  |         for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |             s = pickle.dumps(SpecialAttrsTests.TypeName, proto) | 
					
						
							|  |  |  |             loaded = pickle.loads(s) | 
					
						
							|  |  |  |             self.assertIs(SpecialAttrsTests.TypeName, loaded) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Type variables don't support non-global instantiation per PEP 484 | 
					
						
							|  |  |  |         # restriction that "The argument to TypeVar() must be a string equal | 
					
						
							|  |  |  |         # to the variable name to which it is assigned".  Thus, providing | 
					
						
							|  |  |  |         # __qualname__ is unnecessary. | 
					
						
							|  |  |  |         self.assertEqual(SpecialAttrsT.__name__, 'SpecialAttrsT') | 
					
						
							|  |  |  |         self.assertFalse(hasattr(SpecialAttrsT, '__qualname__')) | 
					
						
							| 
									
										
										
										
											2022-01-19 17:13:38 +03:00
										 |  |  |         self.assertEqual(SpecialAttrsT.__module__, __name__) | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |         # Module-level type variables are picklable. | 
					
						
							|  |  |  |         for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |             s = pickle.dumps(SpecialAttrsT, proto) | 
					
						
							|  |  |  |             loaded = pickle.loads(s) | 
					
						
							|  |  |  |             self.assertIs(SpecialAttrsT, loaded) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(SpecialAttrsP.__name__, 'SpecialAttrsP') | 
					
						
							|  |  |  |         self.assertFalse(hasattr(SpecialAttrsP, '__qualname__')) | 
					
						
							| 
									
										
										
										
											2022-01-19 17:13:38 +03:00
										 |  |  |         self.assertEqual(SpecialAttrsP.__module__, __name__) | 
					
						
							| 
									
										
										
										
											2021-08-06 15:36:35 +02:00
										 |  |  |         # Module-level ParamSpecs are picklable. | 
					
						
							|  |  |  |         for proto in range(pickle.HIGHEST_PROTOCOL + 1): | 
					
						
							|  |  |  |             s = pickle.dumps(SpecialAttrsP, proto) | 
					
						
							|  |  |  |             loaded = pickle.loads(s) | 
					
						
							|  |  |  |             self.assertIs(SpecialAttrsP, loaded) | 
					
						
							| 
									
										
										
										
											2021-07-19 20:22:12 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-16 22:29:59 +08:00
										 |  |  |     def test_genericalias_dir(self): | 
					
						
							|  |  |  |         class Foo(Generic[T]): | 
					
						
							|  |  |  |             def bar(self): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             baz = 3 | 
					
						
							| 
									
										
										
										
											2023-04-10 14:09:19 +03:00
										 |  |  |             __magic__ = 4 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-16 22:29:59 +08:00
										 |  |  |         # The class attributes of the original class should be visible even | 
					
						
							|  |  |  |         # in dir() of the GenericAlias. See bpo-45755. | 
					
						
							| 
									
										
										
										
											2023-04-10 14:09:19 +03:00
										 |  |  |         dir_items = set(dir(Foo[int])) | 
					
						
							|  |  |  |         for required_item in [ | 
					
						
							|  |  |  |             'bar', 'baz', | 
					
						
							|  |  |  |             '__args__', '__parameters__', '__origin__', | 
					
						
							|  |  |  |         ]: | 
					
						
							|  |  |  |             with self.subTest(required_item=required_item): | 
					
						
							|  |  |  |                 self.assertIn(required_item, dir_items) | 
					
						
							|  |  |  |         self.assertNotIn('__magic__', dir_items) | 
					
						
							| 
									
										
										
										
											2021-12-16 22:29:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-01 18:48:55 -08:00
										 |  |  | class RevealTypeTests(BaseTestCase): | 
					
						
							|  |  |  |     def test_reveal_type(self): | 
					
						
							|  |  |  |         obj = object() | 
					
						
							|  |  |  |         with captured_stderr() as stderr: | 
					
						
							|  |  |  |             self.assertIs(obj, reveal_type(obj)) | 
					
						
							|  |  |  |         self.assertEqual(stderr.getvalue(), "Runtime type is 'object'\n") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-25 20:30:25 -07:00
										 |  |  | class DataclassTransformTests(BaseTestCase): | 
					
						
							|  |  |  |     def test_decorator(self): | 
					
						
							|  |  |  |         def create_model(*, frozen: bool = False, kw_only: bool = True): | 
					
						
							|  |  |  |             return lambda cls: cls | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         decorated = dataclass_transform(kw_only_default=True, order_default=False)(create_model) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CustomerModel: | 
					
						
							|  |  |  |             id: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIs(decorated, create_model) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             decorated.__dataclass_transform__, | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "eq_default": True, | 
					
						
							|  |  |  |                 "order_default": False, | 
					
						
							|  |  |  |                 "kw_only_default": True, | 
					
						
							| 
									
										
										
										
											2022-12-05 19:35:43 -08:00
										 |  |  |                 "frozen_default": False, | 
					
						
							| 
									
										
										
										
											2022-04-25 20:30:25 -07:00
										 |  |  |                 "field_specifiers": (), | 
					
						
							|  |  |  |                 "kwargs": {}, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertIs( | 
					
						
							|  |  |  |             decorated(frozen=True, kw_only=False)(CustomerModel), | 
					
						
							|  |  |  |             CustomerModel | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_base_class(self): | 
					
						
							|  |  |  |         class ModelBase: | 
					
						
							|  |  |  |             def __init_subclass__(cls, *, frozen: bool = False): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Decorated = dataclass_transform( | 
					
						
							|  |  |  |             eq_default=True, | 
					
						
							|  |  |  |             order_default=True, | 
					
						
							|  |  |  |             # Arbitrary unrecognized kwargs are accepted at runtime. | 
					
						
							|  |  |  |             make_everything_awesome=True, | 
					
						
							|  |  |  |         )(ModelBase) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CustomerModel(Decorated, frozen=True): | 
					
						
							|  |  |  |             id: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIs(Decorated, ModelBase) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             Decorated.__dataclass_transform__, | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "eq_default": True, | 
					
						
							|  |  |  |                 "order_default": True, | 
					
						
							|  |  |  |                 "kw_only_default": False, | 
					
						
							| 
									
										
										
										
											2022-12-05 19:35:43 -08:00
										 |  |  |                 "frozen_default": False, | 
					
						
							| 
									
										
										
										
											2022-04-25 20:30:25 -07:00
										 |  |  |                 "field_specifiers": (), | 
					
						
							|  |  |  |                 "kwargs": {"make_everything_awesome": True}, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertIsSubclass(CustomerModel, Decorated) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_metaclass(self): | 
					
						
							|  |  |  |         class Field: ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class ModelMeta(type): | 
					
						
							|  |  |  |             def __new__( | 
					
						
							|  |  |  |                 cls, name, bases, namespace, *, init: bool = True, | 
					
						
							|  |  |  |             ): | 
					
						
							|  |  |  |                 return super().__new__(cls, name, bases, namespace) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Decorated = dataclass_transform( | 
					
						
							| 
									
										
										
										
											2022-12-05 19:35:43 -08:00
										 |  |  |             order_default=True, frozen_default=True, field_specifiers=(Field,) | 
					
						
							| 
									
										
										
										
											2022-04-25 20:30:25 -07:00
										 |  |  |         )(ModelMeta) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class ModelBase(metaclass=Decorated): ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         class CustomerModel(ModelBase, init=False): | 
					
						
							|  |  |  |             id: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertIs(Decorated, ModelMeta) | 
					
						
							|  |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             Decorated.__dataclass_transform__, | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "eq_default": True, | 
					
						
							|  |  |  |                 "order_default": True, | 
					
						
							|  |  |  |                 "kw_only_default": False, | 
					
						
							| 
									
										
										
										
											2022-12-05 19:35:43 -08:00
										 |  |  |                 "frozen_default": True, | 
					
						
							| 
									
										
										
										
											2022-04-25 20:30:25 -07:00
										 |  |  |                 "field_specifiers": (Field,), | 
					
						
							|  |  |  |                 "kwargs": {}, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         self.assertIsInstance(CustomerModel, Decorated) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							| 
									
										
										
										
											2022-01-20 00:24:27 +03:00
										 |  |  |         # Context managers. | 
					
						
							|  |  |  |         self.assertIn('ContextManager', a) | 
					
						
							|  |  |  |         self.assertIn('AsyncContextManager', a) | 
					
						
							| 
									
										
										
										
											2023-05-23 15:44:26 +02:00
										 |  |  |         # Check that former namespaces 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): | 
					
						
							|  |  |  |         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 | 
					
						
							|  |  |  |                 # 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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-08 14:21:28 +01:00
										 |  |  | class TypeIterationTests(BaseTestCase): | 
					
						
							|  |  |  |     _UNITERABLE_TYPES = ( | 
					
						
							|  |  |  |         Any, | 
					
						
							|  |  |  |         Union, | 
					
						
							|  |  |  |         Union[str, int], | 
					
						
							|  |  |  |         Union[str, T], | 
					
						
							|  |  |  |         List, | 
					
						
							|  |  |  |         Tuple, | 
					
						
							|  |  |  |         Callable, | 
					
						
							|  |  |  |         Callable[..., T], | 
					
						
							|  |  |  |         Callable[[T], str], | 
					
						
							|  |  |  |         Annotated, | 
					
						
							|  |  |  |         Annotated[T, ''], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_cannot_iterate(self): | 
					
						
							|  |  |  |         expected_error_regex = "object is not iterable" | 
					
						
							|  |  |  |         for test_type in self._UNITERABLE_TYPES: | 
					
						
							|  |  |  |             with self.subTest(type=test_type): | 
					
						
							|  |  |  |                 with self.assertRaisesRegex(TypeError, expected_error_regex): | 
					
						
							|  |  |  |                     iter(test_type) | 
					
						
							|  |  |  |                 with self.assertRaisesRegex(TypeError, expected_error_regex): | 
					
						
							|  |  |  |                     list(test_type) | 
					
						
							|  |  |  |                 with self.assertRaisesRegex(TypeError, expected_error_regex): | 
					
						
							|  |  |  |                     for _ in test_type: | 
					
						
							|  |  |  |                         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_is_not_instance_of_iterable(self): | 
					
						
							|  |  |  |         for type_to_test in self._UNITERABLE_TYPES: | 
					
						
							|  |  |  |             self.assertNotIsInstance(type_to_test, collections.abc.Iterable) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-22 10:14:11 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     main() |