Skip to content

Commit f5299b1

Browse files
committed
Improve the allow_none default for by_value enums
1 parent 7bb19f0 commit f5299b1

3 files changed

Lines changed: 14 additions & 0 deletions

File tree

src/marshmallow/fields.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,6 +1928,7 @@ class Enum(Field[_EnumT]):
19281928
If `by_value` is `False` (default), enum members are (de)serialized by symbol (name).
19291929
If it is `True`, they are (de)serialized by value using `marshmallow.fields.Raw`.
19301930
If it is a field instance or class, they are (de)serialized by value using this field.
1931+
If `by_value` is enabled on an enum with a `None` value `allow_none` defaults to `True`.
19311932
19321933
.. versionadded:: 3.18.0
19331934
"""
@@ -1968,6 +1969,8 @@ def __init__(
19681969
self.choices_text = ", ".join(
19691970
str(self.field._serialize(m.value, None, None)) for m in enum
19701971
)
1972+
if "allow_none" not in kwargs and any(m.value is None for m in enum):
1973+
self.allow_none = True
19711974

19721975
def _serialize(
19731976
self, value: _EnumT | None, attr: str | None, obj: typing.Any, **kwargs

tests/base.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ class HairColorEnum(Enum):
2828
red = "red hair"
2929

3030

31+
class UltimatumEnum(Enum):
32+
all = float("inf")
33+
nothing = None
34+
35+
3136
class DateEnum(Enum):
3237
date_1 = dt.date(2004, 2, 29)
3338
date_2 = dt.date(2008, 2, 29)
@@ -57,6 +62,7 @@ class DateEnum(Enum):
5762
functools.partial(fields.Enum, GenderEnum),
5863
functools.partial(fields.Enum, HairColorEnum, by_value=fields.String),
5964
functools.partial(fields.Enum, GenderEnum, by_value=fields.Integer),
65+
functools.partial(fields.Enum, UltimatumEnum, allow_none=False),
6066
]
6167

6268

tests/test_deserialization.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
DateEnum,
2525
GenderEnum,
2626
HairColorEnum,
27+
UltimatumEnum,
2728
assert_date_equal,
2829
assert_time_equal,
2930
central,
@@ -1281,6 +1282,10 @@ def test_enum_field_by_value_field_wrong_type(self):
12811282
with pytest.raises(ValidationError, match="Not a valid date."):
12821283
field.deserialize("30/02/2004")
12831284

1285+
def test_enum_by_value_allow_none_default(self):
1286+
field = fields.Enum(UltimatumEnum, by_value=True)
1287+
assert field.deserialize(None) is None
1288+
12841289
def test_deserialization_function_must_be_callable(self):
12851290
with pytest.raises(TypeError):
12861291
fields.Function(lambda x: None, deserialize="notvalid")

0 commit comments

Comments
 (0)