Skip to content

Commit ba74d7b

Browse files
committed
Add support for marshmallow.fields.Number.as_string
1 parent 7abbf7d commit ba74d7b

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
@@ -75,3 +75,4 @@ Contributors (chronological)
7575
- Stefan van der Walt `<https://github.com/stefanv>`_
7676
- `<https://github.com/kasium>`_
7777
- Edwin Erdmanis `@vorticity <https://github.com/vorticity>`_
78+
- 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:
@@ -546,3 +547,20 @@ def make_min_max_attributes(validators, min_attr, max_attr) -> dict:
546547
if max_list:
547548
attributes[max_attr] = min(max_list)
548549
return attributes
550+
551+
552+
def get_diverging_field_class_if_required(
553+
field: marshmallow.fields.Field, field_class: typing.Type
554+
) -> typing.Type:
555+
"""Return a field class that diverges from the origin class.
556+
557+
This is currently only required for Number fields, because some applications serialize decimal
558+
numbers as strings, as binary representation of floats can't be precise. However, if more fields
559+
would allow diverging serializer fields in the future, this function could be extended.
560+
"""
561+
if (
562+
issubclass(field_class, marshmallow.fields.Number)
563+
and getattr(field, "as_string", False) is True
564+
):
565+
return marshmallow.fields.String
566+
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)