diff options
Diffstat (limited to 'Lib/functools.py')
-rw-r--r-- | Lib/functools.py | 17 |
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() |