Skip to content

Conversation

@veeceey
Copy link

@veeceey veeceey commented Feb 8, 2026

Summary

Fixes #1479

  • Moves default alias resolution (e.g., stripping leading underscores from _private to private) to before the field_transformer callback, so transformers receive fully populated Attribute objects with usable alias values instead of None.
  • Adds a second alias resolution pass after the transformer to handle any new fields the transformer may have added without setting an alias.
  • Updates Attribute.evolve() to automatically update the alias when the name changes, if the alias was auto-generated (matches the default for the old name). Explicit aliases are preserved.

Before (broken)

def transformer(cls, fields):
    for f in fields:
        print(f.alias)  # None for auto-generated aliases
    return fields

After (fixed)

def transformer(cls, fields):
    for f in fields:
        print(f.alias)  # 'private' for _private, 'my_alias' for explicit
    return fields

Test plan

  • Added test_hook_alias_available - verifies transformer sees resolved aliases
  • Added test_hook_evolve_name_updates_auto_alias - verifies evolve(name=...) updates auto-generated alias
  • Added test_hook_evolve_name_keeps_explicit_alias - verifies evolve(name=...) preserves explicit alias
  • Updated 2 existing test expectations where error messages now show the resolved alias instead of None
  • Full test suite passes: 1367 passed, 6 skipped, 2 xfailed

🤖 Generated with Claude Code

veeceey and others added 2 commits February 8, 2026 15:03
Previously, field_transformer received attributes with alias=None for
fields without an explicit alias. The default alias (e.g., stripping
leading underscores) was only resolved after the transformer ran, making
it impossible for transformers to access or use alias values.

This moves alias resolution to before the field_transformer call, so
transformers receive fully populated Attribute objects. A second pass
after the transformer handles any new fields the transformer may have
added.

Additionally, Attribute.evolve() now automatically updates the alias
when the name changes, if the alias was auto-generated (matching the
default for the old name). Explicit aliases are preserved.

Fixes python-attrs#1479

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update extending.md doctest to reflect that field_transformer now
  receives pre-resolved aliases (use alias == name.lstrip("_") instead
  of `not field.alias` to detect auto-generated aliases)
- Add changelog entry for python-attrs#1479
- Add test_hook_new_field_without_alias to cover the post-transformer
  alias resolution path (line 496 of _make.py)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

Alias not available during field transformation

1 participant