From: Ethan Furman Date: Wed, 16 Sep 2020 20:01:00 +0000 (-0700) Subject: Enum: make `Flag` and `IntFlag` members iterable (GH-22221) X-Git-Tag: v3.10.0a1~101 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7219e27087baaa8a5693b5bef1b1357bddbffa53;p=thirdparty%2FPython%2Fcpython.git Enum: make `Flag` and `IntFlag` members iterable (GH-22221) --- diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 32e8bbf95092..2f84be229bc4 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -656,6 +656,13 @@ be combined with them:: >>> Perm.X | 8 +:class:`IntFlag` members can also be iterated over:: + + >>> list(RW) + [, ] + +.. versionadded:: 3.10 + Flag ^^^^ @@ -709,6 +716,14 @@ value:: >>> bool(Color.BLACK) False +:class:`Flag` members can also be iterated over:: + + >>> purple = Color.RED | Color.BLUE + >>> list(purple) + [, ] + +.. versionadded:: 3.10 + .. note:: For the majority of new code, :class:`Enum` and :class:`Flag` are strongly diff --git a/Lib/enum.py b/Lib/enum.py index 21a94caaee33..3c459ea4113d 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -753,6 +753,10 @@ class Flag(Enum): type(other).__qualname__, self.__class__.__qualname__)) return other._value_ & self._value_ == other._value_ + def __iter__(self): + members, extra_flags = _decompose(self.__class__, self.value) + return (m for m in members if m._value_ != 0) + def __repr__(self): cls = self.__class__ if self._name_ is not None: diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index ebf76047972d..59789fb7bcc5 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -2350,6 +2350,12 @@ class TestFlag(unittest.TestCase): self.assertFalse(W in RX) self.assertFalse(X in RW) + def test_member_iter(self): + Color = self.Color + self.assertEqual(list(Color.PURPLE), [Color.BLUE, Color.RED]) + self.assertEqual(list(Color.BLUE), [Color.BLUE]) + self.assertEqual(list(Color.GREEN), [Color.GREEN]) + def test_auto_number(self): class Color(Flag): red = auto() @@ -2805,6 +2811,12 @@ class TestIntFlag(unittest.TestCase): with self.assertRaises(TypeError): self.assertFalse('test' in RW) + def test_member_iter(self): + Color = self.Color + self.assertEqual(list(Color.PURPLE), [Color.BLUE, Color.RED]) + self.assertEqual(list(Color.BLUE), [Color.BLUE]) + self.assertEqual(list(Color.GREEN), [Color.GREEN]) + def test_bool(self): Perm = self.Perm for f in Perm: diff --git a/Misc/NEWS.d/next/Library/2020-09-12-16-18-42.bpo-32218.IpYkEe.rst b/Misc/NEWS.d/next/Library/2020-09-12-16-18-42.bpo-32218.IpYkEe.rst new file mode 100644 index 000000000000..d5832b9767b7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-12-16-18-42.bpo-32218.IpYkEe.rst @@ -0,0 +1 @@ +`enum.Flag` and `enum.IntFlag` members are now iterable