diff options
author | Nikita Sobolev <mail@sobolevn.me> | 2023-03-16 14:47:30 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-16 14:47:30 (GMT) |
commit | fbe82fdd777cead5d6e08ac0d1da19738c19bd81 (patch) | |
tree | b85c7bed7db51840d0b16060c9bbeaec231fe3c7 /Lib | |
parent | b0ec6253c9cf1b22b87cd99f317dbaeb31263b20 (diff) | |
download | cpython-fbe82fdd777cead5d6e08ac0d1da19738c19bd81.zip cpython-fbe82fdd777cead5d6e08ac0d1da19738c19bd81.tar.gz cpython-fbe82fdd777cead5d6e08ac0d1da19738c19bd81.tar.bz2 |
gh-102721: Improve coverage of `_collections_abc._CallableGenericAlias` (#102722)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/_collections_abc.py | 7 | ||||
-rw-r--r-- | Lib/test/test_typing.py | 39 |
2 files changed, 32 insertions, 14 deletions
diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py index f86b91a..9d7724c 100644 --- a/Lib/_collections_abc.py +++ b/Lib/_collections_abc.py @@ -481,15 +481,8 @@ class _CallableGenericAlias(GenericAlias): # rather than the default types.GenericAlias object. Most of the # code is copied from typing's _GenericAlias and the builtin # types.GenericAlias. - if not isinstance(item, tuple): item = (item,) - # A special case in PEP 612 where if X = Callable[P, int], - # then X[int, str] == X[[int, str]]. - if (len(self.__parameters__) == 1 - and _is_param_expr(self.__parameters__[0]) - and item and not _is_param_expr(item[0])): - item = (item,) new_args = super().__getitem__(item).__args__ diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 89c725c..c9f55de 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1921,14 +1921,29 @@ class BaseCallableTests: self.assertEqual(weakref.ref(alias)(), alias) def test_pickle(self): + global T_pickle, P_pickle, TS_pickle # needed for pickling Callable = self.Callable - alias = Callable[[int, str], float] - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - 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__) + 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 def test_var_substitution(self): Callable = self.Callable @@ -1954,6 +1969,16 @@ class BaseCallableTests: self.assertEqual(C5[int, str, float], Callable[[typing.List[int], tuple[str, int], float], int]) + 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] + def test_type_erasure(self): Callable = self.Callable class C1(Callable): |