Skip to content

enum: dir() of IntFlag instance excludes complex binary values #135559

Open
@AdamPiotrowski91

Description

@AdamPiotrowski91

Bug report

Bug description:

When explicitly set members of an IntFlag are not powers of two (are "complex" in nature), they are not listed via dir() method and it has further implications when used.

Please correct me if I am wrong, but there is no info in documentation suggesting that you should use Flag or IntFlag only with a set of specific values.

The below example clearly shows the behaviour.

class AggregatedRights(IntFlag):
    """Enumeration constants used to specify combination of Rights values."""

    NONE = 0b00000000  # 0
    CONSUME = 0b01000101  # 69
    VIEW = 0b11000101  # 197
    MODIFY = 0b11011101  # 221
    ALL = 0b11111111  # 255

print(dir(AggregatedRights))

"""Outputs:
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__contains__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getstate__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__iter__', '__le__', '__len__', '__lshift__', '__lt__', '__members__', '__mod__', '__module__', '__mul__', '__name__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__qualname__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_count', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'is_integer', 'numerator', 'real', 'to_bytes']
"""

Whereas

class Rights(IntFlag):
    """Enumeration constants used to specify the access granted attribute of
    the DSS objects."""

    EXECUTE = 0b10000000  # 128
    USE = 0b01000000  # 64
    CONTROL = 0b00100000  # 32
    DELETE = 0b00010000  # 16
    WRITE = 0b00001000  # 8
    READ = 0b00000100  # 4
    USE_EXECUTE = 0b00000010  # 2 (deprecated)
    BROWSE = 0b00000001  # 1

print(dir(Rights))

"""Outputs:
['BROWSE', 'CONTROL', 'DELETE', 'EXECUTE', 'READ', 'USE', 'USE_EXECUTE', 'WRITE', '__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__contains__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getstate__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__iter__', '__le__', '__len__', '__lshift__', '__lt__', '__members__', '__mod__', '__module__', '__mul__', '__name__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__qualname__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_count', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'is_integer', 'numerator', 'real', 'to_bytes']
"""

Of course using dir() is mainly just to show that something seems wrong. This has a lot of implications, one of which (and a main problem in my case) is that those members are not generated with autodoc in Sphinx and require additional workarounds just to be found. But just to add to that, for example list(flag) would return an empty list on flag = IntFlag, etc.


Could you advise if that is expected behaviour (and why) and if not, feel free to let me know if anything else may be helpful from me to resolve this.

Also, if that is working as expected, could you improve documentation to clearly state that and advise what would be a standard alternative instead of IntFlag here?


Used Python 3.13.3 on MacOS but I assume this might be irrelevant here.

CPython versions tested on:

3.13

Operating systems tested on:

macOS

Linked PRs

Metadata

Metadata

Assignees

Labels

stdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions