Skip to content

Commit 904b343

Browse files
committed
Add support for marshmallow.fields.Number.as_string
1 parent ec6a7f7 commit 904b343

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

AUTHORS.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,4 @@ Contributors (chronological)
7676
- `<https://github.com/kasium>`_
7777
- Edwin Erdmanis `@vorticity <https://github.com/vorticity>`_
7878
- Mounier Florian `@paradoxxxzero <https://github.com/paradoxxxzero>`_
79+
- Timotheus Roeck `@rockTA <https://github.com/rockTA>`

src/apispec/ext/marshmallow/field_converter.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ def field2type_and_format(
187187
# hierarchy until we find something that does.
188188
for field_class in type(field).__mro__:
189189
if field_class in self.field_mapping:
190+
field_class = get_diverging_field_class_if_required(field, field_class)
190191
type_, fmt = self.field_mapping[field_class]
191192
break
192193
else:
@@ -548,3 +549,20 @@ def make_min_max_attributes(validators, min_attr, max_attr) -> dict:
548549
if max_list:
549550
attributes[max_attr] = min(max_list)
550551
return attributes
552+
553+
554+
def get_diverging_field_class_if_required(
555+
field: marshmallow.fields.Field, field_class: typing.Type
556+
) -> typing.Type:
557+
"""Return a field class that diverges from the origin class.
558+
559+
This is currently only required for Number fields, because some applications serialize decimal
560+
numbers as strings, as binary representation of floats can't be precise. However, if more fields
561+
would allow diverging serializer fields in the future, this function could be extended.
562+
"""
563+
if (
564+
issubclass(field_class, marshmallow.fields.Number)
565+
and getattr(field, "as_string", False) is True
566+
):
567+
return marshmallow.fields.String
568+
return field_class

tests/test_ext_marshmallow_field.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,3 +439,12 @@ class _DesertSentinel:
439439
field.metadata[_DesertSentinel()] = "to be ignored"
440440
result = spec_fixture.openapi.field2property(field)
441441
assert result == {"description": "A description", "type": "boolean"}
442+
443+
444+
def test_number_as_string_is_converted_as_expected(spec_fixture):
445+
field = fields.Number(
446+
as_string=True,
447+
metadata={"description": "A number field that is serialized as a string"},
448+
)
449+
result = spec_fixture.openapi.field2property(field)
450+
assert result["type"] == "string"

0 commit comments

Comments
 (0)