Skip to content

Overloaded method with TypeVar(bound=tuple[int, ...]) resolves to Unknown when object fallback overload is present #3977

Description

@MarcoGorelli

Describe the Bug

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

ShapeT = TypeVar("ShapeT", bound=tuple[int, ...])
TypeT = TypeVar("TypeT")

_AnyShape = tuple[Any, ...]


class Array(Generic[ShapeT, TypeT]):
    pass


def widen_shape(arr: Array[Any, TypeT]) -> Array[_AnyShape, TypeT]: ...


class MyClass:
    @overload
    def __eq__(self, other: Array[ShapeT, Any]) -> Array[ShapeT, bool]: ...
    @overload
    def __eq__(self, other: object) -> bool: ...
    def __eq__(self, other: object) -> Any: ...


def test(x: MyClass, concrete: Array[tuple[int], str]) -> None:
    arr = widen_shape(concrete)
    reveal_type(x == arr)
(scratch) mgorelli@marcoslaptop:~/scratch$ mypy t.py
t.py:26: note: Revealed type is "t.Array[tuple[Any, ...], bool]"
Success: no issues found in 1 source file
(scratch) mgorelli@marcoslaptop:~/scratch$ pyright t.py
/home/mgorelli/scratch/t.py
  /home/mgorelli/scratch/t.py:26:17 - information: Type of "x == arr" is "Array[tuple[Any, ...], bool]"
0 errors, 0 warnings, 1 information
(scratch) mgorelli@marcoslaptop:~/scratch$ pyrefly check t.py
 INFO revealed type: Unknown [reveal-type]
  --> t.py:26:16
   |
26 |     reveal_type(x == arr)
   |                ----------
   |
 INFO 0 errors (3 suppressed)

Noticed in pandas-stubs. I used some assistance from Claude to make a small reproducible example

Sandbox Link

https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeS4ATrgLYAEALqcROgOZ0Q3G6UN0BBdKQA0dAOIx0MShADGYgCrMYANVSUxuAG4youVJjGUYu1FAD6TYjAA66ewGUAFqhuK6AXjrKb6ygAUtiAubjCKwWJ4AK5YngzRxLAA2qwMYoSZALoAlPa%2B4V4%2BKv5BIAURIHkO6BZCpKE2RQlJMMn1Gdn23ehyUKhwcIKUlKikAZLSsnLJjeFKKoq5iPZ0a3TEA3A99pgwYHQA7hB7tXCuNgEalIjDo6TtwgvuuXQAtAB8d2PJdcJzz3CWVumUIdAAxIwVLcIGx0Lw2jBuEw3nhMKQsjtev1BnQALKkADCOLgK3Q6zoAAEdHoDJhVus9gcLBYYABHFkBOAwKBgLQMZwyW4CEY-OaKMT1V6fb4PcVRXC4KDAuigiFQmwwuEI5I0yj6QxvPX9YiY8nram6fV0hlrJl0Fnsznc3n8wU3Oi4bAAKxgcgYOXeXzwSpBmVtdHtjo5Fi5PL5noFQs9Pr9AaDgmEYcIWPtDHgDAC%2BFuBOJWzEclwvRM%2BeFooeLRSaSyYjgDEo0q%2BADkqzAyRTrkVjqcLOcwgFK9WYPnqhSTGZLNYYEWvN5rjkQCIQGQTGAoKRCAxaFAKJCAAqkXf7uhoLB4fB0SeQNjRUYMCBVnPoSGOGAwOjOAwDDEKSAD0oE7vs%2B6ELwbCgVIoGYLgchwKBT6wq%2BqDvlWoF0GAvB0Kg2ioNAqDYLAj5Vs%2BmHYeSuDELRcBfmQApVm8VpwB%2B5LeMEADMhAAIwAEzBPYyQyNQlBwGasRcDwfAwJgbyYBAJj%2BhAuhFAA5LC8ImFp9jwgwbwmGy0SqYpbwANYwKQbyoHIcjwEM3haYcGjoAZ6AgAAvluDnvroABi0AwBQt44AQJDkD5QA

(Only applicable for extension issues) IDE Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions