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

functools.partial plugin is only triggered on calls #17620

Open
nerodono opened this issue Aug 1, 2024 · 1 comment
Open

functools.partial plugin is only triggered on calls #17620

nerodono opened this issue Aug 1, 2024 · 1 comment
Labels
bug mypy got something wrong topic-plugins The plugin API and ideas for new plugins

Comments

@nerodono
Copy link

nerodono commented Aug 1, 2024

Bug Report

partial support is too fragile and easy to fool.

To Reproduce

import typing as t
from functools import partial

# 1.
# uncomment this to get type error
# partial(lambda x, y: x + y, 10)()

# 2.
# But this silly little thing passes type-check
silly: t.Callable[[], int] = partial(lambda x, y: x + y, 10)
silly()

Expected Behavior

Fail to coerce partial into incompatible callable type.

Actual Behavior

Success: no issues found in 1 source file

Your Environment

  • Mypy version used: master
  • Mypy command-line flags: no
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used: 3.12

Looks like we carry information about needed arguments somewhere anyways, since 1 fails type check due to not enough arguments, so why we allow to coerce that partial into incompatible callable?
Perhaps this is due to this definition of partial:

    def __call__(self, /, *args: Any, **kwargs: Any) -> _T: ...

But, for example, pyright takes that into account and fails as expected:

[nix-shell:/tmp]$ pyright issue.py
/tmp/issue.py
  /tmp/issue.py:10:30 - error: Expression of type "partial[Unknown]" is incompatible with declared type "() -> int"
    Type "partial[Unknown]" is incompatible with type "() -> int"
      Extra parameter "y" (reportAssignmentType)
1 error, 0 warnings, 0 informations

I think it worth fixing, since we support partial and it is useful to rely on that support. It can be fixed, for example, as viewing partial result internally not as partial[int] type, but as something like

class FakePartial(Protocol[P, Ret]):
    @property
    def args(self) -> tuple[Any, ...]: ...
    
    @property
    def keywords(self) -> dict[any, ...]: ...

    @property
    def func(self) -> t.Callable[..., Ret]: ...

    def __call__(self, *args: P.args, **kwargs: P.kwargs) -> Ret: ...
@nerodono nerodono added the bug mypy got something wrong label Aug 1, 2024
@hauntsaninja
Copy link
Collaborator

Thanks, I think this comment from Ivan would be a way to address this: #17425 (comment)

@hauntsaninja hauntsaninja changed the title Support of partial is too fragile and easy to fool functools.partial plugin is only triggered on calls Oct 9, 2024
@brianschubert brianschubert added the topic-plugins The plugin API and ideas for new plugins label Nov 9, 2024
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-plugins The plugin API and ideas for new plugins
Projects
None yet
Development

No branches or pull requests

3 participants