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

Paramspec cannot be used as tuple/dict #12386

Closed
kasium opened this issue Mar 19, 2022 · 3 comments · Fixed by #12668
Closed

Paramspec cannot be used as tuple/dict #12386

kasium opened this issue Mar 19, 2022 · 3 comments · Fixed by #12668
Labels
bug mypy got something wrong topic-paramspec PEP 612, ParamSpec, Concatenate

Comments

@kasium
Copy link

kasium commented Mar 19, 2022

Bug Report

I face issues, when using ParamSpec.args as a tuple and ParamSpec.kwargs as a dict

To Reproduce

Execute mypy on the following code

from typing_extensions import ParamSpec
from typing import Callable

P = ParamSpec("P")

def foo(func: Callable[P, None]):
    def _inner(*args: P.args, **kwargs: P.kwargs):
        x = kwargs.pop("x")

Expected Behavior

It works

Actual Behavior

Error: test.py:8:13: error: "P.kwargs" has no attribute "pop" [attr-defined]

Your Environment

  • Mypy version used: 0.941
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.7.1
  • Operating system and version: Linux
@kasium kasium added the bug mypy got something wrong label Mar 19, 2022
@JelleZijlstra JelleZijlstra added the topic-paramspec PEP 612, ParamSpec, Concatenate label Mar 19, 2022
@AlexWaygood
Copy link
Member

AlexWaygood commented Apr 24, 2022

I just closed #12660 as a duplicate. Here's the repro from that issue, by @rbroderi:

from typing import TypeVar, Callable, ParamSpec
from functools import wraps

P = ParamSpec("P")
R = TypeVar("R")

def dec_test(func: Callable[P, R]) -> Callable[P, R]:
    @wraps(func)
    def inner(*args: P.args, **kwargs: P.kwargs) -> R:
        for a in args:  # error: "P.args" has no attribute "__iter__" (not iterable)
            print(a)
        for arg_k, arg_v in kwargs.items():  # error: "P.kwargs" has no attribute "items"
            print(f"{arg_k},{arg_v}")
        return func(*args, **kwargs)
  
    return inner

Playground link: https://mypy-play.net/?mypy=latest&python=3.10&gist=52d9dbf3999e25e8a72c3bb20c1cb097

JukkaL pushed a commit that referenced this issue Apr 29, 2022
…mSpec.args and ParamSpec.kwargs (#12668)

Mypy thought that a variable annotated with P.args is not iterable, and 
that a variable annotated with P.kwargs does not have a .pop() method.

Fixes #12386.
@svenpanne
Copy link

I don't think that this is fully fixed, a slight variation using destructuring doesn't work:

from collections.abc import Callable
from typing import ParamSpec

P = ParamSpec("P")

def foo(func: Callable[P, None]) -> None:
    def _inner(*args: P.args, **kwargs: P.kwargs) -> None:
        x, *y = args

See https://mypy-play.net/?mypy=latest&python=3.10&gist=0c605f87eb31c12b25c7da8f7c2819cd. You get the error: main.py:8: error: "P.args" object is not iterable. The really funny thing is that looping with for x in args works. Can you re-open this ticket?

@AlexWaygood
Copy link
Member

@svenpanne, I fixed that just the other day in #13459. It'll be included in the next mypy release (0.980).

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
4 participants