Skip to content

Clarify evolve behavior for init=False fields#1587

Open
ahmojo wants to merge 1 commit into
python-attrs:mainfrom
ahmojo:docs/251-evolve-init-false
Open

Clarify evolve behavior for init=False fields#1587
ahmojo wants to merge 1 commit into
python-attrs:mainfrom
ahmojo:docs/251-evolve-init-false

Conversation

@ahmojo

@ahmojo ahmojo commented Jul 11, 2026

Copy link
Copy Markdown

Summary

Clarifies how attrs.evolve() handles fields declared with init=False.

What changed

  • Documented that existing values of init=False fields are not copied from the original instance.
  • Scoped the inability to pass such fields as changes to classes with an attrs-generated __init__.
  • Explained that normal construction determines their state on the new instance, including defaults, factories, and __attrs_post_init__ where applicable.
  • No behavior, public API, or dependency changes.

Why

attrs.evolve() skips init=False fields when copying values and then constructs a fresh instance through the class constructor.
The previous documentation said only that these fields could not be set with evolve(), which did not explain that mutated values are not preserved and was too broad for classes with a custom constructor.

Tests

  • uvx prek run --files docs/api.rst
  • uvx --with tox-uv tox run -e docs-doctests
  • uvx --with tox-uv tox run -e docs-build
  • git diff --check
  • Focused runtime checks covering a static default, factory, __attrs_post_init__, an unset field, and a custom constructor

Pull Request Checklist

  • I acknowledge this project's AI policy.
  • This pull request is not from my main branch.
  • The documentation uses semantic newlines.
  • No changelog fragment is included because this only clarifies existing behavior.

Closes #251

@ahmojo ahmojo marked this pull request as ready for review July 11, 2026 01:49
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.

evolve() and attr.ib(init=False, default="foo")

1 participant