aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/enum.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/enum.py')
-rw-r--r--Lib/enum.py30
1 files changed, 28 insertions, 2 deletions
diff --git a/Lib/enum.py b/Lib/enum.py
index 01fecca3e5a..538b9cc8e96 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -535,7 +535,7 @@ class EnumType(type):
# now set the __repr__ for the value
classdict['_value_repr_'] = metacls._find_data_repr_(cls, bases)
#
- # Flag structures (will be removed if final class is not a Flag
+ # Flag structures (will be removed if final class is not a Flag)
classdict['_boundary_'] = (
boundary
or getattr(first_enum, '_boundary_', None)
@@ -544,6 +544,29 @@ class EnumType(type):
classdict['_singles_mask_'] = 0
classdict['_all_bits_'] = 0
classdict['_inverted_'] = None
+ # check for negative flag values and invert if found (using _proto_members)
+ if Flag is not None and bases and issubclass(bases[-1], Flag):
+ bits = 0
+ inverted = []
+ for n in member_names:
+ p = classdict[n]
+ if isinstance(p.value, int):
+ if p.value < 0:
+ inverted.append(p)
+ else:
+ bits |= p.value
+ elif p.value is None:
+ pass
+ elif isinstance(p.value, tuple) and p.value and isinstance(p.value[0], int):
+ if p.value[0] < 0:
+ inverted.append(p)
+ else:
+ bits |= p.value[0]
+ for p in inverted:
+ if isinstance(p.value, int):
+ p.value = bits & p.value
+ else:
+ p.value = (bits & p.value[0], ) + p.value[1:]
try:
classdict['_%s__in_progress' % cls] = True
enum_class = super().__new__(metacls, cls, bases, classdict, **kwds)
@@ -1487,7 +1510,10 @@ class Flag(Enum, boundary=STRICT):
)
if value < 0:
neg_value = value
- value = all_bits + 1 + value
+ if cls._boundary_ in (EJECT, KEEP):
+ value = all_bits + 1 + value
+ else:
+ value = singles_mask & value
# get members and unknown
unknown = value & ~flag_mask
aliases = value & ~singles_mask