Skip to content

Commit

Permalink
Add support for marshmallow.fields.Number.as_string
Browse files Browse the repository at this point in the history
  • Loading branch information
rockTA committed Dec 21, 2022
1 parent ec6a7f7 commit 904b343
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,4 @@ Contributors (chronological)
- `<https://github.com/kasium>`_
- Edwin Erdmanis `@vorticity <https://github.com/vorticity>`_
- Mounier Florian `@paradoxxxzero <https://github.com/paradoxxxzero>`_
- Timotheus Roeck `@rockTA <https://github.com/rockTA>`
18 changes: 18 additions & 0 deletions src/apispec/ext/marshmallow/field_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ def field2type_and_format(
# hierarchy until we find something that does.
for field_class in type(field).__mro__:
if field_class in self.field_mapping:
field_class = get_diverging_field_class_if_required(field, field_class)
type_, fmt = self.field_mapping[field_class]
break
else:
Expand Down Expand Up @@ -548,3 +549,20 @@ def make_min_max_attributes(validators, min_attr, max_attr) -> dict:
if max_list:
attributes[max_attr] = min(max_list)
return attributes


def get_diverging_field_class_if_required(
field: marshmallow.fields.Field, field_class: typing.Type
) -> typing.Type:
"""Return a field class that diverges from the origin class.
This is currently only required for Number fields, because some applications serialize decimal
numbers as strings, as binary representation of floats can't be precise. However, if more fields
would allow diverging serializer fields in the future, this function could be extended.
"""
if (
issubclass(field_class, marshmallow.fields.Number)
and getattr(field, "as_string", False) is True
):
return marshmallow.fields.String
return field_class
9 changes: 9 additions & 0 deletions tests/test_ext_marshmallow_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,3 +439,12 @@ class _DesertSentinel:
field.metadata[_DesertSentinel()] = "to be ignored"
result = spec_fixture.openapi.field2property(field)
assert result == {"description": "A description", "type": "boolean"}


def test_number_as_string_is_converted_as_expected(spec_fixture):
field = fields.Number(
as_string=True,
metadata={"description": "A number field that is serialized as a string"},
)
result = spec_fixture.openapi.field2property(field)
assert result["type"] == "string"

0 comments on commit 904b343

Please sign in to comment.