Skip to content

Commit

Permalink
specialize accepts a list of enumeration values, implements #43
Browse files Browse the repository at this point in the history
  • Loading branch information
bckohan committed Apr 16, 2023
1 parent a7b4582 commit 638c329
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 9 deletions.
2 changes: 1 addition & 1 deletion doc/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.4.0
enum-properties==1.5.0
2 changes: 1 addition & 1 deletion doc/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ There is one minimally impactful breaking change in the 1.5.0 release:
The 1.5.0 release includes two feature improvements:

* Implemented `Configurable behavior for matching none on symmetric fields <https://github.com/bckohan/enum-properties/issues/44>`_

* Implemented `Allow @specialize to accept a list of enumeration values. <https://github.com/bckohan/enum-properties/issues/43>`_

v1.4.0
======
Expand Down
22 changes: 21 additions & 1 deletion doc/source/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ decorator. For example:
assert SpecializedEnum.TWO.method() == 'method_two()'
assert SpecializedEnum.THREE.method() == 'method_three()'
The @specialize decorator works on @classmethods and @staticmethods as well,
The :py:meth:`~enum_properties.specialize` decorator works on @classmethods and @staticmethods as well,
but it must be the outermost decorator.

The undecorated method will apply to all members that lack a specialization:
Expand Down Expand Up @@ -281,6 +281,26 @@ lack the method.
assert SpecializedEnum.THREE.method() == 'method_three()'
:py:meth:`~enum_properties.specialize` will also accept a list so that
multiple enumeration values can share the same specialization.

.. code-block:: python
class SpecializedEnum(EnumProperties):
ONE = 1
TWO = 2
THREE = 3
@specialize(TWO, THREE)
def method(self):
return 'shared()'
assert not hasattr(SpecializedEnum.ONE, 'method')
assert SpecializedEnum.TWO.method() == 'shared()'
assert SpecializedEnum.THREE.method() == 'shared()'
Flags
-----

Expand Down
13 changes: 7 additions & 6 deletions enum_properties/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,20 +122,20 @@ class _Specialized: # pylint: disable=R0903
:param wrapped: The wrapped member function
:param value: The value to specialize for
"""
def __init__(self, wrapped, value):
def __init__(self, wrapped, values):
self.wrapped = wrapped
self.value = value
self.values = values


def specialize(value):
def specialize(*values):
"""
A decorator to specialize a method for a given enumeration value.
:param value: The enumeration value to specialize
:param values: The enumeration value(s) to specialize
:return: A decorated specialized member method
"""
def specialize_decorator(method):
return _Specialized(method, value)
return _Specialized(method, values)

return specialize_decorator

Expand Down Expand Up @@ -338,7 +338,8 @@ def __init__(self):

def __setitem__(self, key, value):
if isinstance(value, _Specialized):
self._specialized_.setdefault(value.value, {})[key] = value
for en in value.values:
self._specialized_.setdefault(en, {})[key] = value
elif key in EnumPropertiesMeta.EXPECTED:
dict.__setitem__(self, key, value)
elif key in EnumPropertiesMeta.RESERVED:
Expand Down
19 changes: 19 additions & 0 deletions enum_properties/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1913,6 +1913,25 @@ def test(self, count=3):
self.assertEqual(SpecializedEnum.THREE.test(), 'threethreethree')
self.assertEqual(SpecializedEnum('two').test(count=1), 'two')

def test_specialize_multiple_lists(self):

class SpecializedEnum(EnumProperties, s('label')):
ONE = 1, 'one'
TWO = 2, 'two'
THREE = 3, 'three'

@specialize(ONE)
def test(self, count=1):
return self.label * count

@specialize(TWO, THREE)
def test(self, count=2):
return self.label * count

self.assertEqual(SpecializedEnum.ONE.test(), 'one')
self.assertEqual(SpecializedEnum.TWO.test(), 'twotwo')
self.assertEqual(SpecializedEnum.THREE.test(), 'threethree')


class PerformanceAndMemoryChecks(TestCase):

Expand Down

0 comments on commit 638c329

Please sign in to comment.