-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Expression has type "function", variable has type "Callable[[], None]" #10740
Comments
This seems to be expected behavior, if the boolean something is false you reassign action to method2 which has an argument however in your code this creates a conflict because when you first typed action you said that it will never have any arguments but now it does, creating incompatible types in the assignment. To make mypy happy I presume that you will have to use a union. (Disclaimer: I am new to mypy so this may very well be incorrect) from typing import Callable
from typing import Union
class Test:
def method1(self) -> None:
pass
def method2(self, optional: int = 0) -> None:
pass
def test(self, something: bool) -> None:
action: Union[Callable[[], None], Callable[[int], None]]
action = self.method1 if something else self.method2 |
This looks like a mypy bug to me. It type checks fine with pyright. To work around the bug, you can do the following: def test(self, something: bool) -> None:
action1: Callable[[], None] = self.method1
action2: Callable[[], None] = self.method2
action: Callable[[], None] = action1 if something else action2 |
Yeah, I think there are two improvements here. One, mypy uses joins for ternary expressions (#9264 and #5392 are related) where maybe a union / meet would be better. Two, the join logic doesn't take into account optional parameters, so you get |
``` discord/backoff.py:73: error: Incompatible types in assignment (expression has type "function", variable has type "Callable[..., float]") ``` - Refer to <python/mypy#10740 (comment)>
Any update here? |
The inverse of this situation (#17017) is when the callables are actually incompatible and are joined into from typing import Callable
class C:
def __init__(self, i: int=1): ...
c1: Callable[[], object] = C
c2: Callable[[int], object] = C
reveal_type(c1 if bool() else c2) # Revealed type is "builtins.function" |
this helps avoid python/mypy#10740
this helps avoid python/mypy#10740
this helps avoid python/mypy#10740
this helps avoid python/mypy#10740
After switching to inferring unions for ternary, this now works on master. |
@ilevkivskyi why was this issue closed? none of the problems listed were resolved, simply masked by a behaviour change. from typing import *
T = TypeVar("T")
def join(t1: T, t2: T) -> T:
return t1
def f1() -> None: ...
def f2(optional: int = 0) -> None: ...
action: Callable[[], None]
action = join(f1, f2) # Incompatible types in assignment (expression has type "function", variable has type "Callable[[], None]") [assignment]
class C:
def __init__(self, i: int=1): ...
c1: Callable[[], object] = C
c2: Callable[[int], object] = C
reveal_type(join(c1, c2)) # Revealed type is "builtins.function" |
To Reproduce
Expected Behavior
I believe the code above should validate in mypy.
Actual Behavior
Your Environment
mypy.ini
(and other config files): noneThe text was updated successfully, but these errors were encountered: