From ce840960a6c1ccbfc70dc8473cddbf8cbb2f5c7e Mon Sep 17 00:00:00 2001 From: Brian Kohan Date: Tue, 25 Oct 2022 18:49:02 -0700 Subject: [PATCH] closes #17, #18, #19 --- enum_properties/__init__.py | 34 +++++++++++++++++++++------------- enum_properties/tests/tests.py | 14 ++++++++++++++ setup.cfg | 3 +++ 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/enum_properties/__init__.py b/enum_properties/__init__.py index 5392481..2dcf9a4 100644 --- a/enum_properties/__init__.py +++ b/enum_properties/__init__.py @@ -18,13 +18,17 @@ import enum # pylint: disable=protected-access import unicodedata -from collections.abc import Generator, Hashable, Iterable +from collections.abc import ( # pylint: disable=E0611 + Generator, + Hashable, + Iterable, +) try: from functools import cached_property -except ImportError: +except ImportError: # pragma: no cover # todo remove when python 3.7 support is dropped - cached_property = property # pragma: no cover + cached_property = property # pylint: disable=C0103 VERSION = (1, 3, 0) @@ -120,7 +124,7 @@ class SymmetricMixin: # pylint: disable=R0903 _ep_symmetric_map_ = {} _ep_isymmetric_map_ = {} - _symmetric_builtins_ = ['name'] + _symmetric_builtins_ = [] def __eq__(self, value): """Symmetric equality - try to coerce value before failure""" @@ -369,11 +373,12 @@ def __new__( # pylint: disable=W0221 classdict ) cls._ep_coerce_types_ = [] - cls._ep_symmetric_map_ = {} + cls._ep_symmetric_map_ = cls._member_map_ cls._ep_isymmetric_map_ = {} cls.enum_properties = list(classdict._ep_properties_.keys()) def add_sym_lookup(prop, p_val, enum_inst): + print(prop, p_val, enum_inst) if not isinstance(p_val, Hashable): raise ValueError( f'{cls}.{prop}:{p_val} is not hashable. Symmetrical ' @@ -516,19 +521,22 @@ def flagged(self): """ Returns the list of flags that are active. """ - # do import here to keep lib less brittle b/c this is a private - # include and may change, rely on CI to find issues - from enum import _decompose # pylint: disable=C0415 - return [ - flag for flag in _decompose(self.__class__, self._value_)[0] - if flag != 0 - ] + return list(flag for flag in iter(self)) def __iter__(self): """ Return a generator for the active flags. """ - return (flag for flag in self.flagged) + return ( + member for member in self.__class__ + if ( + (member.value != 0) and + # make sure member is a power of 2, composites are included in + # iteration < 3.11 + ((member.value & (member.value - 1)) == 0) and + (self.value & member.value == member.value) + ) + ) def __len__(self): """ diff --git a/enum_properties/tests/tests.py b/enum_properties/tests/tests.py index 1ef83e5..9e43f0b 100644 --- a/enum_properties/tests/tests.py +++ b/enum_properties/tests/tests.py @@ -931,6 +931,10 @@ class Perm( X = 4, 'execute' RWX = 7, 'all' + @property + def custom_prop(self): + return self.label.upper() + self.assertEqual(Perm.R.label, 'read') self.assertEqual(Perm.W.label, 'write') self.assertEqual(Perm.X.label, 'execute') @@ -941,6 +945,9 @@ class Perm( self.assertTrue(Perm.X is Perm('execute')) self.assertTrue(Perm.RWX is Perm('all')) + self.assertEqual(Perm.W.custom_prop, 'WRITE') + self.assertEqual(Perm.RWX.custom_prop, 'ALL') + self.assertTrue((Perm.R | Perm.W | Perm.X) is Perm('RWX')) self.assertTrue(Perm([Perm.R, Perm.W, Perm.X]) is Perm('RWX')) self.assertTrue(Perm({'read', 'write', 'execute'}) is Perm('RWX')) @@ -987,6 +994,10 @@ class Perm( X = auto(), 'execute' RWX = R | W | X, 'all' + @property + def custom_prop(self): + return self.label.upper() + self.assertEqual(Perm.R.label, 'read') self.assertEqual(Perm.W.label, 'write') self.assertEqual(Perm.X.label, 'execute') @@ -997,6 +1008,9 @@ class Perm( self.assertTrue(Perm.X is Perm('execute')) self.assertTrue(Perm.RWX is Perm('all')) + self.assertEqual(Perm.W.custom_prop, 'WRITE') + self.assertEqual(Perm.RWX.custom_prop, 'ALL') + self.assertTrue((Perm.R | Perm.W | Perm.X) is Perm('RWX')) self.assertTrue(Perm([Perm.R, Perm.W, Perm.X]) is Perm('RWX')) self.assertTrue(Perm({'read', 'write', 'execute'}) is Perm('RWX')) diff --git a/setup.cfg b/setup.cfg index 1fa776c..79e06c3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -15,6 +15,9 @@ valid-metaclass-classmethod-first-arg = mcs [pylint.DESIGN] max-branches=15 +[pylint.MESSAGES CONTROL] +disable=W0511 + [darglint] # Darglint integrates with flake8 # https://github.com/terrencepreilly/darglint