Skip to content

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

Open
@osandov

Description

@osandov

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).

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions