Skip to content

Compatibility of return type with subclass upon overload #19952

Description

@cmp0xff

Hi, we have the following minimal code snippet that reproduces our concern from pandas-dev/pandas-stubs#1385. In words, when the return types from different overloads are parametrised by a type variable, type checkers can work. When return types are subclasses, however, mypy does not seem to work.

from typing import Any, Generic, Never, TypeVar, overload, reveal_type

T = TypeVar("T")

class Arg(Generic[T]): ...

class Gen(Generic[T]): ...

# part 1: return type is Generic

class D0:
    @overload
    def m(self, p: Arg[Never]) -> Gen: ...

    @overload
    def m(self, p: Arg[int]) -> Gen[int]: ...

reveal_type(D0().m(Arg[Any]()))  # pyright gives Gen[Unknown], mypy gives Gen[Any], good
reveal_type(D0().m(Arg[int]()))  # Gen[int], good
reveal_type(D0().m(Arg[float]()))  # error, good

# part 2: return types are subclasses

class Base: ...

class Sub(Base): ...

class D1:
    @overload
    def m(self, p: Arg[Never]) -> Base: ...  # we want to get Base for Arg[Any]; mypy warns overload-overlap here, whereas pyright does not warn (at least without strict)

    @overload
    def m(self, p: Arg[int]) -> Sub: ...

reveal_type(D1().m(Arg[Any]()))  # pyright gives Base, but mypy gives Any
reveal_type(D1().m(Arg[int]()))  # Sub, good
reveal_type(D1().m(Arg[float]()))  # error, good

Part 1 is understood from #19525. Could someone explain part 2? Thank you 🙂

Activity

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions