microsoft / pyright

Static Type Checker for Python
Other
13.04k stars 1.39k forks source link

Regression: `is_dataclass(x)` returns `TypeIs[type[DataclassInstance]]` -- should be `TypeIs[DataclassInstance | type[DataclassInstance]]` #8391

Closed rsokl closed 1 month ago

rsokl commented 1 month ago

Checking if object is an instance of a dataclass type leads to unreachable code

from dataclasses import is_dataclass
from typing import Any

def f(x: Any):
    if is_dataclass(x) and not isinstance(x, type):
        # this code is unreachable

I think this regression started in 1.1.366

erictraut commented 1 month ago

Pyright's behavior is correct here, so I don't consider this a bug. For comparison, mypy's behavior is the same.

The is_dataclass(x) call uses TypeIs, and it narrows the type to type[DataclassInstance]. Thenot isinstance(x, type)call narrows this type toNever`.

If you change the annotation for x from Any to object, it will work as you intend.