summaryrefslogtreecommitdiffstats
path: root/Lib/functools.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/functools.py')
-rw-r--r--Lib/functools.py17
1 files changed, 14 insertions, 3 deletions
diff --git a/Lib/functools.py b/Lib/functools.py
index 77ec852..305ceb4 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -740,6 +740,7 @@ def _compose_mro(cls, types):
# Remove entries which are already present in the __mro__ or unrelated.
def is_related(typ):
return (typ not in bases and hasattr(typ, '__mro__')
+ and not isinstance(typ, GenericAlias)
and issubclass(cls, typ))
types = [n for n in types if is_related(n)]
# Remove entries which are strict bases of other entries (they will end up
@@ -837,6 +838,9 @@ def singledispatch(func):
dispatch_cache[cls] = impl
return impl
+ def _is_valid_dispatch_type(cls):
+ return isinstance(cls, type) and not isinstance(cls, GenericAlias)
+
def register(cls, func=None):
"""generic_func.register(cls, func) -> func
@@ -844,9 +848,15 @@ def singledispatch(func):
"""
nonlocal cache_token
- if func is None:
- if isinstance(cls, type):
+ if _is_valid_dispatch_type(cls):
+ if func is None:
return lambda f: register(cls, f)
+ else:
+ if func is not None:
+ raise TypeError(
+ f"Invalid first argument to `register()`. "
+ f"{cls!r} is not a class."
+ )
ann = getattr(cls, '__annotations__', {})
if not ann:
raise TypeError(
@@ -859,11 +869,12 @@ def singledispatch(func):
# only import typing if annotation parsing is necessary
from typing import get_type_hints
argname, cls = next(iter(get_type_hints(func).items()))
- if not isinstance(cls, type):
+ if not _is_valid_dispatch_type(cls):
raise TypeError(
f"Invalid annotation for {argname!r}. "
f"{cls!r} is not a class."
)
+
registry[cls] = func
if cache_token is None and hasattr(cls, '__abstractmethods__'):
cache_token = get_cache_token()