Skip to content

Commit 024b5d0

Browse files
bysiberdeckar01sloria
authored
Fix Enum field by-name lookup to only return actual members (#2902)
* Fix Enum field by-name lookup to only return actual members Use dict-style access (self.enum[val]) instead of getattr(self.enum, val) for by-name deserialization. getattr returns any attribute of the Enum class, not just members. For example, passing "mro" or "__class__" would return built-in methods/attributes instead of raising a validation error. The enum item access operator [] only looks up actual enum members, so non-member attribute names now correctly raise a validation error. * Add test for Enum field rejecting non-member attributes by name * Update changelog --------- Co-authored-by: Jared Deckard <jared@shademaps.com> Co-authored-by: Steven Loria <git@stevenloria.com>
1 parent 252090c commit 024b5d0

3 files changed

Lines changed: 13 additions & 3 deletions

File tree

CHANGELOG.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ Bug fixes:
1414
Thanks: user:`T90REAL` for the report and :user:`rstar327` for the PR.
1515
- Fix behavior when passing a dot-delited attribute name to ``partial`` for a key with ``data_key`` set (:pr:`2903`).
1616
Thanks :user:`bysiber` for the PR.
17-
17+
- Fix Enum field by-name lookup to only return actual members (:pr:`2902`).
18+
Thanks :user:`bysiber` for the PR.
1819

1920
4.2.2 (2026-02-04)
2021
------------------

src/marshmallow/fields.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,9 +1947,10 @@ def _deserialize(self, value, attr, data, **kwargs) -> _EnumT:
19471947
except ValueError as error:
19481948
raise self.make_error("unknown", choices=self.choices_text) from error
19491949
try:
1950-
return getattr(self.enum, val)
1951-
except AttributeError as error:
1950+
ret = self.enum[val]
1951+
except KeyError as error:
19521952
raise self.make_error("unknown", choices=self.choices_text) from error
1953+
return ret
19531954

19541955

19551956
class Method(Field):

tests/test_deserialization.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,14 @@ def test_enum_field_by_symbol_invalid_value(self):
11971197
):
11981198
field.deserialize("dummy")
11991199

1200+
@pytest.mark.parametrize("non_member", ["mro", "__class__", "__members__"])
1201+
def test_enum_field_by_symbol_rejects_non_member_attributes(self, non_member):
1202+
field = fields.Enum(GenderEnum)
1203+
with pytest.raises(
1204+
ValidationError, match="Must be one of: male, female, non_binary."
1205+
):
1206+
field.deserialize(non_member)
1207+
12001208
def test_enum_field_by_symbol_not_string(self):
12011209
field = fields.Enum(GenderEnum)
12021210
with pytest.raises(ValidationError, match="Not a valid string."):

0 commit comments

Comments
 (0)