in typing.py
NoType = object()
def cast_overload(func, overload_func, type=NoType):
"""If tpye is NoType, type = Type[overload_func]"""
f = getattr(func, "__func__", func)
of = getattr(overload_func, "__func__", overload_func)
try:
_overload_registry[f.__module__][f.__qualname__][
of.__code__.co_firstlineno
] = overload_func
except AttributeError:
# Not a normal function; ignore.
pass
return overload_func
Usage
from typing import Callable, Concatenate, LiteralString, cast_overload
factory_dict = dict[str, Callable]()
def factory(key, *args, **kwargs):
return factory_dict[key](*args, **kwargs)
def register[K: LiteralString](key: K):
def decorator[**P, T](func: Callable[P, T]):
factory_dict[key] = func
return cast_overload(factory, func, Callable[Concatenate[K, P], T])
return decorator
@register("function1")
def func1(x, y, z):
pass
@register("function2")
def func2(a, b, c):
pass
This can support type hint for Interface & implementation