Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/attr/_make.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ def _transform_attrs(
attrs = base_attrs + own_attrs

if field_transformer is not None:
attrs = field_transformer(cls, attrs)
attrs = tuple(field_transformer(cls, attrs))

# Check attr order after executing the field_transformer.
# Mandatory vs non-mandatory attr order only matters when they are part of
Expand Down
16 changes: 16 additions & 0 deletions tests/test_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,22 @@ class C:
assert "CAttributes" == fields_type.__name__
assert issubclass(fields_type, tuple)

def test_hook_generator(self):
"""
Ensure that `attrs.fields` are correctly recorded when field_transformer is a generator

Regression test for #1417
"""

def hook(cls, attribs):
yield from attribs

@attr.s(auto_attribs=True, field_transformer=hook)
class Base:
x: int

assert ["x"] == [a.name for a in attr.fields(Base)]


class TestAsDictHook:
def test_asdict(self):
Expand Down