Closed
Description
(Expanding from python/typeshed#7520 (comment))
Consider this code:
from typing import Callable
class X:
f: Callable[[], int]
g: Callable[["X"], int]
reveal_type(X().f())
reveal_type(X().g())
Here is how current type checkers handle it:
- pyright complains about the second call (
Expected 1 more positional argument
) - pytype complains about the second call (
Function <callable> expects 1 arg(s), got 0 [wrong-arg-count]
) - pyanalyze complains about the second call (
Missing required positional argument: '__arg0' (code: incompatible_call)
) - pyre accepts both calls (I think there's a bug where it doesn't complain about missing arguments?)
- mypy complains about the first one (
main.py:8: error: Attribute function "f" with type "Callable[[], int]" does not accept self argument
).
I feel like mypy is wrong here, because the behavior where self
gets implicitly bound on instances is specific to functions, not all callables. But the type system sometimes conflates functions with callables, so I can see where mypy is coming from.
In either case, the discrepancy is unfortunate because it means we can't write typeshed stubs that satisfy both type checkers. We should come to an agreement on the right behavior and document it.
@Akuli pointed out a workaround for mypy's behavior: using a callable protocol (python/typeshed#7520 (comment))