diff --git a/changelog.d/100.propagate.rst b/changelog.d/100.propagate.rst new file mode 100644 index 0000000..be278fc --- /dev/null +++ b/changelog.d/100.propagate.rst @@ -0,0 +1 @@ +Nested fields will now inherit their parent dataclass' metadata params so that `marshmallow.EXCLUDE` will propagate to child dataclasses. diff --git a/src/desert/_make.py b/src/desert/_make.py index 088386c..d250cf5 100644 --- a/src/desert/_make.py +++ b/src/desert/_make.py @@ -130,7 +130,7 @@ def class_schema( attributes[field.name] = field_for_schema( hints.get(field.name, field.type), _get_field_default(field), - field.metadata, + {**meta, **field.metadata}, ) cls_schema = type( @@ -289,7 +289,8 @@ def field_for_schema( if field is None: nested = forward_reference or class_schema(typ) - field = marshmallow.fields.Nested(nested) + params = {k: v for k, v in metadata.items() if type(k) is str} + field = marshmallow.fields.Nested(nested, **params) field.metadata.update(metadata) diff --git a/tests/test_make.py b/tests/test_make.py index 0e1aa01..4230c1a 100644 --- a/tests/test_make.py +++ b/tests/test_make.py @@ -191,6 +191,24 @@ class B: assert data == B(A(5)) +def test_nested_unknown(module): + """Schemas will propagate meta to Nested dataclasses.""" + + @module.dataclass + class A: + x: int + + @module.dataclass + class B: + y: A + + data = desert.schema_class(B, meta={"unknown": marshmallow.EXCLUDE})().load( + {"y": {"x": 5, "z": 3}} + ) + + assert data == B(A(5)) + + def test_optional(module): """Setting an optional type makes the default None."""