summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEthan Furman <ethan@stoneleaf.us>2020-09-16 20:01:00 (GMT)
committerGitHub <noreply@github.com>2020-09-16 20:01:00 (GMT)
commit7219e27087baaa8a5693b5bef1b1357bddbffa53 (patch)
tree9235d51826e2a14c26220a63a536085615604d16
parentfc23a9483ef0d7c98bea9f82392377d0b6ef7b18 (diff)
downloadcpython-7219e27087baaa8a5693b5bef1b1357bddbffa53.zip
cpython-7219e27087baaa8a5693b5bef1b1357bddbffa53.tar.gz
cpython-7219e27087baaa8a5693b5bef1b1357bddbffa53.tar.bz2
Enum: make `Flag` and `IntFlag` members iterable (GH-22221)
-rw-r--r--Doc/library/enum.rst15
-rw-r--r--Lib/enum.py4
-rw-r--r--Lib/test/test_enum.py12
-rw-r--r--Misc/NEWS.d/next/Library/2020-09-12-16-18-42.bpo-32218.IpYkEe.rst1
4 files changed, 32 insertions, 0 deletions
diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst
index 32e8bbf..2f84be2 100644
--- a/Doc/library/enum.rst
+++ b/Doc/library/enum.rst
@@ -656,6 +656,13 @@ be combined with them::
>>> Perm.X | 8
<Perm.8|X: 9>
+:class:`IntFlag` members can also be iterated over::
+
+ >>> list(RW)
+ [<Perm.R: 4>, <Perm.W: 2>]
+
+.. 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)
+ [<Color.BLUE: 2>, <Color.RED: 1>]
+
+.. 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 21a94ca..3c459ea 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 ebf7604..59789fb 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 0000000..d5832b9
--- /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