Skip to content

Commit 4a2002b

Browse files
committed
Add fields with init=False after the object is created
1 parent 5504913 commit 4a2002b

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

marshmallow_dataclass/__init__.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -905,18 +905,41 @@ def _base_schema(
905905

906906
# Remove `type: ignore` when mypy handles dynamic base classes
907907
# https://github.com/python/mypy/issues/2813
908+
fields_not_init = set()
909+
for field in dataclasses.fields(clazz):
910+
if field.init is False:
911+
fields_not_init.add(field.name)
912+
continue
913+
908914
class BaseSchema(base_schema or marshmallow.Schema): # type: ignore
909915
def load(self, data: Mapping, *, many: Optional[bool] = None, **kwargs):
910916
all_loaded = super().load(data, many=many, **kwargs)
911917
many = self.many if many is None else bool(many)
912918
if many:
913-
return [clazz(**loaded) for loaded in all_loaded]
919+
return [
920+
get_obj_with_init(clazz, fields_not_init, loaded)
921+
for loaded in all_loaded
922+
]
914923
else:
915-
return clazz(**all_loaded)
924+
return get_obj_with_init(clazz, fields_not_init, all_loaded)
916925

917926
return BaseSchema
918927

919928

929+
def get_obj_with_init(
930+
clazz: type, fields_not_init: set[str], all_loaded: dict[str, Any]
931+
):
932+
if fields_not_init:
933+
not_in_init = {
934+
key: all_loaded.pop(key) for key in fields_not_init if key in all_loaded
935+
}
936+
obj = clazz(**all_loaded)
937+
if fields_not_init:
938+
for key, value in not_in_init.items():
939+
setattr(obj, key, value)
940+
return obj
941+
942+
920943
def _get_field_default(field: dataclasses.Field):
921944
"""
922945
Return a marshmallow default value given a dataclass default value

0 commit comments

Comments
 (0)