Files
python-patterns/sources/attrs.md
T
2026-06-01 21:42:05 +00:00

3.0 KiB

Attrs source notes

Repo: python-attrs/attrs Local checkout: /home/ubuntu/repos/rodin-sources/attrs

Why this repo is useful

  • attrs is a strong source for explicit data-carrier design: generated methods, constructor-shape control, and deliberate conversion at boundaries.
  • Its docs are especially valuable because they include caveats and failure cases, not just happy-path examples.

Declarative fields are the default for data-heavy classes

Repeated evidence

  • docs/examples.md:24-44 shows @define with typed fields immediately generating constructor, repr, and equality behavior.
  • docs/examples.md:31-44 makes the generated behavior visible at the REPL rather than implicit.
  • docs/examples.md:51-58 shows the same declarative shape without relying on type annotations, via field().

Why it matters

Repeated signal: when a class mostly carries data, attrs prefers declaring fields and letting the library generate the boilerplate. The code emphasizes structure and invariants over handwritten dunder noise.

Caveat / counterexample

docs/examples.md:60-62 warns that mixing field() declarations without annotations flips attrs into a no-typing mode and can ignore annotation-only attributes. That is a sharp edge worth preserving in synthesis: declarative does not mean "mix styles freely."

Keyword-only fields are used to protect call-site clarity and inheritance

Repeated evidence

  • docs/examples.md:147-157 shows field(kw_only=True) forcing explicit construction at the call site.
  • docs/examples.md:159-172 shows decorator-level @define(kw_only=True) applying the same rule to the whole class.
  • docs/examples.md:176-191 shows the practical inheritance payoff: subclasses can add required fields even when the base class already has defaults.
  • docs/examples.md:193-205 shows the counterexample when kw_only=True is omitted: invalid attribute ordering raises a ValueError.

Why it matters

Repeated signal: keyword-only fields are not just cosmetic. They are a tool for making constructor calls self-describing and for avoiding inheritance-order traps.

Serialization is explicit and filterable

Repeated evidence

  • docs/examples.md:211-217 shows asdict(...) as a deliberate conversion step from object to plain data.
  • docs/examples.md:219-235 shows asdict(..., filter=...) excluding sensitive fields like passwords.
  • docs/examples.md:238-253 shows built-in include/exclude helpers for more reusable serialization control.

Why it matters

Repeated signal: even value-like objects are not assumed to be wire-ready. attrs makes the serialization boundary explicit and gives callers hooks to shape what crosses it.

Pattern candidates supported by this repo

  • use declarative field definitions for data-carrier classes
  • prefer keyword-only construction when call-site clarity or inheritance safety matters
  • keep serialization as an explicit step
  • preserve caveats about mixed declaration styles and constructor ordering