Skip to content

ParamSpec: Allow only P.args #1000

Closed
Closed
@cdce8p

Description

@cdce8p

I would like to use ParamSpec to type a function that accepts a Callable[P, Any] and *args which will be passed to the callable. The function itself does not accept keyword arguments. As an example, AbstractEventLoop.call_soon behaves similar. This is the current Typeshed definition

    def call_soon(self, callback: Callable[..., Any], *args: Any) -> Handle: ...

typeshed -> stdlib/asyncio/events.pyi -> AbstractEventLoop

P = ParamSpec("P")

    def call_soon(self, callback: Callable[P, Any], *args: P.args) -> Handle: ...

Intuitively adding a ParamSpec variable like this would make sense: "Only except *args. If any arguments are passed, they need to match those of the callback." I would also expect that if callback has required arguments, they need to be passed with *args to call_soon.

The issue here is that PEP 612 explicitly forbids specifying P.args or P.kwargs alone. They always need to be together.
https://www.python.org/dev/peps/pep-0612/#id2

Furthermore, because the default kind of parameter in Python ((x: int)) may be addressed
both positionally and through its name, two valid invocations of a (*args: P.args, **kwargs: P.kwargs)
function may give different partitions of the same set of parameters. Therefore, we need to make
sure that these special types are only brought into the world together, and are used together,
so that our usage is valid for all possible partitions.

I do wonder if this strict limitation makes sense or if there are other ways to work around it so the case described above could be supported. After all it's similar to adding **kwargs to the function signature without ever passing keyword arguments.

    def call_soon(self, callback: Callable[P, Any], *args: P.args, **kwargs: P.kwargs) -> Handle: ...

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: featureDiscussions about new features for Python's type annotations

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions