Skip to content

isinstance can coerce a known type to become None #4952

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

Open
ikelos opened this issue Apr 23, 2018 · 2 comments
Open

isinstance can coerce a known type to become None #4952

ikelos opened this issue Apr 23, 2018 · 2 comments
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal

Comments

@ikelos
Copy link

ikelos commented Apr 23, 2018

Given the following code (mypy 0.590 and python 3.6.5):

from typing import *

class A(object):
    def method(self) -> str:
        return ''

R = TypeVar('R')

class B(object):
    def func(self, instance: A, instance_type: Type[R]) -> None:
        reveal_type(instance)
        if isinstance(instance, instance_type):
            reveal_type(instance)
            instance.method()

I get the following response:

test.py:11: error: Revealed type is 'test.A'
test.py:13: error: Revealed type is 'builtins.None'
test.py:14: error: "None" has no attribute "method"

I would have expected the type of instance to have at the very least been a subclass of A, given that it was before it went into the call. So something like:

test.py:11: error: Revealed type is 'test.A'
test.py:13: error: Revealed type is 'R'

Or perhaps more complex to indicate it subclasses from both A and R, (but I don't know the syntax for that). It makes no difference whether R is bound to A or not.

@ilevkivskyi
Copy link
Member

I think this is essentially a duplicate of #3603, but we can keep this for another use case.

A side note: having a type variable only on one side in generic function doesn't make sense (in vast majority of cases including yours).

@ilevkivskyi ilevkivskyi added bug mypy got something wrong priority-1-normal labels Apr 23, 2018
@ikelos
Copy link
Author

ikelos commented Apr 23, 2018

The return type was removed in the simplification (since it wasn't required to produce the issue). The original return type was List[Tuple[str, str, R]], but that gave rise to #4949 so I figured I'd leave it out in this example.

Also, in this instance, it isn't strictly multiple inheritance, since this happens even when R is bound to A. Having said that, according to the bug you mentioned Type[R] might be classed as a really weird situation and so it may well be the same bug. This seems to be specific to TypeVar because the following code returns as expected, which should be equivalent to the TypeVar('R', bound = A) situation:

from typing import *

class A(object):
    def method(self) -> str:
        return ''

class AA(A):
    pass

class B(object):
    def func(self, instance: AA, instance_type: Type[A]) -> None:
        reveal_type(instance)
        if isinstance(instance, instance_type):
            reveal_type(instance)
            instance.method()

@ilevkivskyi ilevkivskyi added the false-positive mypy gave an error on correct code label May 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal
Projects
None yet
Development

No branches or pull requests

2 participants