Description
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