issue23591: bool(empty_flags) == False; more docs & tests
This commit is contained in:
parent
0443953067
commit
25d94bbf05
|
@ -546,6 +546,10 @@ members also subclass :class:`int` and can be used wherever an :class:`int` is.
|
||||||
Any operation on an :class:`IntFlag` member besides the bit-wise operations
|
Any operation on an :class:`IntFlag` member besides the bit-wise operations
|
||||||
will lose the :class:`IntFlag` membership.
|
will lose the :class:`IntFlag` membership.
|
||||||
|
|
||||||
|
.. versionadded:: 3.6
|
||||||
|
|
||||||
|
Sample :class:`IntFlag` class::
|
||||||
|
|
||||||
>>> from enum import IntFlag
|
>>> from enum import IntFlag
|
||||||
>>> class Perm(IntFlag):
|
>>> class Perm(IntFlag):
|
||||||
... R = 4
|
... R = 4
|
||||||
|
@ -560,19 +564,71 @@ will lose the :class:`IntFlag` membership.
|
||||||
>>> Perm.R in RW
|
>>> Perm.R in RW
|
||||||
True
|
True
|
||||||
|
|
||||||
.. versionadded:: 3.6
|
It is also possible to name the combinations::
|
||||||
|
|
||||||
|
>>> class Perm(IntFlag):
|
||||||
|
... R = 4
|
||||||
|
... W = 2
|
||||||
|
... X = 1
|
||||||
|
... RWX = 7
|
||||||
|
>>> Perm.RWX
|
||||||
|
<Perm.RWX: 7>
|
||||||
|
>>> ~Perm.RWX
|
||||||
|
<Perm.0: 0>
|
||||||
|
|
||||||
|
Another important difference between :class:`IntFlag` and :class:`Enum` is that
|
||||||
|
if no flags are set (the value is 0), its boolean evaluation is :data:`False`::
|
||||||
|
|
||||||
|
>>> Perm.R & Perm.X
|
||||||
|
<Perm.0: 0>
|
||||||
|
>>> bool(Perm.R & Perm.X)
|
||||||
|
False
|
||||||
|
|
||||||
|
Because :class:`IntFlag` members are also subclasses of :class:`int` they can
|
||||||
|
be combined with them::
|
||||||
|
|
||||||
|
>>> Perm.X | 8
|
||||||
|
<Perm.8|X: 9>
|
||||||
|
|
||||||
|
|
||||||
Flag
|
Flag
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
The last variation is :class:`Flag`. Like :class:`IntFlag`, :class:`Flag`
|
The last variation is :class:`Flag`. Like :class:`IntFlag`, :class:`Flag`
|
||||||
members can be combined using the bitwise operators (^, \|, ^, ~). Unlike
|
members can be combined using the bitwise operators (&, \|, ^, ~). Unlike
|
||||||
:class:`IntFlag`, they cannot be combined with, nor compared against, any
|
:class:`IntFlag`, they cannot be combined with, nor compared against, any
|
||||||
other :class:`Flag` enumeration nor :class:`int`.
|
other :class:`Flag` enumeration, nor :class:`int`.
|
||||||
|
|
||||||
.. versionadded:: 3.6
|
.. versionadded:: 3.6
|
||||||
|
|
||||||
|
Like :class:`IntFlag`, if a combination of :class:`Flag` members results in no
|
||||||
|
flags being set, the boolean evaluation is :data:`False`::
|
||||||
|
|
||||||
|
>>> from enum import Flag
|
||||||
|
>>> class Color(Flag):
|
||||||
|
... red = 1
|
||||||
|
... blue = 2
|
||||||
|
... green = 4
|
||||||
|
...
|
||||||
|
>>> Color.red & Color.green
|
||||||
|
<Color.0: 0>
|
||||||
|
>>> bool(Color.red & Color.green)
|
||||||
|
False
|
||||||
|
|
||||||
|
Giving a name to the "no flags set" condition does not change its boolean
|
||||||
|
value::
|
||||||
|
|
||||||
|
>>> class Color(Flag):
|
||||||
|
... black = 0
|
||||||
|
... red = 1
|
||||||
|
... blue = 2
|
||||||
|
... green = 4
|
||||||
|
...
|
||||||
|
>>> Color.black
|
||||||
|
<Color.black: 0>
|
||||||
|
>>> bool(Color.black)
|
||||||
|
False
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
For the majority of new code, :class:`Enum` and :class:`Flag` are strongly
|
For the majority of new code, :class:`Enum` and :class:`Flag` are strongly
|
||||||
|
|
|
@ -714,6 +714,9 @@ class Flag(Enum):
|
||||||
'|'.join([str(m._name_ or m._value_) for m in members]),
|
'|'.join([str(m._name_ or m._value_) for m in members]),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return bool(self._value_)
|
||||||
|
|
||||||
def __or__(self, other):
|
def __or__(self, other):
|
||||||
if not isinstance(other, self.__class__):
|
if not isinstance(other, self.__class__):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
|
@ -1767,6 +1767,14 @@ class TestFlag(unittest.TestCase):
|
||||||
self.assertIs(Open.WO & ~Open.WO, Open.RO)
|
self.assertIs(Open.WO & ~Open.WO, Open.RO)
|
||||||
self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE)
|
self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE)
|
||||||
|
|
||||||
|
def test_bool(self):
|
||||||
|
Perm = self.Perm
|
||||||
|
for f in Perm:
|
||||||
|
self.assertTrue(f)
|
||||||
|
Open = self.Open
|
||||||
|
for f in Open:
|
||||||
|
self.assertEqual(bool(f.value), bool(f))
|
||||||
|
|
||||||
def test_programatic_function_string(self):
|
def test_programatic_function_string(self):
|
||||||
Perm = Flag('Perm', 'R W X')
|
Perm = Flag('Perm', 'R W X')
|
||||||
lst = list(Perm)
|
lst = list(Perm)
|
||||||
|
@ -2137,6 +2145,14 @@ class TestIntFlag(unittest.TestCase):
|
||||||
self.assertFalse(W in RX)
|
self.assertFalse(W in RX)
|
||||||
self.assertFalse(X in RW)
|
self.assertFalse(X in RW)
|
||||||
|
|
||||||
|
def test_bool(self):
|
||||||
|
Perm = self.Perm
|
||||||
|
for f in Perm:
|
||||||
|
self.assertTrue(f)
|
||||||
|
Open = self.Open
|
||||||
|
for f in Open:
|
||||||
|
self.assertEqual(bool(f.value), bool(f))
|
||||||
|
|
||||||
class TestUnique(unittest.TestCase):
|
class TestUnique(unittest.TestCase):
|
||||||
|
|
||||||
def test_unique_clean(self):
|
def test_unique_clean(self):
|
||||||
|
|
Loading…
Reference in New Issue