Skip to content
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

Inheritance + if/elif/else chain of isinstance() doesn't constrain type as expected #4864

Open
osandov opened this issue Apr 6, 2018 · 2 comments
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-2-low topic-type-narrowing Conditional type narrowing / binder topic-union-types

Comments

@osandov
Copy link

osandov commented Apr 6, 2018

I have something like the following code:

from typing import Any, Union


class A:
    pass


class B(A):
    def __init__(self):
        self.member = 1


class C(A):
    def __init__(self):
        self.member = 2


def f(obj: A) -> int:
    if isinstance(obj, B):
        pass
    elif isinstance(obj, C):
        pass
    else:
        raise ValueError()
    return obj.member

mypy claims:

test.py:25: error: "A" has no attribute "member"

However, at line 25, it's clear that obj must be either a B or a C. If I remove the elif isinstance(obj, C) branch, then there is no error.

This similar code has a related error:

from typing import Any, Union


class A:
    pass


class B(A):
    def __init__(self):
        self.member = 1


class C(A):
    def __init__(self):
        self.member = 2


def f(obj: A) -> Union[B, C]:
    if isinstance(obj, B):
        pass
    elif isinstance(obj, C):
        pass
    else:
        raise ValueError()
    return obj
test.py:25: error: Incompatible return value type (got "A", expected "Union[B, C]")

Interestingly, if I remove the inheritance so that B and C are no longer subclasses of A, there is no error.

This happens on mypy 0.570 and current git (0.590-dev-3346cfad75374c096b1dd8024df24ce50f18a35c).

@ilevkivskyi
Copy link
Member

It looks like another case of join vs union problem plus a complex binder situation. Why can't you just use obj: Union[B, C] in the signature of your function?

I would say this is a relatively low priority. There may be some binder refactoring later, then this will probably be easier to fix.

@osandov
Copy link
Author

osandov commented Apr 7, 2018 via email

@ilevkivskyi ilevkivskyi added the false-positive mypy gave an error on correct code label May 19, 2018
@hauntsaninja hauntsaninja added the topic-type-narrowing Conditional type narrowing / binder label Dec 28, 2024
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-2-low topic-type-narrowing Conditional type narrowing / binder topic-union-types
Projects
None yet
Development

No branches or pull requests

3 participants