From 96b080c1afcb080572d848f4e8890c6649ff92ec Mon Sep 17 00:00:00 2001 From: Ben Radler Date: Fri, 30 Mar 2018 13:14:15 -0700 Subject: [PATCH 1/4] The allow_none keyword argument is lost in the constructor override in this library --- marshmallow_enum/__init__.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/marshmallow_enum/__init__.py b/marshmallow_enum/__init__.py index b731cbb..f818847 100644 --- a/marshmallow_enum/__init__.py +++ b/marshmallow_enum/__init__.py @@ -33,7 +33,15 @@ class EnumField(Field): } def __init__( - self, enum, by_value=False, load_by=None, dump_by=None, error='', *args, **kwargs + self, + enum, + by_value=False, + load_by=None, + dump_by=None, + error='', + allow_none=None, + *args, + **kwargs ): self.enum = enum self.by_value = by_value @@ -69,7 +77,7 @@ def __init__( self.load_by = load_by self.dump_by = dump_by - super(EnumField, self).__init__(*args, **kwargs) + super(EnumField, self).__init__(allow_none=allow_none, *args, **kwargs) def _serialize(self, value, attr, obj): if value is None: From 3d981382f294ab6fdf04a7fb92491f6438cb952d Mon Sep 17 00:00:00 2001 From: Ben Radler Date: Mon, 2 Apr 2018 13:03:27 -0700 Subject: [PATCH 2/4] Handle lists of string enums --- marshmallow_enum/__init__.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/marshmallow_enum/__init__.py b/marshmallow_enum/__init__.py index f818847..bfe1804 100644 --- a/marshmallow_enum/__init__.py +++ b/marshmallow_enum/__init__.py @@ -29,7 +29,8 @@ class EnumField(Field): default_error_messages = { 'by_name': 'Invalid enum member {input}', 'by_value': 'Invalid enum value {input}', - 'must_be_string': 'Enum name must be string' + 'must_be_string': 'Enum name must be string', + 'must_be_list': 'Enum must be a list of strings' } def __init__( @@ -102,13 +103,23 @@ def _deserialize_by_value(self, value, attr, data): self.fail('by_value', input=value, value=value) def _deserialize_by_name(self, value, attr, data): + # str if not isinstance(value, string_types): self.fail('must_be_string', input=value, name=value) - - try: - return getattr(self.enum, value) - except AttributeError: - self.fail('by_name', input=value, name=value) + else: + try: + return getattr(self.enum, value) + except AttributeError: + self.fail('by_name', input=value, name=value) + + # list + if not isinstance(value, list): + self.fail('must_be_list', input=value, name=value) + else: + try: + return [getattr(self.enum, v) for v in value] + except AttributeError: + self.fail('by_name', input=value, name=value) def fail(self, key, **kwargs): kwargs['values'] = ', '.join([text_type(mem.value) for mem in self.enum]) From d1b62d9c5ec9f9a65c1566d4f7f84deec9045c94 Mon Sep 17 00:00:00 2001 From: Ben Radler Date: Mon, 2 Apr 2018 14:53:34 -0700 Subject: [PATCH 3/4] refactor allow lists of enums --- marshmallow_enum/__init__.py | 15 +++++++-------- tests/test_enum_field.py | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/marshmallow_enum/__init__.py b/marshmallow_enum/__init__.py index bfe1804..c0bc0a7 100644 --- a/marshmallow_enum/__init__.py +++ b/marshmallow_enum/__init__.py @@ -29,8 +29,7 @@ class EnumField(Field): default_error_messages = { 'by_name': 'Invalid enum member {input}', 'by_value': 'Invalid enum value {input}', - 'must_be_string': 'Enum name must be string', - 'must_be_list': 'Enum must be a list of strings' + 'must_be_string_or_list': 'Enum must be string or list of strings' } def __init__( @@ -104,23 +103,23 @@ def _deserialize_by_value(self, value, attr, data): def _deserialize_by_name(self, value, attr, data): # str - if not isinstance(value, string_types): - self.fail('must_be_string', input=value, name=value) - else: + if isinstance(value, string_types): try: return getattr(self.enum, value) except AttributeError: self.fail('by_name', input=value, name=value) # list - if not isinstance(value, list): - self.fail('must_be_list', input=value, name=value) - else: + elif isinstance(value, list): try: return [getattr(self.enum, v) for v in value] except AttributeError: self.fail('by_name', input=value, name=value) + # validation + else: + self.fail('must_be_string_or_list', input=value, name=value) + def fail(self, key, **kwargs): kwargs['values'] = ', '.join([text_type(mem.value) for mem in self.enum]) kwargs['names'] = ', '.join([mem.name for mem in self.enum]) diff --git a/tests/test_enum_field.py b/tests/test_enum_field.py index 2426bfe..edfc22e 100644 --- a/tests/test_enum_field.py +++ b/tests/test_enum_field.py @@ -168,7 +168,7 @@ def test_uses_default_error_if_no_custom_provided(self): class TestRegressions(object): - @pytest.mark.parametrize('bad_value', [object, object(), [], {}, 1, 3.4, False, ()]) + @pytest.mark.parametrize('bad_value', [object, object(), {}, 1, 3.4, False, ()]) def test_by_name_must_be_string(self, bad_value): class SomeEnum(Enum): From 8a55a52511d7ade3292c3859b5a0b985d40a9a46 Mon Sep 17 00:00:00 2001 From: Nick Tarnek Date: Sun, 24 Nov 2019 23:48:46 -0800 Subject: [PATCH 4/4] support for marshamallow 3 --- marshmallow_enum/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/marshmallow_enum/__init__.py b/marshmallow_enum/__init__.py index c0bc0a7..9b4b0fa 100644 --- a/marshmallow_enum/__init__.py +++ b/marshmallow_enum/__init__.py @@ -79,7 +79,7 @@ def __init__( super(EnumField, self).__init__(allow_none=allow_none, *args, **kwargs) - def _serialize(self, value, attr, obj): + def _serialize(self, value, attr, obj, **kwargs): if value is None: return None elif self.dump_by == LoadDumpOptions.value: @@ -87,7 +87,7 @@ def _serialize(self, value, attr, obj): else: return value.name - def _deserialize(self, value, attr, data): + def _deserialize(self, value, attr, data, **kwargs): if value is None: return None elif self.load_by == LoadDumpOptions.value: