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

Generic class with ParamSpec isn't callable as far as partial is concerned #14802

Closed
NeilGirdhar opened this issue Feb 28, 2023 · 2 comments
Closed
Labels
bug mypy got something wrong topic-paramspec PEP 612, ParamSpec, Concatenate

Comments

@NeilGirdhar
Copy link
Contributor

NeilGirdhar commented Feb 28, 2023

from collections.abc import Callable
from functools import partial
from typing import Generic, TypeVar

from typing_extensions import ParamSpec

R_co = TypeVar('R_co', covariant=True)
P = ParamSpec('P')

class X(Generic[P, R_co]):
    def __init__(self, f: Callable[P, R_co]):
        super().__init__()
        self.f = f

    def __call__(self, /, *args: P.args, **kwargs: P.kwargs) -> R_co:
        return self.f(*args, **kwargs)

@partial(X)  # error: Argument 1 to "partial" has incompatible type "Type[X[Any, Any]]"; expected "Callable[..., X[P, R_co]]"  [arg-type]
def f() -> int:
    return 2

print(f())
@NeilGirdhar NeilGirdhar added the bug mypy got something wrong label Feb 28, 2023
@AlexWaygood AlexWaygood added the topic-paramspec PEP 612, ParamSpec, Concatenate label Feb 28, 2023
@gschaffner
Copy link
Contributor

gschaffner commented Mar 23, 2023

oddly, Mypy accepts X as a Callable[P, T_co] here—it's specifically Callable[..., T_co] that it's rejecting:

class X(Generic[P, T_co]):
    def __init__(self, func: Callable[P, T_co], /) -> None:
        self._func = func

    def __call__(self, *args: P.args, **kwargs: P.kwargs) -> T_co:
        return self._func(*args, **kwargs)


class badX(Generic[T_co]):
    # the same wrapper thing, but "typed" (really, half-typed) like :class:`~functools.partial`.
    def __init__(self, func: Callable[..., T_co], /) -> None:
        self._func = func

    def __call__(self, *args: Any, **kwargs: Any) -> T_co:
        return self._func(*args, **kwargs)


X(X)
badX(X)  # error: Argument 1 to "badX" has incompatible type "Type[X[Any, Any]]"; expected "Callable[..., X[P, T_co]]"  [arg-type]

(https://mypy-play.net/?mypy=1.1.1&python=3.11&gist=75162691fee56d70787ee7a94896a081)

@ilevkivskyi
Copy link
Member

The original example works on master, likely fixed by #15837

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-paramspec PEP 612, ParamSpec, Concatenate
Projects
None yet
Development

No branches or pull requests

4 participants