python / python/mypy

Connection to TypeVar bound to Union is lost after returning Self from method

Open
#16,826 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug topic-type-variables
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Bug Report

A variable of which the type is determined by a TypeVar can normally return an object of type Self from a method and have the returned object recognized as an instance of the TypeVar type. This no longer works of the TypeVar is bound to a Union, even if the method always returns a Self object for every type in the Union.

To Reproduce

from typing import Self, TypeVar


class A:
    def new_version(self) -> Self:
        return self


class B:
    def new_version(self) -> Self:
        return self


T = TypeVar("T", bound=A)
S = TypeVar("S", bound=A | B)


def f(x: T) -> T:
    return x.new_version()


def g(x: S) -> S:
    return x.new_version()

Mypy playground gist: https://mypy-play.net/?mypy=latest&python=3.12&gist=5e9aa0a21d090f7f21e4e3b643cd9941

Expected Behavior

mypy should approve both function f and g.

Actual Behavior

mypy considers function g to be erroneous:

main.py:23: error: Incompatible return value type (got "A | B", expected "S")  [return-value]

Your Environment

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the provided Python reproducer in the linked mypy playground and compare why f is accepted while g reports an incompatible return type. Done means mypy accepts both functions, with the behavior covered by an appropriate regression check.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.