Skip to content

Commit

Permalink
Make t.uint_t-based IntFlag enums compatible with 3.8.6 (#507)
Browse files Browse the repository at this point in the history
  • Loading branch information
puddly committed Sep 30, 2020
1 parent d83e55b commit a1010cb
Showing 1 changed file with 32 additions and 27 deletions.
59 changes: 32 additions & 27 deletions zigpy/types/basic.py
Expand Up @@ -129,25 +129,6 @@ class uint64_t(uint_t, size=8):
pass


class EnumIntFlagMixin:
"""
Enum does not allow multiple base classes. We turn enum.IntFlag into a mixin because
it doesn't actualy depend on the base class specifically being `int`.
"""

# Rebind classmethods to our own class
_missing_ = classmethod(enum.IntFlag._missing_.__func__)
_create_pseudo_member_ = classmethod(enum.IntFlag._create_pseudo_member_.__func__)

__or__ = enum.IntFlag.__or__
__and__ = enum.IntFlag.__and__
__xor__ = enum.IntFlag.__xor__
__ror__ = enum.IntFlag.__ror__
__rand__ = enum.IntFlag.__rand__
__rxor__ = enum.IntFlag.__rxor__
__invert__ = enum.IntFlag.__invert__


class _IntEnumMeta(enum.EnumMeta):
def __call__(cls, value, names=None, *args, **kwargs):
if isinstance(value, str) and value.startswith("0x"):
Expand All @@ -157,6 +138,30 @@ def __call__(cls, value, names=None, *args, **kwargs):
return super().__call__(value, names, *args, **kwargs)


def bitmap_factory(int_type: CALLABLE_T) -> CALLABLE_T:
"""
Mixins are broken by Python 3.8.6 so we must dynamically create the enum with the
appropriate methods but with only one non-Enum parent class.
"""

class _NewEnum(int_type, enum.Flag):
# Rebind classmethods to our own class
_missing_ = classmethod(enum.IntFlag._missing_.__func__)
_create_pseudo_member_ = classmethod(
enum.IntFlag._create_pseudo_member_.__func__
)

__or__ = enum.IntFlag.__or__
__and__ = enum.IntFlag.__and__
__xor__ = enum.IntFlag.__xor__
__ror__ = enum.IntFlag.__ror__
__rand__ = enum.IntFlag.__rand__
__rxor__ = enum.IntFlag.__rxor__
__invert__ = enum.IntFlag.__invert__

return _NewEnum


def enum_factory(int_type: CALLABLE_T, undefined: str = "undefined") -> CALLABLE_T:
"""Enum factory."""

Expand All @@ -180,35 +185,35 @@ class enum16(enum_factory(uint16_t)): # noqa: N801
pass


class bitmap8(EnumIntFlagMixin, uint8_t, enum.Flag):
class bitmap8(bitmap_factory(uint8_t)):
pass


class bitmap16(EnumIntFlagMixin, uint16_t, enum.Flag):
class bitmap16(bitmap_factory(uint16_t)):
pass


class bitmap24(EnumIntFlagMixin, uint24_t, enum.Flag):
class bitmap24(bitmap_factory(uint24_t)):
pass


class bitmap32(EnumIntFlagMixin, uint32_t, enum.Flag):
class bitmap32(bitmap_factory(uint32_t)):
pass


class bitmap40(EnumIntFlagMixin, uint40_t, enum.Flag):
class bitmap40(bitmap_factory(uint40_t)):
pass


class bitmap48(EnumIntFlagMixin, uint48_t, enum.Flag):
class bitmap48(bitmap_factory(uint48_t)):
pass


class bitmap56(EnumIntFlagMixin, uint56_t, enum.Flag):
class bitmap56(bitmap_factory(uint56_t)):
pass


class bitmap64(EnumIntFlagMixin, uint64_t, enum.Flag):
class bitmap64(bitmap_factory(uint64_t)):
pass


Expand Down

0 comments on commit a1010cb

Please sign in to comment.