Skip to content

Commit c1e93e9

Browse files
japTinche
andauthored
Use the un-underscored name if no alias attribute is there. (#416)
* Simplify code as cattrs depends on modern attrs This modern version of `attrs` provides the `alias` attribute on fields that contains the name we should use here. Also add a test to verify that structuring and unstructuring aliased attributes (which can be triggered by prefixing an attribute with an underscore) works as expected. * Tweak test --------- Co-authored-by: Tin Tvrtković <[email protected]>
1 parent c447dfe commit c1e93e9

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

HISTORY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
([#420](https://github.com/python-attrs/cattrs/pull/420))
4646
- Add support for `datetime.date`s to the PyYAML preconfigured converter.
4747
([#393](https://github.com/python-attrs/cattrs/issues/393))
48+
- Remove some unused lines in the unstructuring code.
49+
([#416](https://github.com/python-attrs/cattrs/pull/416))
4850

4951
## 23.1.2 (2023-06-02)
5052

src/cattrs/converters.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -509,16 +509,12 @@ def structure_attrs_fromdict(self, obj: Mapping[str, Any], cl: Type[T]) -> T:
509509

510510
conv_obj = {} # Start with a fresh dict, to ignore extra keys.
511511
for a in fields(cl):
512-
name = a.name
513-
514512
try:
515-
val = obj[name]
513+
val = obj[a.name]
516514
except KeyError:
517515
continue
518516

519-
if name[0] == "_":
520-
name = name[1:]
521-
517+
# try .alias and .name because this code also supports dataclasses!
522518
conv_obj[getattr(a, "alias", a.name)] = self._structure_attribute(a, val)
523519

524520
return cl(**conv_obj)

tests/test_converter.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from hypothesis import HealthCheck, assume, given, settings
1818
from hypothesis.strategies import booleans, just, lists, one_of, sampled_from
1919

20-
from cattrs import Converter, UnstructureStrategy
20+
from cattrs import BaseConverter, Converter, UnstructureStrategy
2121
from cattrs.errors import ClassValidationError, ForbiddenExtraKeysError
2222
from cattrs.gen import make_dict_structure_fn, override
2323

@@ -381,6 +381,23 @@ class C:
381381
assert inst == converter.structure(unstructured, C)
382382

383383

384+
def test_dict_roundtrip_with_alias():
385+
"""
386+
A class with an aliased attribute can be unstructured and structured.
387+
"""
388+
389+
converter = BaseConverter()
390+
391+
@define
392+
class C:
393+
_a: int
394+
395+
inst = C(a=0)
396+
unstructured = converter.unstructure(inst)
397+
assert unstructured == {"_a": 0}
398+
assert converter.structure(unstructured, C) == inst
399+
400+
384401
@given(simple_typed_classes(defaults=True))
385402
def test_type_overrides(cl_and_vals):
386403
"""

0 commit comments

Comments
 (0)