From b6f4158f2df68fd57016dc3f0ec04e73ca3d334c Mon Sep 17 00:00:00 2001 From: yuval Date: Tue, 7 Nov 2023 19:47:30 +0200 Subject: [PATCH] if default value is callable, call it, also, verify that the default value is serializable --- marshmallow_jsonschema/base.py | 17 +++++++++++++++-- tests/test_dump.py | 11 +++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/marshmallow_jsonschema/base.py b/marshmallow_jsonschema/base.py index 2db5a3d..5744dc6 100644 --- a/marshmallow_jsonschema/base.py +++ b/marshmallow_jsonschema/base.py @@ -1,5 +1,6 @@ import datetime import decimal +import json import uuid from enum import Enum from inspect import isclass @@ -195,8 +196,13 @@ def _from_python_type(self, obj, field, pytype) -> typing.Dict[str, typing.Any]: if field.dump_only: json_schema["readOnly"] = True - if field.default is not missing and not callable(field.default): - json_schema["default"] = field.default + if field.default is not missing: + if (not callable(field.default) and self._is_serializable(field.default)): + json_schema["default"] = field.default + else: + default_value = field.default() + if self._is_serializable(default_value): + json_schema["default"] = default_value if ALLOW_ENUMS and isinstance(field, EnumField): json_schema["enum"] = self._get_enum_values(field) @@ -225,6 +231,13 @@ def _from_python_type(self, obj, field, pytype) -> typing.Dict[str, typing.Any]: ) return json_schema + def _is_serializable(self, value): + try: + json.dumps(value) + return True + except TypeError: + return False + def _get_enum_values(self, field) -> typing.List[str]: assert ALLOW_ENUMS and isinstance(field, EnumField) diff --git a/tests/test_dump.py b/tests/test_dump.py index 38584f5..6a0a0b6 100644 --- a/tests/test_dump.py +++ b/tests/test_dump.py @@ -42,6 +42,17 @@ class TestSchema(Schema): props = dumped["definitions"]["TestSchema"]["properties"] assert "default" not in props["uid"] +def test_default_callable_serialized(): + class TestSchema(Schema): + uid = fields.UUID(default=lambda: str(uuid.uuid4())) + + schema = TestSchema() + + dumped = validate_and_dump(schema) + + props = dumped["definitions"]["TestSchema"]["properties"] + assert "default" in props["uid"] + def test_uuid(): schema = UserSchema()