diff --git a/changelog.d/79.change.rst b/changelog.d/79.change.rst new file mode 100644 index 0000000..ff4c4b5 --- /dev/null +++ b/changelog.d/79.change.rst @@ -0,0 +1 @@ +Schemas no longer copy non-field dataclass attributes. Thanks to @sveinse for report and test. diff --git a/src/desert/_make.py b/src/desert/_make.py index 30fa030..088386c 100644 --- a/src/desert/_make.py +++ b/src/desert/_make.py @@ -118,10 +118,12 @@ def class_schema( else: raise desert.exceptions.NotAnAttrsClassOrDataclass(clazz) - # Copy all public members of the dataclass to the schema - attributes = {k: v for k, v in inspect.getmembers(clazz) if not k.startswith("_")} - # Update the schema members to contain marshmallow fields instead of dataclass fields + # Copy all public fields of the dataclass to the schema + attributes = { + field.name: field for field in fields if not field.name.startswith("_") + } + # Update the schema members to contain marshmallow fields instead of dataclass fields. hints = t.get_type_hints(clazz) for field in fields: if field.init: diff --git a/tests/test_make.py b/tests/test_make.py index d865209..0e1aa01 100644 --- a/tests/test_make.py +++ b/tests/test_make.py @@ -557,3 +557,17 @@ def _(self): schema = desert.schema(C) assert schema.load({"x": 1}) == C(x=1, y=2) + + +def test_methods_not_on_schema(module): + """Dataclass methods are not copied to the schema.""" + + @module.dataclass + class A: + def dataclass_method(self) -> None: + """This method should not exist on the schema.""" + + schema = desert.schema(A) + sentinel = object() + method = getattr(schema, "dataclass_method", sentinel) + assert method is sentinel