summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/_collections_abc.py12
-rw-r--r--Lib/test/test_genericalias.py6
2 files changed, 17 insertions, 1 deletions
diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py
index 7c3faa6..e4eac79 100644
--- a/Lib/_collections_abc.py
+++ b/Lib/_collections_abc.py
@@ -434,7 +434,7 @@ class _CallableGenericAlias(GenericAlias):
raise TypeError(
"Callable must be used as Callable[[arg, ...], result].")
t_args, t_result = args
- if isinstance(t_args, list):
+ if isinstance(t_args, (list, tuple)):
ga_args = tuple(t_args) + (t_result,)
# This relaxes what t_args can be on purpose to allow things like
# PEP 612 ParamSpec. Responsibility for whether a user is using
@@ -456,6 +456,16 @@ class _CallableGenericAlias(GenericAlias):
args = list(args[:-1]), args[-1]
return _CallableGenericAlias, (Callable, args)
+ def __getitem__(self, item):
+ # Called during TypeVar substitution, returns the custom subclass
+ # rather than the default types.GenericAlias object.
+ ga = super().__getitem__(item)
+ args = ga.__args__
+ t_result = args[-1]
+ t_args = args[:-1]
+ args = (t_args, t_result)
+ return _CallableGenericAlias(Callable, args)
+
def _type_repr(obj):
"""Return the repr() of an object, special-casing types (internal helper).
diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py
index 5de13fe..ccf40b1 100644
--- a/Lib/test/test_genericalias.py
+++ b/Lib/test/test_genericalias.py
@@ -347,6 +347,12 @@ class BaseTest(unittest.TestCase):
self.assertEqual(C2[int, float, str], Callable[[int, float], str])
self.assertEqual(C3[int], Callable[..., int])
+ # multi chaining
+ C4 = C2[int, V, str]
+ self.assertEqual(repr(C4).split(".")[-1], "Callable[[int, ~V], str]")
+ self.assertEqual(repr(C4[dict]).split(".")[-1], "Callable[[int, dict], str]")
+ self.assertEqual(C4[dict], Callable[[int, dict], str])
+
with self.subTest("Testing type erasure"):
class C1(Callable):
def __call__(self):