Skip to content

Isinstance checks against Type[SomeProtocol] unexpectedly fails #7932

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

Closed
Michael0x2a opened this issue Nov 12, 2019 · 1 comment
Closed

Isinstance checks against Type[SomeProtocol] unexpectedly fails #7932

Michael0x2a opened this issue Nov 12, 2019 · 1 comment

Comments

@Michael0x2a
Copy link
Collaborator

Apologies in advance if this is a duplicate issue.

When I try type-checking this program, the final line is inferred to be unreachable. This was a bit surprising to me: I expected to get a "Revealed type is 'SupportsLookup'" note instead.

from typing import Type
from typing_extensions import Protocol

class SupportsLookup(Protocol):
    def lookup(self, key: str) -> int: ...

class Parent: pass

class Child(Parent):
    def lookup(self, key: str) -> int: ...

def cast_and_use(template: Type[SupportsLookup], x: Parent) -> None:
    if isinstance(x, template):
        reveal_type(x)

Somewhat curiously, if I make x be of type object instead of Parent, everything works as expected.

This seems a bit inconsistent to me. Assuming I'm not overlooking some type safety issue in my example, I think it'd be better to always narrow x to SupportsLookup regardless of how it's originally typed as long as the protocol doesn't directly conflict with any signatures defined in Parent.

Note: this issue is a simplification of the root cause of the mypyc error I had in #7917 -- my original version of make_indexing_replay_lookup_func had this issue.

@ilevkivskyi
Copy link
Member

First of all mypyc doesn't support protocols yet, see mypyc/mypyc#586

About mypy issue itself, this is essentially a duplicate of #3830 (also tangentially related to #3827 and #3603).

This is actually not so obvious, we can't say that meet(SupportsLookup, Parent) is SupportsLookup because the latter is not a subtype of Parent, and we can't use Parent either. The best solution is probably to implement internal intersection-like generated TypeInfos that were proposed several times elsewhere, but they may be not easy to implement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants