Skip to content

Commit fbe82fd

Browse files
gh-102721: Improve coverage of _collections_abc._CallableGenericAlias (#102722)
Co-authored-by: Alex Waygood <[email protected]>
1 parent b0ec625 commit fbe82fd

File tree

2 files changed

+32
-14
lines changed

2 files changed

+32
-14
lines changed

Lib/_collections_abc.py

-7
Original file line numberDiff line numberDiff line change
@@ -481,15 +481,8 @@ def __getitem__(self, item):
481481
# rather than the default types.GenericAlias object. Most of the
482482
# code is copied from typing's _GenericAlias and the builtin
483483
# types.GenericAlias.
484-
485484
if not isinstance(item, tuple):
486485
item = (item,)
487-
# A special case in PEP 612 where if X = Callable[P, int],
488-
# then X[int, str] == X[[int, str]].
489-
if (len(self.__parameters__) == 1
490-
and _is_param_expr(self.__parameters__[0])
491-
and item and not _is_param_expr(item[0])):
492-
item = (item,)
493486

494487
new_args = super().__getitem__(item).__args__
495488

Lib/test/test_typing.py

+32-7
Original file line numberDiff line numberDiff line change
@@ -1921,14 +1921,29 @@ def test_weakref(self):
19211921
self.assertEqual(weakref.ref(alias)(), alias)
19221922

19231923
def test_pickle(self):
1924+
global T_pickle, P_pickle, TS_pickle # needed for pickling
19241925
Callable = self.Callable
1925-
alias = Callable[[int, str], float]
1926-
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1927-
s = pickle.dumps(alias, proto)
1928-
loaded = pickle.loads(s)
1929-
self.assertEqual(alias.__origin__, loaded.__origin__)
1930-
self.assertEqual(alias.__args__, loaded.__args__)
1931-
self.assertEqual(alias.__parameters__, loaded.__parameters__)
1926+
T_pickle = TypeVar('T_pickle')
1927+
P_pickle = ParamSpec('P_pickle')
1928+
TS_pickle = TypeVarTuple('TS_pickle')
1929+
1930+
samples = [
1931+
Callable[[int, str], float],
1932+
Callable[P_pickle, int],
1933+
Callable[P_pickle, T_pickle],
1934+
Callable[Concatenate[int, P_pickle], int],
1935+
Callable[Concatenate[*TS_pickle, P_pickle], int],
1936+
]
1937+
for alias in samples:
1938+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
1939+
with self.subTest(alias=alias, proto=proto):
1940+
s = pickle.dumps(alias, proto)
1941+
loaded = pickle.loads(s)
1942+
self.assertEqual(alias.__origin__, loaded.__origin__)
1943+
self.assertEqual(alias.__args__, loaded.__args__)
1944+
self.assertEqual(alias.__parameters__, loaded.__parameters__)
1945+
1946+
del T_pickle, P_pickle, TS_pickle # cleaning up global state
19321947

19331948
def test_var_substitution(self):
19341949
Callable = self.Callable
@@ -1954,6 +1969,16 @@ def test_var_substitution(self):
19541969
self.assertEqual(C5[int, str, float],
19551970
Callable[[typing.List[int], tuple[str, int], float], int])
19561971

1972+
def test_type_subst_error(self):
1973+
Callable = self.Callable
1974+
P = ParamSpec('P')
1975+
T = TypeVar('T')
1976+
1977+
pat = "Expected a list of types, an ellipsis, ParamSpec, or Concatenate."
1978+
1979+
with self.assertRaisesRegex(TypeError, pat):
1980+
Callable[P, T][0, int]
1981+
19571982
def test_type_erasure(self):
19581983
Callable = self.Callable
19591984
class C1(Callable):

0 commit comments

Comments
 (0)