generic_func.register(cls, func) -> func Registers a new implementation for the given *cls* on a *generic_func*.
(cls, func=None)
| 920 | all(isinstance(arg, type) for arg in cls.__args__)) |
| 921 | |
| 922 | def register(cls, func=None): |
| 923 | """generic_func.register(cls, func) -> func |
| 924 | |
| 925 | Registers a new implementation for the given *cls* on a *generic_func*. |
| 926 | |
| 927 | """ |
| 928 | nonlocal cache_token |
| 929 | if _is_valid_dispatch_type(cls): |
| 930 | if func is None: |
| 931 | return lambda f: register(cls, f) |
| 932 | else: |
| 933 | if func is not None: |
| 934 | raise TypeError( |
| 935 | f"Invalid first argument to `register()`. " |
| 936 | f"{cls!r} is not a class or union type." |
| 937 | ) |
| 938 | ann = getattr(cls, '__annotate__', None) |
| 939 | if ann is None: |
| 940 | raise TypeError( |
| 941 | f"Invalid first argument to `register()`: {cls!r}. " |
| 942 | f"Use either `@register(some_class)` or plain `@register` " |
| 943 | f"on an annotated function." |
| 944 | ) |
| 945 | func = cls |
| 946 | |
| 947 | # only import typing if annotation parsing is necessary |
| 948 | from typing import get_type_hints |
| 949 | from annotationlib import Format, ForwardRef |
| 950 | argname, cls = next(iter(get_type_hints(func, format=Format.FORWARDREF).items())) |
| 951 | if not _is_valid_dispatch_type(cls): |
| 952 | if isinstance(cls, UnionType): |
| 953 | raise TypeError( |
| 954 | f"Invalid annotation for {argname!r}. " |
| 955 | f"{cls!r} not all arguments are classes." |
| 956 | ) |
| 957 | elif isinstance(cls, ForwardRef): |
| 958 | raise TypeError( |
| 959 | f"Invalid annotation for {argname!r}. " |
| 960 | f"{cls!r} is an unresolved forward reference." |
| 961 | ) |
| 962 | else: |
| 963 | raise TypeError( |
| 964 | f"Invalid annotation for {argname!r}. " |
| 965 | f"{cls!r} is not a class." |
| 966 | ) |
| 967 | |
| 968 | if isinstance(cls, UnionType): |
| 969 | for arg in cls.__args__: |
| 970 | registry[arg] = func |
| 971 | else: |
| 972 | registry[cls] = func |
| 973 | if cache_token is None and hasattr(cls, '__abstractmethods__'): |
| 974 | cache_token = get_cache_token() |
| 975 | dispatch_cache.clear() |
| 976 | return func |
| 977 | |
| 978 | def wrapper(*args, **kw): |
| 979 | if not args: |
nothing calls this directly
no test coverage detected