diff --git a/cattr/converters.py b/cattr/converters.py index dc7f8b0f..c19a9131 100644 --- a/cattr/converters.py +++ b/cattr/converters.py @@ -283,10 +283,10 @@ def _structure_attr_from_dict(self, a, name, mapping): type_ = a.metadata.get(TYPE_METADATA_KEY) if type_ is None: # No type. - return mapping[name] + return mapping.get(name, a.default) if _is_union_type(type_): # This is a union. - val = mapping.get(name, NOTHING) + val = mapping.get(name, a.default) if NoneType in type_.__args__ and val is NOTHING: return None return self._structure_union(val, type_) diff --git a/tests/test_structure_attrs.py b/tests/test_structure_attrs.py index 77ba9ef9..b975c882 100644 --- a/tests/test_structure_attrs.py +++ b/tests/test_structure_attrs.py @@ -1,10 +1,10 @@ """Loading of attrs classes.""" -from attr import asdict, astuple, fields +from attr import asdict, astuple, fields, make_class from hypothesis import assume, given from typing import Union -from . import simple_classes +from . import simple_classes, simple_attrs @given(simple_classes()) @@ -20,6 +20,16 @@ def test_structure_simple_from_dict(converter, cl_and_vals): assert obj == loaded +@given(simple_attrs(defaults=True)) +def test_structure_simple_from_dict_default(converter, cl_and_vals): + """Test structuring non-nested attrs classes with default value.""" + a, _ = cl_and_vals + cl = make_class("HypClass", {"a": a}) + obj = cl() + loaded = converter.structure({}, cl) + assert obj == loaded + + @given(simple_classes()) def test_roundtrip(converter, cl_and_vals): # type: (Converter, Any) -> None