Skip to content

Inherit omit_if_default when generating dict unstructure hooks - #788

Merged
Tinche merged 1 commit into
python-attrs:mainfrom
guhou-hvi:fix/omit-if-default-238
Oct 2, 2026
Merged

Tinche merged 1 commit into
python-attrs:mainfrom
guhou-hvi:fix/omit-if-default-238

Conversation

@guhou-hvi

Copy link
Copy Markdown
Contributor

Fixes #238.

With Converter(omit_if_default=True), manually registering a dict unstructure hook to rename a field currently makes default-valued fields reappear unless _cattrs_omit_if_default=True is repeated in the generator call.

make_dict_unstructure_fn and make_dict_unstructure_fn_from_attrs now inherit the converter's setting when this argument is omitted, following the existing "from_converter" convention. An explicit True or False still overrides the converter, and per-attribute overrides retain highest precedence. BaseConverter falls back to False. The setting is resolved when the hook is generated.

This also changes include_subclasses(..., overrides=...): its generated hooks now honor omit_if_default=True. If a default-valued Literal field is used to select a subclass during structuring, preserve it with a field override, for example overrides={"kind": override(omit_if_default=False)}. Other default-valued fields can still be omitted. The documentation and subclass round-trip tests cover this compatibility change.

Tests cover attrs classes and dataclasses, both generator entry points, default/true/false converter settings, explicit overrides, renamed fields, per-attribute precedence, and subclass round trips with default and tagged union strategies.
The 54 new cases produce 8 failures and 46 passes on the base commit.

Validation on Windows/Python 3.12.2:

  • Core suite: 984 passed, 15 expected failures (tests, excluding tests/test_preconf.py and tests/preconf).
  • Ruff 0.15.6, as pinned in uv.lock: full project lint and format checks pass.
  • The original issue reproduction now passes; generated hook bytecode, constants and defaults match the baseline for unchanged default/explicit-boolean behavior.
  • Sphinx: all 78 doctests in the changed customizing page pass and the new API links resolve. Full HTML/doctest runs reproduce the baseline's seven missing optional-module warnings and four doctest failures (two Windows path representations, two from missing orjson).

The optional preconfigured-converter suites and other Python versions were not run locally.

AI assistance: Codex drafted the implementation, tests, documentation and this description, and ran the local checks. A separate Codex agent reviewed the change; its compatibility finding was addressed. I reviewed and understand the changes.

@codspeed

codspeed Bot commented Oct 2, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 64 untouched benchmarks


Comparing guhou-hvi:fix/omit-if-default-238 (ff4682a) with main (b3fb197)

Open in CodSpeed

@Tinche

Tinche commented Oct 2, 2026

Copy link
Copy Markdown
Member

LGTM! Thanks.

@Tinche
Tinche merged commit 2c6cf5b into python-attrs:main Oct 2, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adding a make_dict_unstructure_fn breaks omit_if_default=True

2 participants