Skip to content

Inconsistent behaviour with / without a dummy type variable #20442

@cmp0xff

Description

@cmp0xff

Bug Report

mypy behaves differently with and without an unfunctional type variable.

To Reproduce

from typing_extensions import TypeVar, Self, reveal_type
from typing import Any, Generic, overload
from collections.abc import Callable, Hashable, Iterable

IndexT0 = TypeVar("IndexT0")
T = TypeVar("T")


class Series:
    pass


class _LocIndexerFrame(Generic[T]):
    @overload
    def __getitem__(
        self, idx: "tuple[Callable[[DataFrame], int], str]"
    ) -> int: ...
    @overload
    def __getitem__(
        self, idx: "tuple[Callable[[DataFrame], list[Hashable]], str]"
    ) -> Series: ...
    @overload
    def __getitem__(
        self, idx: "tuple[Callable[[DataFrame], Any], Iterable[Hashable]]"
    ) -> T: ...
    def __getitem__(self, idx: object) -> object:
        return  # type: ignore[return-value]


class DataFrame(Generic[IndexT0]):
    @property
    def loc(self) -> _LocIndexerFrame[Self]:
        return _LocIndexerFrame()


def select2(df: DataFrame) -> list[Hashable]:
    return []


reveal_type(DataFrame().loc[select2, "x"])  # pyright gives Series, mypy gives Any


def select3(_: DataFrame) -> int:
    return 1


reveal_type(DataFrame().loc[select3, "x"])  # pyright gives int, mypy gives Any

Expected Behavior

Same results from the two playground links, since the type variable is not functional

Actual Behavior

Different results.

Your Environment

  • Mypy version used: 1.19.1
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.12, 3.14

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions