From 373664651d9d108aaf2d19a6c95f14d86641f05e Mon Sep 17 00:00:00 2001 From: Brian Kohan Date: Mon, 17 Apr 2023 23:28:47 -0700 Subject: [PATCH] fixes #45 --- doc/requirements.txt | 2 +- doc/source/changelog.rst | 5 +++ enum_properties/__init__.py | 31 +++++++++--------- enum_properties/tests/tests.py | 59 ++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- 5 files changed, 82 insertions(+), 17 deletions(-) diff --git a/doc/requirements.txt b/doc/requirements.txt index c1a33f1..67b1ae0 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -6,4 +6,4 @@ sphinxcontrib-htmlhelp==2.0.1; python_version >= "3.5" sphinxcontrib-jsmath==1.0.1; python_version >= "3.5" sphinxcontrib-qthelp==1.0.3; python_version >= "3.5" sphinxcontrib-serializinghtml==1.1.5; python_version >= "3.5" -enum-properties==1.5.0 +enum-properties==1.5.1 diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index a1e3619..ccfce4e 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -2,6 +2,11 @@ Change Log ========== +v1.5.1 +====== + +* Fixed `Symmetric string 'none' values enable coercion from None despite match_none=False `_ + v1.5.0 ====== diff --git a/enum_properties/__init__.py b/enum_properties/__init__.py index 02ac5ee..562f6fd 100644 --- a/enum_properties/__init__.py +++ b/enum_properties/__init__.py @@ -31,7 +31,7 @@ cached_property = property # pylint: disable=C0103 -VERSION = (1, 5, 0) +VERSION = (1, 5, 1) __title__ = 'Enum Properties' __version__ = '.'.join(str(i) for i in VERSION) @@ -218,24 +218,25 @@ def _missing_(cls, value): # pylint: disable=R0911 except KeyError: pass - for coerce_to in cls._ep_coerce_types_: - try: - val = coerce_to(value) + if value is not None: + for coerce_to in cls._ep_coerce_types_: try: - return cls._value2member_map_[val] - except KeyError: - pass + val = coerce_to(value) + try: + return cls._value2member_map_[val] + except KeyError: + pass - try: - return cls._ep_symmetric_map_[val] - except KeyError: - pass + try: + return cls._ep_symmetric_map_[val] + except KeyError: + pass - if isinstance(val, str): - return cls._ep_isymmetric_map_[_do_casenorm(val)] + if isinstance(val, str): + return cls._ep_isymmetric_map_[_do_casenorm(val)] - except (KeyError, TypeError, ValueError): - pass + except (KeyError, TypeError, ValueError): + pass return super()._missing_(value) diff --git a/enum_properties/tests/tests.py b/enum_properties/tests/tests.py index b5254d9..7bf7f0f 100644 --- a/enum_properties/tests/tests.py +++ b/enum_properties/tests/tests.py @@ -1933,6 +1933,65 @@ def test(self, count=2): self.assertEqual(SpecializedEnum.THREE.test(), 'threethree') +class NoneCoercionTests(TestCase): + + def test_string_to_none_coercion_disabled(self): + + class EnumWithNones(EnumProperties, s('prop', match_none=True)): + VALUE1 = 1, None + VALUE2 = 2, 'label' + + self.assertRaises(ValueError, EnumWithNones, 'None') + + class EnumWithNones( + EnumProperties, s('prop', case_fold=True, match_none=False) + ): + VALUE1 = 1, None + VALUE2 = 2, 'label' + + self.assertRaises(ValueError, EnumWithNones, 'None') + + class EnumWithNones(EnumProperties): + VALUE1 = None + VALUE2 = 'label' + + self.assertRaises(ValueError, EnumWithNones, 'None') + self.assertEqual(EnumWithNones(None), EnumWithNones.VALUE1) + + def test_none_to_string_coercion_disabled(self): + + class EnumWithNones(EnumProperties, s('prop', match_none=True)): + VALUE1 = 1, 'None' + VALUE2 = 2, 'label' + + self.assertRaises(ValueError, EnumWithNones, None) + self.assertEqual(EnumWithNones('None'), EnumWithNones.VALUE1) + + class EnumWithNones( + EnumProperties, s('prop', case_fold=True, match_none=True) + ): + VALUE1 = 1, 'None' + VALUE2 = 2, 'label' + + self.assertRaises(ValueError, EnumWithNones, None) + self.assertEqual(EnumWithNones('none'), EnumWithNones.VALUE1) + + class EnumWithNones(EnumProperties, s('prop', match_none=False)): + VALUE1 = 1, 'None' + VALUE2 = 2, 'label' + + self.assertRaises(ValueError, EnumWithNones, None) + self.assertEqual(EnumWithNones('None'), EnumWithNones.VALUE1) + + class EnumWithNones(EnumProperties): + VALUE1 = 'None' + VALUE2 = 'label' + + self.assertRaises(ValueError, EnumWithNones, None) + self.assertRaises(KeyError, lambda x: EnumWithNones[x], None) + self.assertEqual(EnumWithNones('None'), EnumWithNones.VALUE1) + + class PerformanceAndMemoryChecks(TestCase): from enum_properties.tests.big_enum import ISOCountry diff --git a/pyproject.toml b/pyproject.toml index 4748eff..fb0efc2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "enum-properties" -version = "1.5.0" +version = "1.5.1" description = "Add properties and method specializations to Python enumeration values with a simple declarative syntax." authors = ["Brian Kohan "] license = "MIT"