[1.12, 1.13 regression] typing.overload and ParamSpec · Issue #18027 · python/mypy (original) (raw)

Bug Report

There are two overloaded versions of function: the first version for AsyncContextManager parameter, the second version for Callable with ParamSpec.
Static type checker must choose the first version, but it chooses the second one.

BUT: after removing ParamSpec from function signature, mypy ends up working well (see the comment in example).

Note: pyright (v. 1.1.386) works just fine on it.
Possibly related to #17960

To Reproduce

from future import annotations

from types import TracebackType from typing import Any, AsyncContextManager, Callable, TypeVar, overload

from typing_extensions import ParamSpec, Self

T = TypeVar("T") P = ParamSpec("P")

class Animal: async def aenter(self) -> Self: return self

async def __aexit__(
    self,
    typ: type[BaseException] | None,
    exc: BaseException | None,
    tb: TracebackType | None,
) -> None:
    return None

def __call__(self) -> str:
    return "name"

@overload def name(animal: AsyncContextManager[T]) -> T: ...

@overload def name( animal: Callable[P, T], *_args: P.args, **_kwargs: P.kwargs, ) -> T: ...

BUT!

if replace the second overload with

@overload

def name(animal: Callable[[], T]) -> T: ...

or even

def name(animal: Callable[[int], T]) -> T: ...

everything works fine

def name( animal: Any, *_args: Any, **_kwargs: Any, ) -> Any: return animal

dog = Animal() dog2: Animal = name(dog)

Live playground link

Expected Behavior
mypy has not reported any issue with such overloaded functions, and should still not report as it was for mypy prior to 1.12.0.

Actual Behavior

main.py:58: error: Incompatible types in assignment (expression has type "str", variable has type "Animal") [assignment] Found 1 error in 1 file (checked 1 source file)

Your Environment