-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Function + @overload cause "Single overload definition, multiple required" #5047
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'm a little bit confused about your type signature here: if 'default' is set to None, doesn't that mean the first overload alternative will always match? So, the only case where 'get_item' can return 'None' would be if 'default' is a non-None object? Basically, I think your type signature is equivalent to the following:
In any case, I think you usually want your overload signatures to be "specializations" of the implementation signature. We don't really want to force users to have the implementation signature be a valid overload alternative in that case. |
I suspect that the OP intended something like this: @overload
def get_item(key: str) -> Optional[Item]: ...
@overload
def get_item(key: str, default: None) -> Optional[Item]: ...
@overload
def get_item(key: str, default: Item) -> Item: ...
def get_item(key: str, default: Optional[item]) -> Optional[Item]:
# implementation goes here In any case we don't have plans to make it easier to shoot yourself in the foot here. |
If someone comes over this issue: The intended way of writing two different signatures, is to have them in two
That's why there must be at least two |
There's a good use case for single overloads in having a stricter signature than the actual implementation: from typing import Any, Dict, overload
@overload
def create_safe_thing(*, field_a: int, field_b: bool) -> Dict[str, Any]:
...
def create_safe_thing(**kwargs: Any) -> Dict[str, Any]:
return dict(kwargs)
print(create_safe_thing(field_a=3,field_b=True))
# >>> {'field_a': 3, 'field_b': True} Would be nice to be able to do this as right now, when you're just chucking kwargs into another function, you have to choose between messy error-prone x=y for each kwarg but having a strongly typed signature, or having a weakly typed signature and non-error-prone code. It's very easy while doing the former to accidentally do e.g. from typing import Any, Dict, overload
def create_safe_thing(*, field_a: int, field_b: bool) -> Dict[str, Any]:
return dict(field_a=field_a, field_b=field_a)
print(create_safe_thing(field_a=3,field_b=True))
# >>> {'field_a': 3, 'field_b': 3} There are of course ways to achieve the best of both worlds, but the ones I can think of are quite tedious. |
I did this: @overload
def my_func(*, arg1: str, arg2: int, ...):
...
# Hack to prevent mypy error:
# "error: Single overload definition, multiple required"
class _EmptyType:
__new__ = None # type: ignore
@overload
def my_func(a : _EmptyType):
...
def my_func(**kwargs):
# implementation here. I couldn't find any reference to a built in the typing or mypy docs. |
In 3.11 the @overload
def foo_wrapper(a: str, b: int, c: Optional[float]=..., d: int=..., etc: Bool=...) -> int: ... # a, b, and foo args
@overload
def foo_wrapper(a: Never, b: Never, **kw: Never) -> Never: ... # don't recommend
def foo_wrapper(a, b, **kw):
return self.foo(a, b, **kw) At the time of writing, pyright (via pylance, vscode) seems only to ignore (not display to the user) overloads of methods with |
For those looking for a workaround prior to Python 3.11's class Taint(dict):
@overload
def __init__(self, *, key: str, value: Optional[str] = None, effect: Union[Effect, str]): ...
@overload
def __init__(self: NoReturn) -> NoReturn: ... # workaround for mypy single overload definition error
def __init__(self, **kwargs):
# implementation |
|
For anyone else who came here because they wanted to do something like @audoh (like I did):
from typing import Any, TypedDict, Unpack
class SafeThingKwargs(TypedDict):
field_a: int
field_b: bool
def create_safe_thing(**kwargs: Unpack[SafeThingKwargs]) -> dict[str, Any]:
return dict(kwargs) |
Assume a function like:
Now let's assume we want to enhance typing through an
@overload
by changing it to:mypy will complain with:
This check makes sense for a
.pyi
file where you would expect multiple@overload
s on equal footing, but in this case the original declaration might as well serve as an "overload".A workaround is obviously to add:
which adds needless verbosity.
The text was updated successfully, but these errors were encountered: