python / cpython

The Python programming language
https://www.python.org/
Other
60.87k stars 29.38k forks source link

enum.Flag ignores bitwise operator methods from mixins #121291

Open gswifort opened 2 days ago

gswifort commented 2 days ago

When I define methods ('__or__', '__and__', '__xor__', '__ror__', '__rand__', '__rxor__', '__invert__') directly in the class inheriting from enum.Flag, these methods are "added" (mro) to the members, however, if the method is defined in the mixin, the methods defined in enum.Flag are added (e.g. Flag.__or__). I would expect methods to be called from mixin.

from enum import Flag

class Mixin:
    def __or__(self, value): ...

class MyFlag(Mixin, Flag):
    pass

class MyFlag2(Flag):
    def __or__(self, value): ...

print(MyFlag.__or__.__qualname__)  # Flag.__or__, I would expect Mixin.__or__
print(MyFlag2.__or__.__qualname__)  # MyFlag2.__or__ - GOOD

https://github.com/python/cpython/blob/089835469d5efbea4793cd611b43cb8387f2e7e5/Lib/enum.py#L610-L619

pygeek commented 2 days ago

super().__or__()

gswifort commented 2 days ago

super().__or__()

Yes, it is a workaround, but I use mixins so as not to add the method in all derived classes. It's easier to add them in __init_subclass__:

class Mixin:

    def __or__(self, value): ...

    def __init_subclass__(cls) -> None:
        setattr(cls, "__or__", Mixin.__or__)