Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asking isinstance on a Union[...] type

Tags:

python

types

mypy

I'm trying to ask an isinstance question on a user defined type: ConstData = Union[int, str]:

from typing import Union, Optional
ConstData = Union[int, str]
def foo(x) -> Optional[ConstData]:
    if isinstance(x, ConstData):  # <--- this doesn't work
    # if isinstance(x, (int, str)): <--- this DOES work ...
        return x
    return None

Sadly enough, it doesn't work:

$ mypy main.py
main.py:4: error: Parameterized generics cannot be used with class or instance checks
main.py:4: error: Argument 2 to "isinstance" has incompatible type "object"; expected "Union[type, Tuple[Union[type, Tuple[Any, ...]], ...]]"
Found 2 errors in 1 file (checked 1 source file)

Is there any elegant way to solve this?

like image 402
OrenIshShalom Avatar asked Jul 08 '26 06:07

OrenIshShalom


1 Answers

About:

"Still, with if isinstance(x, get_args(ConstData)): return x mypy can't infer that x has the correct return type. It complains it's Any"

I think it is a bug in reveal_type(), Mypy undertands the narrowing of x type. As you can see in the following code, it does not raise an error when test() is called with x:

def test(k:Union[int, str]) -> None:
    pass


def foo(x: Any) -> Optional[ConstData]:
    if isinstance(x, get_args(ConstData)):
        reveal_type(x)  # Mypy: Revealed type is "Any"
        test(x)  # Mypy: no error
        return x  # Mypy: no error
    return None
like image 93
hussic Avatar answered Jul 10 '26 18:07

hussic