Fix an issubclass failure for protocols with overloaded methods#9904
Fix an issubclass failure for protocols with overloaded methods#9904JelleZijlstra merged 2 commits intopython:masterfrom
issubclass failure for protocols with overloaded methods#9904Conversation
JukkaL
left a comment
There was a problem hiding this comment.
Thanks for the fix!
Left an (optional) request to update the test case, otherwise looks good.
test-data/unit/check-protocols.test
Outdated
| def meth(self, a): | ||
| pass | ||
|
|
||
| reveal_type(issubclass(int, POverload)) # N: Revealed type is 'builtins.bool' |
There was a problem hiding this comment.
Could you also add a concrete class (e.g., COverload) that has a suitable overloaded method, and test that issubclass can be used to narrow down from Type[Union[COverload, E]], similar to above around line 2218?
There was a problem hiding this comment.
So while trying the add the test you proposed I seem to have stumbled across another bug.
The if block successfully narrows down the Union to Type[COverload] but the else block
on the other hand fails to do the same with E, revealing the type as the original Union.
Would you happen to know where in mypy the type inference of if / else statements is handled?
I imagine that change similar to non_method_protocol_members() will have to be made there,
but I'm not quite sure where to look.
Examples
class COverload:
x: str
@overload
def meth(self, a: int) -> float: ...
@overload
def meth(self, a: str) -> Sequence[float]: ...
def meth(self, a):
pass
cls_overload: Type[Union[COverload, E]]
if issubclass(cls_overload, POverload):
reveal_type(cls_overload) # N: Revealed type is 'Type[__main__.COverload]'
else:
reveal_type(cls_overload) # N: Revealed type is 'Type[__main__.E]'The test output:
Expected:
...
main:45: note: Revealed type is 'Type[__main__.COverload]'
main:47: note: Revealed type is 'Type[__main__.E]' (diff)
Actual:
...
main:45: note: Revealed type is 'Type[__main__.COverload]'
main:47: note: Revealed type is 'Union[Type[__main__.COverload], Type[__main__.E]]' (diff)
There was a problem hiding this comment.
Could you please open a new issue about it?
There was a problem hiding this comment.
Could you please open a new issue about it?
I just created an issue at #12228.
issubclass failure for protocols with overloaded methodsissubclass failure for protocols with overloaded methods
|
Passes all the tests now. Shall we merge this one? @hauntsaninja |
|
Jukka already approved it, so let's land it. |
Description
Mypy currently rejects
issubclasschecks for protocols containing non-method members.What I noticed is that this includes overloaded functions as well, the latter being incorrectly
identified as a "non-method" due to a missing
isinstance(typ, mypy.types.Overloaded)check.This PR attempts to remedy aforementioned issue.
Examples
The
issubclassbehavior prior to this PR:Test Plan
A new
issubclasstest has been added for overload-containing protocols.