Skip to content

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

Before — flagged Forwarding broad arguments still loses the callable contract
app/adapter.py
def wrapper(*args: object, **kwargs: object):
return target(*args, **kwargs)
After — preferred ParamSpec preserves the forwarded callable contract
app/adapter.py
from collections.abc import Callable
def wrapper[**P, R](target: Callable[P, R], *args: P.args, **kwargs: P.kwargs) -> R:
return target(*args, **kwargs)
Before — flagged An ignored catch-all weakens a fake's contract
tests/fakes/session.py
class Session:
async def start(self, **_kwargs: object) -> None:
self.start_count += 1
After — preferred Preserve named typed keywords with a named unused binding
tests/fakes/session.py
class Session:
async def start(self, *, room: Room, agent: Agent) -> None:
_unused_inputs = room, agent
self.start_count += 1
Before — flagged A deliberately open formatting interface still requests policy review
app/templates.py
def render(template: str, **values: object) -> str:
return template.format(**values)
After — preferred Document why template fields require an open object-valued interface
app/templates.py
def render(
template: str, **values: object
) -> (
str
): # sarj-noqa: SARJ477 — template supplies dynamic field names and object formatting
return template.format(**values)