Skip to content

Incorrect type inference with __radd__ with subclass of tuple[int, ...] #19006

Description

@randolf-scholz

Bug Report

mypy generally correctly prioritizes __radd__ if the right operand is a subtype of the left operand. However, I discovered that it can fail to do so when creating a subclass of tuple[int, ...].

To Reproduce

from typing import assert_type

class Size(tuple[int, ...]):
    def __add__(self, other: tuple[int, ...], /) -> "Size": return Size()  # type: ignore[override]
    def __radd__(self, other: tuple[int, ...], /) -> "Size": return Size()

tup0: tuple[()] = ()
tup1: tuple[int] = (1,)
tup2: tuple[int, int] = (1, 2)
tupN: tuple[int, ...] = (1, 2, 3)
size: Size = Size([3, 4])

# __radd__
assert_type(tup0 + tupN, tuple[int, ...])  # ✅
assert_type(tup1 + tupN, tuple[int, ...])  # ✅
assert_type(tup2 + tupN, tuple[int, ...])  # ✅
assert_type(tupN + tupN, tuple[int, ...])  # ✅
assert_type(tup0 + size, Size)  # ❌ False positive
assert_type(tup1 + size, Size)  # ❌ False positive
assert_type(tup2 + size, Size)  # ❌ False positive
assert_type(tupN + size, Size)  # ✅

The bug does seem to be tuple-specific, for instance it does not appear with integer literals: https://mypy-play.net/?mypy=latest&python=3.12&gist=da0763e25cd0654d1a8b8b0b67291bc5

Expected Behavior

All assert_type in the example above should succeed.

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

    bugmypy got something wrongtopic-runtime-semanticsmypy doesn't model runtime semantics correctly

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions