Skip to content

3.11.4: ValueError when inverting enum.Flag member with mask member #105497

Closed
@The-Compiler

Description

With code such as:

import enum

class Flag(enum.Flag):
    A = 0x01
    B = 0x02
    Mask = 0xff

print(~Flag.A)

Python 3.10.11 prints Flag.B, and so does Python 3.11.3. However, with Python 3.11.4, this happens instead:

Traceback (most recent call last):
  File "/home/florian/tmp/f.py", line 9, in <module>
    print(~Flag.A)
          ^^^^^^^
  File "/usr/lib/python3.11/enum.py", line 1542, in __invert__
    self._inverted_ = self.__class__(self._flag_mask_ ^ self._value_)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/enum.py", line 711, in __call__
    return cls.__new__(cls, value)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/enum.py", line 1136, in __new__
    raise exc
  File "/usr/lib/python3.11/enum.py", line 1113, in __new__
    result = cls._missing_(value)
             ^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/enum.py", line 1454, in _missing_
    raise ValueError('%r: no members with value %r' % (cls, unknown))
ValueError: <flag 'Flag'>: no members with value 252

As a workaround, a detour via .value works in this case:

>>> Flag((Flag.A | Flag.B).value & ~Flag.A.value)
<Flag.B: 2>

This causes issues with PyQt, which has the following flags (as bindings from C++):

>>> from PyQt6.QtCore import Qt
>>> for e in Qt.KeyboardModifier:
...     print(f"{e.name} = {hex(e.value)}")
... 
NoModifier = 0x0
ShiftModifier = 0x2000000
ControlModifier = 0x4000000
AltModifier = 0x8000000
MetaModifier = 0x10000000
KeypadModifier = 0x20000000
GroupSwitchModifier = 0x40000000
KeyboardModifierMask = 0xfe000000

(Output from Python 3.10 - with Python 3.11, KeyboardModifierMask goes missing in the output, and so does Flag.Mask above, but that seems like a different issue?)

With my project, I'm trying to remove a modifier from the given flags. With Python 3.10.11 and 3.11.3:

>>> (Qt.KeyboardModifier.ShiftModifier | Qt.KeyboardModifier.ControlModifier) & ~Qt.KeyboardModifier.ControlModifier
<KeyboardModifier.ShiftModifier: 33554432>

But with Python 3.11.4, same issue as above:

>>> from PyQt6.QtCore import Qt
>>> (Qt.KeyboardModifier.ShiftModifier | Qt.KeyboardModifier.ControlModifier) & ~Qt.KeyboardModifier.ControlModifier
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.11/enum.py", line 1542, in __invert__
    self._inverted_ = self.__class__(self._flag_mask_ ^ self._value_)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/enum.py", line 711, in __call__
    return cls.__new__(cls, value)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/enum.py", line 1136, in __new__
    raise exc
  File "/usr/lib/python3.11/enum.py", line 1113, in __new__
    result = cls._missing_(value)
             ^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/enum.py", line 1454, in _missing_
    raise ValueError('%r: no members with value %r' % (cls, unknown))
ValueError: <flag 'KeyboardModifier'>: no members with value 2147483648

As a culprit, I suspect:

cc @ethanfurman @benburrill

Linked PRs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

3.11only security fixes3.12bugs and security fixesstdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions