#11731·pyright

Regression: specialised self overloads erase container types and suppress attribute errors

Author: cmp0xffCreated Sep 10, 2026Updated Sep 10, 2026

Describe the bug

Starting with Pyright 1.1.412, Container[Any].copy() becomes Any instead of Container[Any], losing the outer container type and suppressing the nonexistent-member error. Expected: preserve Container[Any] and report the invalid attribute, since every overload returns a container.

Code or Screenshots

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

T = TypeVar("T")

class Container(Generic[T]):
    @overload
    def copy(self: "Container[Never]") -> "Container[Any]": ...
    @overload
    def copy(self: "Container[int]") -> "Container[int]": ...
    @overload
    def copy(self: "Container[float]") -> "Container[float]": ...
    def copy(self) -> "Container[Any]":
        return self

def example(value: Container[Any], concrete: Container[int]) -> None:
    reveal_type(value.copy())
    reveal_type(concrete.copy())
    value.copy().nonexistent_member()

VS Code extension or command-line

Version 1.1.411 exits with status 1; the later versions exit with status 0.

Pyright Generic result Missing-member error
1.1.411 Container[Any] Reported
1.1.412–1.1.414 Any Missed

All four versions infer Container[int] for the concrete control.

#11601 intentionally handles ambiguity from nested Any/Unknown in invariant nominal type arguments, with specialized-self and pandas-like tests covering precision loss. This report asks whether the shared outer container can be preserved to retain attribute checking; it does not claim a typing-specification violation.

On unchanged pandas-stubs main at pandas-dev/pandas-stubs@507243e, Pyright 1.1.414 reports 240 reportAssertTypeFailure errors versus zero in 1.1.411; related work: pandas-dev/pandas-stubs#1941 and temporary pin pandas-dev/pandas-stubs#1942.