Typing kwargs with typing.Unpack

PEP-0692 gave us a way to typehint **kwargs using a typing.TypedDict but this requires you to:

  1. Write a TypedDict that’s matches the signature of the function we want to pass the kwargs to
  2. Keep it in sync if said function gains or loses a kwarg in future

Is there no way to “automatically” copy the function signature?

Essentially, I’m looking for something like this:

from typing import Unpack

from httpx import Client, Response

def my_wrapper(foo: str, **kwargs: Unpack[Client]) -> Response:

    with Client(**kwargs) as session:
        response = session.get(...)
    return response

httpx.Client() takes lots of arguments, it’s not gonna be fun to write all of that in a TypedDict

Client kwargs
    def __init__(
        auth: AuthTypes | None = None,
        params: QueryParamTypes | None = None,
        headers: HeaderTypes | None = None,
        cookies: CookieTypes | None = None,
        verify: VerifyTypes = True,
        cert: CertTypes | None = None,
        http1: bool = True,
        http2: bool = False,
        proxy: ProxyTypes | None = None,
        proxies: ProxiesTypes | None = None,
        mounts: None | (typing.Mapping[str, BaseTransport | None]) = None,
        timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG,
        follow_redirects: bool = False,
        limits: Limits = DEFAULT_LIMITS,
        max_redirects: int = DEFAULT_MAX_REDIRECTS,
        event_hooks: None | (typing.Mapping[str, list[EventHook]]) = None,
        base_url: URLTypes = "",
        transport: BaseTransport | None = None,
        app: typing.Callable[..., typing.Any] | None = None,
        trust_env: bool = True,
        default_encoding: str | typing.Callable[[bytes], str] = "utf-8",
    ) -> None:

Here’s me trying to get it close with a TypedDict

from typing import TYPE_CHECKING, Any, Callable, Mapping, TypedDict

    from httpx import BaseTransport, Limits
    from httpx._client import EventHook
    from httpx._types import (

# Note, I can't even match it 1:1 because TypedDicts don't support
# right hand-side values used to indicate the default
class HTTPXClientKwargs(TypedDict):
    auth: AuthTypes | None
    params: QueryParamTypes | None
    headers: HeaderTypes | None
    cookies: CookieTypes | None
    verify: VerifyTypes
    cert: CertTypes | None
    http1: bool
    http2: bool
    proxy: ProxyTypes | None
    proxies: ProxiesTypes | None
    mounts: None | (Mapping[str, BaseTransport | None])
    timeout: TimeoutTypes
    follow_redirects: bool
    limits: Limits
    max_redirects: int
    event_hooks: None | (Mapping[str, list[EventHook]])
    base_url: URLTypes
    transport: BaseTransport | None
    app: Callable[..., Any] | None
    trust_env: bool
    default_encoding: str | Callable[[bytes], str]


  • Super verbose
  • Duping code
  • Can’t match it 1:1 because typedDicts don’t support right hand side values used to indicate the default in function signature

Perhaps taking them from the parameters attribute of the output of inspect.signature.