Proper singledispatch type definitions

Correctly detects calls to `register()` with a function of incompatible return
type.  Correctly recognizes the `register()`, `dispatch()`, and
`_clear_cache()` methods on a generic function, as well as the `registry`
mapping.

Possible future improvements: it would be amazing if `register()` checked if
the first argument of the registered callable is indeed of valid type. This
would require Callable[] to support varargs.  It would also be great if we
could read the arguments of the remaining arguments during `@singledispatch()`
and cross-check them during `register()` with the currently registered
implementation. Again, this would require Callable[] to become much more
advanced.
This commit is contained in:
Lukasz Langa
2016-12-19 12:54:08 -08:00
parent beb9183103
commit 2058ae30ab
2 changed files with 32 additions and 6 deletions

View File

@@ -3,7 +3,8 @@
# NOTE: These are incomplete!
from abc import ABCMeta, abstractmethod
from typing import Any, Callable, Generic, Dict, Iterable, Optional, Sequence, Tuple, TypeVar, NamedTuple, overload
import sys
from typing import Any, Callable, Generic, Dict, Iterable, Mapping, Optional, Sequence, Tuple, TypeVar, NamedTuple, overload
from collections import namedtuple
_AnyCallable = Callable[..., Any]
@@ -43,8 +44,21 @@ def total_ordering(cls: type) -> type: ...
def cmp_to_key(mycmp: Callable[[_T, _T], int]) -> Callable[[_T], Any]: ...
class partial(Generic[_T]):
func = ... # Callable[..., _T]
func = ... # type: Callable[..., _T]
args = ... # type: Tuple[Any, ...]
keywords = ... # type: Dict[str, Any]
def __init__(self, func: Callable[..., _T], *args: Any, **kwargs: Any) -> None: ...
def __call__(self, *args: Any, **kwargs: Any) -> _T: ...
if sys.version_info >= (3, 4):
class _SingleDispatchCallable(Generic[_T]):
registry = ... # type: Mapping[Any, Callable[..., _T]]
def dispatch(self, cls: Any) -> Callable[..., _T]: ...
@overload
def register(self, cls: Any) -> Callable[[Callable[..., _T]], Callable[..., _T]]: ...
@overload
def register(self, cls: Any, func: Callable[..., _T]) -> Callable[..., _T]: ...
def _clear_cache(self) -> None: ...
def __call__(self, *args: Any, **kwargs: Any) -> _T: ...
def singledispatch(func: Callable[..., _T]) -> _SingleDispatchCallable[_T]: ...