You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
MethodType incorrectly rejected as subtype of Callable #8869
In Python 3 (not sure about 2), an instance of MethodType always represents a bound method; a non-bound method is considered an instance of FunctionType instead:
The instance that a method is bound to is stored in the __self__ attribute of the bound method object:
>>> o = C()
>>> o
<__main__.C object at 0x7f926f2a3d30>
>>> o.m
<bound method C.m of <__main__.C object at 0x7f926f2a3d30>>
>>> o.m.__self__
<__main__.C object at 0x7f926f2a3d30>
>>> o.m()
>>>
As you can see, it's correct to call a bound method that only takes self as an argument with 0 additional arguments.
That makes sense. In the interest of narrowing things down, are you able to clear the error if you tweak the callable type? Either specifically to take a C or Any or some other option?
Changing the argument types of the Callable does not seem to have any effect, but changing the return type to Any makes the warning go away, which doesn't make sense to me.
Mypy has no special understanding of MethodType. It's defined as a regular class in typeshed, and mypy assumes that's the whole story.
A potential fix would be to special case MethodType when deciding whether the isinstance check can be true. The relevant code seems to be in is_overlapping_types (mypy.meet)?
MethodType.__call__ returns Any, so perhaps that is why changing the return type makes the message go away? A subclass is allowed to narrow the return type of a method though, so I still don't understand why mypy thinks isinstance(func, MethodType) is always false.
Activity
beezee commentedon May 22, 2020
Methods always have at least one arg (self) - would that justify mypy concluding that a nullary callable would never unify with MethodType?
mthuurne commentedon May 22, 2020
In Python 3 (not sure about 2), an instance of
MethodTypealways represents a bound method; a non-bound method is considered an instance ofFunctionTypeinstead:The instance that a method is bound to is stored in the
__self__attribute of the bound method object:As you can see, it's correct to call a bound method that only takes
selfas an argument with 0 additional arguments.beezee commentedon May 22, 2020
That makes sense. In the interest of narrowing things down, are you able to clear the error if you tweak the callable type? Either specifically to take a C or Any or some other option?
mthuurne commentedon May 22, 2020
Changing the argument types of the
Callabledoes not seem to have any effect, but changing the return type toAnymakes the warning go away, which doesn't make sense to me.JukkaL commentedon May 22, 2020
Mypy has no special understanding of
MethodType. It's defined as a regular class in typeshed, and mypy assumes that's the whole story.A potential fix would be to special case
MethodTypewhen deciding whether theisinstancecheck can be true. The relevant code seems to be inis_overlapping_types(mypy.meet)?mthuurne commentedon May 22, 2020
MethodTypein typeshed:MethodType.__call__returnsAny, so perhaps that is why changing the return type makes the message go away? A subclass is allowed to narrow the return type of a method though, so I still don't understand why mypy thinksisinstance(func, MethodType)is always false.mthuurne commentedon May 22, 2020
Here is a test case that doesn't use
MethodTypebut does exhibit the same behavior that I don't understand:mypy reports:
Which is the
return 'ProtoAny'line, soisinstance(func, ProtoAny)is considered always false, butisinstance(func, ProtoNone)is not.mthuurne commentedon May 22, 2020
A test case without
Anydoes work in the way I expect it:mypy reports:
Line 27 is the body of
class D, which is indeed incorrect, because it widens the return type of__call__compared to its superclass.ods commentedon Mar 16, 2021
One more case:
The output:
error: Argument 1 to "f" has incompatible type "Callable[[], Any]"; expected "MethodType"JelleZijlstra commentedon Apr 26, 2024
This is now also reproducible with
TypeIs; found it as a result of python/typeshed#11823. Here is an example that doesn't rely on any non-basic types:--warn-unreachablewill say the tworeveal_types are unreachable. https://mypy-play.net/?mypy=latest&python=3.10&flags=warn-unreachable&gist=61455819df1bb90f40587091a810851dConsider overlap between instances and callables (python#17389)