pythonpython-typingmypyunion-types

Mypy error - incompatible return value type


Just started to use mypy, encountered a Incompatible return value type problem on a case that I considered correct, minimal example as follows:

from typing import Union

class A:
    def __init__(self, element: str):
        self._element = element

class B(A): ...
class C(B): ...
class D(A): ...

def run(value: bool) -> Union[C, D]:
    test = (
        C("foo")
        if value is True
        else D("bar")
    )

    return test  # error: Incompatible return value type (got "A", expected "Union[C, D]")  [return-value]

def run_2(value: bool) -> Union[C, D]:
    return (
        C("foo")
        if value is True
        else D("bar")
    )  # success: no issues found

I expected this simple example to work. I used mypy=1.0.0.

Is it expected? Did I do something wrong? Thanks!


Solution

  • mypy can get confused when types get complicated, in these cases we have to write type hints for it manually, even if it is a bit annoying:

    from typing import Union
    
    class A:
        def __init__(self, element: str):
            self._element = element
    
    class B(A): pass
    class C(B): pass
    class D(A): pass
    
    def run(value: bool) -> Union[C, D]:
        test: Union[C, D] = (
            C("foo")
            if value is True
            else D("bar")
        )
    
        return test  # ok
    
    def run_2(value: bool) -> Union[C, D]:
        return (
            C("foo")
            if value is True
            else D("bar")
        )  # success: no issues found
    

    This is checked without issues by mypy