summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_enum.py
diff options
context:
space:
mode:
authorEthan Furman <ethan@stoneleaf.us>2018-09-22 02:03:09 (GMT)
committerGitHub <noreply@github.com>2018-09-22 02:03:09 (GMT)
commit5bdab641da0afd8aa581dfbde4f82d88d337c4b5 (patch)
tree492ee0a5d87717eeeb8abc992d71af18746f40c7 /Lib/test/test_enum.py
parentfd97d1f1af910a6222ea12aec42c456b64f9aee4 (diff)
downloadcpython-5bdab641da0afd8aa581dfbde4f82d88d337c4b5.zip
cpython-5bdab641da0afd8aa581dfbde4f82d88d337c4b5.tar.gz
cpython-5bdab641da0afd8aa581dfbde4f82d88d337c4b5.tar.bz2
bpo-29577: Enum: mixin classes don't mix well with already mixed Enums (GH-9328)
* bpo-29577: allow multiple mixin classes
Diffstat (limited to 'Lib/test/test_enum.py')
-rw-r--r--Lib/test/test_enum.py199
1 files changed, 199 insertions, 0 deletions
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index b8efb83..aadc11f 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -122,6 +122,22 @@ class TestHelpers(unittest.TestCase):
'__', '___', '____', '_____',):
self.assertFalse(enum._is_dunder(s))
+# for subclassing tests
+
+class classproperty:
+
+ def __init__(self, fget=None, fset=None, fdel=None, doc=None):
+ self.fget = fget
+ self.fset = fset
+ self.fdel = fdel
+ if doc is None and fget is not None:
+ doc = fget.__doc__
+ self.__doc__ = doc
+
+ def __get__(self, instance, ownerclass):
+ return self.fget(ownerclass)
+
+
# tests
class TestEnum(unittest.TestCase):
@@ -1730,6 +1746,102 @@ class TestEnum(unittest.TestCase):
else:
raise Exception('Exception not raised.')
+ def test_multiple_mixin(self):
+ class MaxMixin:
+ @classproperty
+ def MAX(cls):
+ max = len(cls)
+ cls.MAX = max
+ return max
+ class StrMixin:
+ def __str__(self):
+ return self._name_.lower()
+ class SomeEnum(Enum):
+ def behavior(self):
+ return 'booyah'
+ class AnotherEnum(Enum):
+ def behavior(self):
+ return 'nuhuh!'
+ def social(self):
+ return "what's up?"
+ class Color(MaxMixin, Enum):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(Color.RED.value, 1)
+ self.assertEqual(Color.GREEN.value, 2)
+ self.assertEqual(Color.BLUE.value, 3)
+ self.assertEqual(Color.MAX, 3)
+ self.assertEqual(str(Color.BLUE), 'Color.BLUE')
+ class Color(MaxMixin, StrMixin, Enum):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(Color.RED.value, 1)
+ self.assertEqual(Color.GREEN.value, 2)
+ self.assertEqual(Color.BLUE.value, 3)
+ self.assertEqual(Color.MAX, 3)
+ self.assertEqual(str(Color.BLUE), 'blue')
+ class Color(StrMixin, MaxMixin, Enum):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(Color.RED.value, 1)
+ self.assertEqual(Color.GREEN.value, 2)
+ self.assertEqual(Color.BLUE.value, 3)
+ self.assertEqual(Color.MAX, 3)
+ self.assertEqual(str(Color.BLUE), 'blue')
+ class CoolColor(StrMixin, SomeEnum, Enum):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(CoolColor.RED.value, 1)
+ self.assertEqual(CoolColor.GREEN.value, 2)
+ self.assertEqual(CoolColor.BLUE.value, 3)
+ self.assertEqual(str(CoolColor.BLUE), 'blue')
+ self.assertEqual(CoolColor.RED.behavior(), 'booyah')
+ class CoolerColor(StrMixin, AnotherEnum, Enum):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(CoolerColor.RED.value, 1)
+ self.assertEqual(CoolerColor.GREEN.value, 2)
+ self.assertEqual(CoolerColor.BLUE.value, 3)
+ self.assertEqual(str(CoolerColor.BLUE), 'blue')
+ self.assertEqual(CoolerColor.RED.behavior(), 'nuhuh!')
+ self.assertEqual(CoolerColor.RED.social(), "what's up?")
+ class CoolestColor(StrMixin, SomeEnum, AnotherEnum):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(CoolestColor.RED.value, 1)
+ self.assertEqual(CoolestColor.GREEN.value, 2)
+ self.assertEqual(CoolestColor.BLUE.value, 3)
+ self.assertEqual(str(CoolestColor.BLUE), 'blue')
+ self.assertEqual(CoolestColor.RED.behavior(), 'booyah')
+ self.assertEqual(CoolestColor.RED.social(), "what's up?")
+ class ConfusedColor(StrMixin, AnotherEnum, SomeEnum):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(ConfusedColor.RED.value, 1)
+ self.assertEqual(ConfusedColor.GREEN.value, 2)
+ self.assertEqual(ConfusedColor.BLUE.value, 3)
+ self.assertEqual(str(ConfusedColor.BLUE), 'blue')
+ self.assertEqual(ConfusedColor.RED.behavior(), 'nuhuh!')
+ self.assertEqual(ConfusedColor.RED.social(), "what's up?")
+ class ReformedColor(StrMixin, IntEnum, SomeEnum, AnotherEnum):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(ReformedColor.RED.value, 1)
+ self.assertEqual(ReformedColor.GREEN.value, 2)
+ self.assertEqual(ReformedColor.BLUE.value, 3)
+ self.assertEqual(str(ReformedColor.BLUE), 'blue')
+ self.assertEqual(ReformedColor.RED.behavior(), 'booyah')
+ self.assertEqual(ConfusedColor.RED.social(), "what's up?")
+ self.assertTrue(issubclass(ReformedColor, int))
+
class TestOrder(unittest.TestCase):
@@ -2093,6 +2205,49 @@ class TestFlag(unittest.TestCase):
d = 6
self.assertEqual(repr(Bizarre(7)), '<Bizarre.d|c|b: 7>')
+ def test_multiple_mixin(self):
+ class AllMixin:
+ @classproperty
+ def ALL(cls):
+ members = list(cls)
+ all_value = None
+ if members:
+ all_value = members[0]
+ for member in members[1:]:
+ all_value |= member
+ cls.ALL = all_value
+ return all_value
+ class StrMixin:
+ def __str__(self):
+ return self._name_.lower()
+ class Color(AllMixin, Flag):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(Color.RED.value, 1)
+ self.assertEqual(Color.GREEN.value, 2)
+ self.assertEqual(Color.BLUE.value, 4)
+ self.assertEqual(Color.ALL.value, 7)
+ self.assertEqual(str(Color.BLUE), 'Color.BLUE')
+ class Color(AllMixin, StrMixin, Flag):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(Color.RED.value, 1)
+ self.assertEqual(Color.GREEN.value, 2)
+ self.assertEqual(Color.BLUE.value, 4)
+ self.assertEqual(Color.ALL.value, 7)
+ self.assertEqual(str(Color.BLUE), 'blue')
+ class Color(StrMixin, AllMixin, Flag):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(Color.RED.value, 1)
+ self.assertEqual(Color.GREEN.value, 2)
+ self.assertEqual(Color.BLUE.value, 4)
+ self.assertEqual(Color.ALL.value, 7)
+ self.assertEqual(str(Color.BLUE), 'blue')
+
@support.reap_threads
def test_unique_composite(self):
# override __eq__ to be identity only
@@ -2468,6 +2623,49 @@ class TestIntFlag(unittest.TestCase):
for f in Open:
self.assertEqual(bool(f.value), bool(f))
+ def test_multiple_mixin(self):
+ class AllMixin:
+ @classproperty
+ def ALL(cls):
+ members = list(cls)
+ all_value = None
+ if members:
+ all_value = members[0]
+ for member in members[1:]:
+ all_value |= member
+ cls.ALL = all_value
+ return all_value
+ class StrMixin:
+ def __str__(self):
+ return self._name_.lower()
+ class Color(AllMixin, IntFlag):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(Color.RED.value, 1)
+ self.assertEqual(Color.GREEN.value, 2)
+ self.assertEqual(Color.BLUE.value, 4)
+ self.assertEqual(Color.ALL.value, 7)
+ self.assertEqual(str(Color.BLUE), 'Color.BLUE')
+ class Color(AllMixin, StrMixin, IntFlag):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(Color.RED.value, 1)
+ self.assertEqual(Color.GREEN.value, 2)
+ self.assertEqual(Color.BLUE.value, 4)
+ self.assertEqual(Color.ALL.value, 7)
+ self.assertEqual(str(Color.BLUE), 'blue')
+ class Color(StrMixin, AllMixin, IntFlag):
+ RED = auto()
+ GREEN = auto()
+ BLUE = auto()
+ self.assertEqual(Color.RED.value, 1)
+ self.assertEqual(Color.GREEN.value, 2)
+ self.assertEqual(Color.BLUE.value, 4)
+ self.assertEqual(Color.ALL.value, 7)
+ self.assertEqual(str(Color.BLUE), 'blue')
+
@support.reap_threads
def test_unique_composite(self):
# override __eq__ to be identity only
@@ -2553,6 +2751,7 @@ class TestUnique(unittest.TestCase):
value = 4
+
expected_help_output_with_docs = """\
Help on class Color in module %s: