no-broad-keyword-capture
Prefer precise keyword interfaces over missing, Any- or object-valued captures.
Why
Replacing a fixed typed interface with broad **kwargs can erase required keyword names and per-key value types, making test doubles accept calls the real implementation rejects. object remains a safe typed top type, and deliberately open data interfaces can be valid; this strict interface policy requires a precise contract or a documented open-boundary exception.
Fix
Keep explicit typed parameters at fixed interfaces. Preserve required keyword names with named unused local bindings. Use ParamSpec for forwarding, Unpack[TypedDict] for named schemas, or a precise homogeneous value type. Document genuinely open interfaces with an exact-code reasoned suppression.
Examples
def wrapper(*args: object, **kwargs: object): return target(*args, **kwargs)from collections.abc import Callable
def wrapper[**P, R](target: Callable[P, R], *args: P.args, **kwargs: P.kwargs) -> R: return target(*args, **kwargs)class Session: async def start(self, **_kwargs: object) -> None: self.start_count += 1class Session: async def start(self, *, room: Room, agent: Agent) -> None: _unused_inputs = room, agent self.start_count += 1def render(template: str, **values: object) -> str: return template.format(**values)def render( template: str, **values: object) -> ( str): # sarj-noqa: SARJ477 — template supplies dynamic field names and object formatting return template.format(**values)