1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

[Python] How can I type a dict to match a generic `Callable`’s `ParamSpec.kwargs`?

Discussão em 'Python' iniciado por Stack, Setembro 15, 2025.

  1. Stack

    Stack Membro Participativo

    I’m trying to write a small utility that forwards a dict of keyword arguments to an arbitrary callable, and I’d like static type checking to verify that the dict’s keys/values match the callable’s keyword parameters.

    def apply[R](fn: Callable[..., R], inputs: dict[str, Any]) -> R:
    return fn(**inputs)


    This works at runtime, but type checkers don’t relate the dict type to the Callable so incorrect keys/values won’t be flagged.

    What I would like is something like the following:

    def apply[**P, R](fn: Callable[P, R], inputs: P.kwargs) -> R:
    return fn(**inputs)


    The standard *args/**kwargs forwarding (works, but changes the call site)

    def apply[**P, R](fn: Callable[P, R], /, *args: P.args, **kwargs: P.kwargs) -> R:
    return fn(*args, **kwargs)


    This type-checks perfectly. However, it forces callers to use apply(fn, **inputs) instead of apply(fn, inputs). I’m specifically asking whether inputs can be a single dict parameter that’s type-checked against P.kwargs. Also type checkers report that I need to include both args and kwargs attributes of ParamSpec, even though I only want to support kwargs.

    Ideally, it would type check like this:

    def f(*, a: int, b: str) -> tuple[int, str]:
    return (a, b)

    good = apply(f, {"a": 1, "b": "x"}) # should type-check
    bad = apply(f, {"a": "oops"}) # should be a type error
    extra = apply(f, {"a": 1, "b": "x", "c": 0}) # should be a type error


    Is there any way to make inputs’s type track fn’s P.kwargs without changing the call site to apply(fn, **inputs)?

    Continue reading...

Compartilhe esta Página