typing icon indicating copy to clipboard operation
typing copied to clipboard

(Partial) keyword argument forwarding

Open srittau opened this issue 2 years ago • 1 comments

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".

srittau avatar Dec 06 '23 11:12 srittau

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.

Daverball avatar Dec 11 '23 08:12 Daverball