Skip to content

[1.12 regression] mypy no longer recognises descriptors/get that bind self #18036

Closed
@maxfischer2781

Description

@maxfischer2781

Bug Report

For decorators that work on methods as descriptors, I do type-hint+overload __get__ as returning the descriptor or filling in self. This previously worked up to MyPy 1.11 and PyRight was/is happy with it. However, since version 1.12 MyPy no longer matches the overload and completely loses type information; the Possible overload variant suggested is the least suitable.

I initially was notified about this for my own library providing async versions of the standard library, specifically the lru_cache. An MRE not using my library is below (in case I missed something that makes the MRE fixable but not my library, this would be good to know, too).

To Reproduce

from __future__ import annotations
from typing import Any, overload, Callable, Concatenate


class Descriptor[C: Callable[..., Any]]:
    def __init__(self, impl: C) -> None: ...

    @overload
    def __get__(
        self: Descriptor[C], instance: None, owner: type | None
    ) -> Descriptor[C]: ...

    @overload
    def __get__[S, **P, R](
        self: Descriptor[Callable[Concatenate[S, P], R]], instance: S, owner: type | None,
    ) -> Callable[P, R]: ...


class Test:
    @Descriptor
    def method(self, foo: int, bar: str) -> bytes: ...


reveal_type(Test().method)
# Pyright pyright 1.1.386    Type of "Test().method" is "(foo: int, bar: str) -> bytes"
# MyPy 1.11                  Revealed type is "def (foo: builtins.int, bar: builtins.str) -> builtins.bytes"
# MyPy 1.12                  Revealed type is "Any"

Playground link. The ordering of the overload cases does not matter.

Expected Behavior

MyPy should correctly infer the type of the bound method. MyPy should report the most suitable overload.

Actual Behavior

MyPy matches none of the overloads and thus completely loses type information. The reported most suitable overload is actually the least suitable.

Your Environment

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions