python / typing

Python static typing home. Hosts the documentation and a user help forum.
https://typing.readthedocs.io/
Other
1.57k stars 232 forks source link

(Partial) keyword argument forwarding #1524

Open srittau opened 8 months ago

srittau commented 8 months ago

Split from #1000.


I have a similar use case with Ariadne middleware functions, but with kwargs. In Ariadne, a "resolver" function takes two positional arguments and a varying number of keyword arguments that depend on the API the resolver implements. As the name implies, a middleware function sits between Ariadne and the resolver function and forwards arguments.

Ideally, I would like to type a middleware function as follows:

_P = ParamSpec("_P")
_R = TypeVar("_R")
_T = TypeVar("_T")

def foo_middleware(
    resolver: Callable[Concatenate[_T, GraphQLResolveInfo, _P], _R],
    obj: _T,
    info: GraphQLResolveInfo,
    /,
    **kwargs: _P.kwargs,
) -> _R:
    ...
    return resolver(obj, info, **kwargs)

But currently this isn't possible, because _P.args is "missing".

Daverball commented 8 months ago

My understanding of PEP612 always was that the "pos-args-only" and "kwargs-only" case (and any other arbitrary restriction) would be supported in the future through upper bounds, the main limiting factor of this, is that we don't have a complete way to manually bind a param spec yet (without using another callable). We've relied on callback protocols as a workaround for the Callable syntax not being expressive enough to capture all the possible types of arguments.

PEP646 let us cover one very important use-case "pos-args-only", but it also doesn't specify upper bounds yet, so we can't cover all the possible uses of *args either.