diff options
author | Ethan Furman <ethan@stoneleaf.us> | 2018-09-21 19:03:09 -0700 |
---|---|---|
committer | Ethan Furman <ethan@stoneleaf.us> | 2018-09-21 19:09:16 -0700 |
commit | 13ba6d21f19b87f4768217d0989bea4885be0827 (patch) | |
tree | db67aad2c83c8258a1dba466412fc76a27177aa8 /Lib/test/test_enum.py | |
parent | e5fde1f992e94f166415ab96d874ed1d2e0c8004 (diff) | |
download | cpython-git-backport-5bdab64-3.7.tar.gz |
[3.7] bpo-29577: Enum: mixin classes don't mix well with already mixed Enums (GH-9328)backport-5bdab64-3.7
* bpo-29577: allow multiple mixin classes.
(cherry picked from commit 5bdab641da0afd8aa581dfbde4f82d88d337c4b5)
Co-authored-by: Ethan Furman <ethan@stoneleaf.us>
Diffstat (limited to 'Lib/test/test_enum.py')
-rw-r--r-- | Lib/test/test_enum.py | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 4b17228946..6c147d7ca6 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -120,6 +120,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): @@ -1701,6 +1717,102 @@ class TestEnum(unittest.TestCase): third = auto() self.assertEqual([Dupes.first, Dupes.second, Dupes.third], list(Dupes)) + 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): @@ -2064,6 +2176,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 @@ -2439,6 +2594,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 @@ -2524,6 +2722,7 @@ class TestUnique(unittest.TestCase): value = 4 + expected_help_output_with_docs = """\ Help on class Color in module %s: |