Skip to content

is_dataclass(Any) return type incorrect, differs from is_dataclass(object) #12401

Closed

Description

@intgr

I found this surprising and arguably incorrect. According to mypy:

from typing import Any
from dataclasses import is_dataclass


def example1(arg: Any) -> None:
    if is_dataclass(arg):
        reveal_type(arg)  # ❌ Revealed type is "type[_typeshed.DataclassInstance]"


def example2(arg: object) -> None:
    if is_dataclass(arg):
        reveal_type(arg)  # ✅ Revealed type is "Union[_typeshed.DataclassInstance, type[_typeshed.DataclassInstance]]"

(Mypy playground)

This is because Any matches the 1st overload, even if 2nd overload with object argument is more appropriate for Any:

@overload
def is_dataclass(obj: type) -> TypeIs[type[DataclassInstance]]: ...
@overload
def is_dataclass(obj: object) -> TypeIs[DataclassInstance | type[DataclassInstance]]: ...

I couldn't think of an elegant fix for this.

Activity

  1. srittau commented on Jul 22, 2024

    @srittau
    Collaborator

    I don't think there is a fix, as Any is compatible with everything, so it will always match the first overload. Reordering is also not possible, at least not until we get a "Not" type (python/typing#801).

  2. intgr commented on Jul 22, 2024

    @intgr
    ContributorAuthor

    As a hack, we could add another overload case, with argument type that no real type ever satisfies but only Any can satisfy. Could we use the Never type?

  3. sobolevn commented on Jul 27, 2024

    @sobolevn
    Member
  4. srittau commented on Aug 7, 2024

    @srittau
    Collaborator

    @intgr We could try your suggestion in an experimental PR. (We should definitely add tests, though.) Otherwise I would close this issue as unfixable.

  5. intgr commented on Aug 12, 2024

    @intgr
    ContributorAuthor
  6. sobolevn commented on Aug 14, 2024

    @sobolevn
    Member

    MyPy PR is here: python/mypy#17678

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions