Skip to content
Open
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
11 changes: 8 additions & 3 deletions dataclasses_json/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,14 @@ def _decode_dataclass(cls, kvs, infer_missing):
decode_names = _decode_letter_case_overrides(field_names, overrides)
kvs = {decode_names.get(k, k): v for k, v in kvs.items()}
missing_fields = {field for field in fields(cls) if field.name not in kvs}
factory_populated_fields = set()

for field in missing_fields:
if field.default is not MISSING:
kvs[field.name] = field.default
elif field.default_factory is not MISSING:
kvs[field.name] = field.default_factory()
factory_populated_fields.add(field.name)
elif infer_missing:
kvs[field.name] = None

Expand Down Expand Up @@ -230,9 +232,12 @@ def _decode_dataclass(cls, kvs, infer_missing):
infer_missing)
init_kwargs[field.name] = value
elif _is_supported_generic(field_type) and field_type != str:
init_kwargs[field.name] = _decode_generic(field_type,
field_value,
infer_missing)
if field.name in factory_populated_fields:
init_kwargs[field.name] = field_value
else:
init_kwargs[field.name] = _decode_generic(field_type,
field_value,
infer_missing)
else:
init_kwargs[field.name] = _support_extended_types(field_type,
field_value)
Expand Down
20 changes: 20 additions & 0 deletions tests/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,23 @@ def test_counter(self):
)
def test_abstract_collections(self, json_string, expected_instance):
assert type(expected_instance).from_json(json_string) == expected_instance

def test_mutable_mapping_default_factory_from_empty_dict(self):
"""Regression test for issue #505:
MutableMapping fields with default_factory should not raise TypeError
when deserializing from an input dict that omits the field."""
from collections.abc import MutableMapping
from dataclasses import dataclass, field
from dataclasses_json import DataClassJsonMixin

@dataclass
class MyClass(DataClassJsonMixin):
field1: MutableMapping[str, str] = field(default_factory=dict)

# Should not raise TypeError: MutableMapping() takes no arguments
result = MyClass.from_dict({})
assert result.field1 == {}

# Full round-trip should also work
obj = MyClass(field1={"key": "value"})
assert MyClass.from_dict(obj.to_dict()).field1 == {"key": "value"}
Loading