Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.12, 1.13 regression] typing.overload and ParamSpec #18027

Closed
Mityuha opened this issue Oct 24, 2024 · 2 comments · Fixed by #18033
Closed

[1.12, 1.13 regression] typing.overload and ParamSpec #18027

Mityuha opened this issue Oct 24, 2024 · 2 comments · Fixed by #18033
Labels
bug mypy got something wrong topic-overloads topic-paramspec PEP 612, ParamSpec, Concatenate

Comments

@Mityuha
Copy link

Mityuha commented Oct 24, 2024

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

  • Mypy version used: 1.12.0, 1.12.1, 1.13.0
  • Mypy command-line flags: N/A
  • Mypy configuration options from mypy.ini (and other config files): N/A
  • Python version used: 3.8, 3.9, 3.10, 3.11, 3.12
@JukkaL
Copy link
Collaborator

JukkaL commented Oct 24, 2024

This bisects to #17323.

@sterliakov Could you have a look at this?

@sterliakov
Copy link
Contributor

Yes, sure! I'll try to fix this today.

Caused by overload filtering logic change in #17323, but does not relate to #17960 which is specific to functools.partial and does not concern overloads, they don't share the same underlying problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-overloads topic-paramspec PEP 612, ParamSpec, Concatenate
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants