importtypingastfromdataclassesimportdataclass, field@dataclassclassExample:
a: t.Callable[[], int] =field(default=lambda: 42)
defcall_a(self) ->None:
self.a() # Attribute function "a" with type "Callable[[], int]" does not accept self argument
Curiously, adding Example as the first argument to the type of a makes the call be recognized OK but the default not.
fromtypingimporttfromdataclassesimportdataclass, field@dataclassclassExample:
a: t.Callable[['Example'], int] =field(default=lambda: 42) # Incompatible types in assignment (expression has type "Callable[[], int]", variable has type "Callable[[Example], int]")defcall_a(self):
self.a()
Your Environment
Mypy version used: mypy 0.782
Mypy command-line flags:
Mypy configuration options from mypy.ini (and other config files):
I feel like there should be a way for mypy to distinguish these cases, unless there are conflicting use cases (which I am not aware of yet). But I haven't taken a look into the related mypy code.
Edit Ctrl+Enter too early again 😄 Completed the comment
This runs without problems and should pass Mypy, but instead produces the following errors:
error: Invalid self argument "Example" to attribute function "func" with type "Callable[[str], str]"
error: Too many arguments
As in the original issue, one workaround is to declare the field as Optional and assert that it is not None before usage.
My understanding is that because func is declared on the class, Mypy thinks that it is a class attribute (and not an instance attribute). If this were true, example.func would indeed give a bound method. But because func exists on the instance, we get the_func back unmodified.
Activity
gvanrossum commented on Sep 26, 2020
Hm, this is unfortunate. I think it's due to mypy not really understanding the difference between class and instance attributes.
I expect it'll be hard to fix. In the meantime, here's a weird workaround: if you make the type Optional and check for None before the call, it works:
NiklasRosenstein commented on Sep 26, 2020
I just found another workaround using a Protocol:
I feel like there should be a way for mypy to distinguish these cases, unless there are conflicting use cases (which I am not aware of yet). But I haven't taken a look into the related mypy code.
Edit Ctrl+Enter too early again 😄 Completed the comment
broken-pen commented on Jun 2, 2021
I'm hitting the same issue, but with a different error. In case anyone else is affect, here is the MWE:
This runs without problems and should pass Mypy, but instead produces the following errors:
As in the original issue, one workaround is to declare the field as Optional and assert that it is not None before usage.
My understanding is that because func is declared on the class, Mypy thinks that it is a class attribute (and not an instance attribute). If this were true, example.func would indeed give a bound method. But because func exists on the instance, we get the_func back unmodified.
hauntsaninja commented on Sep 20, 2021
Fixed by #10548