Skip to content

Paramspec cannot be used as tuple/dict #12386

Closed

Description

@kasium

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

Activity

  1. AlexWaygood commented on Apr 24, 2022

    @AlexWaygood
    Member

    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

  2. added a commit that references this issue on Apr 29, 2022
    c6cf7cd
  3. svenpanne commented on Aug 23, 2022

    @svenpanne

    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?

  4. AlexWaygood commented on Aug 23, 2022

    @AlexWaygood
    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-paramspecPEP 612, ParamSpec, Concatenate

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions