Use kw_only dataclass fields to prevent argument swaps

Use kw_only dataclass fields to prevent argument swaps

Positional arguments are compact, but they can hide a swap when adjacent values share a type. An endpoint’s port and timeout are both integers, so Endpoint("api", 5, 443) looks plausible while carrying the wrong meaning. Marking those dataclass fields with field(kw_only=True) makes the generated initializer require their names. The call site therefore records whether 443 is port and whether 5 is timeout_seconds.

The valid construction is asserted and printed. The second construction supplies the two integer values positionally; it raises TypeError, which the example catches to demonstrate the generated signature’s runtime enforcement. This feature prevents accidental positional swapping at that constructor boundary, not every possible configuration mistake. A caller can still deliberately attach an unsuitable number to a correct keyword, so domain validation remains separate. Keyword-only fields are also omitted from the dataclass’s positional pattern-matching arguments, which may affect matching code. Per-field kw_only and the decorator option were added in Python 3.10.

See the official dataclasses.field documentation. AI assistance disclosure: this article was drafted with AI assistance and checked using a synthetic example.

from dataclasses import dataclass, field


@dataclass(frozen=True)
class Endpoint:
    host: str
    port: int = field(kw_only=True)
    timeout_seconds: int = field(kw_only=True)


endpoint = Endpoint("api", port=443, timeout_seconds=5)
assert endpoint == Endpoint("api", port=443, timeout_seconds=5)
try:
    Endpoint("api", 443, 5)
except TypeError:
    print("positional values rejected")
else:
    raise AssertionError("keyword-only fields accepted positional values")
print(f"{endpoint.host}:{endpoint.port} timeout={endpoint.timeout_seconds}")
positional values rejected
api:443 timeout=5

Comments

Popular posts from this blog

Compare Two Text Files in Python Without Modifying Them

Seven CSV Quality Checks to Run Before Importing Data

Explain why SQLite transactions cannot make an HTTP call atomic