forked from auracaster/bumble_mirror
python 3.9 and 3.10 compatibility
This commit is contained in:
@@ -468,7 +468,7 @@ BT_HDP_SINK_SERVICE = UUID.from_16_bits(0x1402,
|
|||||||
@dataclasses.dataclass
|
@dataclasses.dataclass
|
||||||
class ClassOfDevice:
|
class ClassOfDevice:
|
||||||
# fmt: off
|
# fmt: off
|
||||||
class MajorServiceClasses(enum.IntFlag):
|
class MajorServiceClasses(utils.CompatibleIntFlag):
|
||||||
LIMITED_DISCOVERABLE_MODE = (1 << 0)
|
LIMITED_DISCOVERABLE_MODE = (1 << 0)
|
||||||
LE_AUDIO = (1 << 1)
|
LE_AUDIO = (1 << 1)
|
||||||
POSITIONING = (1 << 3)
|
POSITIONING = (1 << 3)
|
||||||
@@ -1647,7 +1647,7 @@ class AdvertisingData:
|
|||||||
THREE_D_INFORMATION_DATA = 0x3D
|
THREE_D_INFORMATION_DATA = 0x3D
|
||||||
MANUFACTURER_SPECIFIC_DATA = 0xFF
|
MANUFACTURER_SPECIFIC_DATA = 0xFF
|
||||||
|
|
||||||
class Flags(enum.IntFlag):
|
class Flags(utils.CompatibleIntFlag):
|
||||||
LE_LIMITED_DISCOVERABLE_MODE = 1 << 0
|
LE_LIMITED_DISCOVERABLE_MODE = 1 << 0
|
||||||
LE_GENERAL_DISCOVERABLE_MODE = 1 << 1
|
LE_GENERAL_DISCOVERABLE_MODE = 1 << 1
|
||||||
BR_EDR_NOT_SUPPORTED = 1 << 2
|
BR_EDR_NOT_SUPPORTED = 1 << 2
|
||||||
@@ -2153,7 +2153,7 @@ class LeRole(enum.IntEnum):
|
|||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Security Manager OOB Flag
|
# Security Manager OOB Flag
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
class SecurityManagerOutOfBandFlag(enum.IntFlag):
|
class SecurityManagerOutOfBandFlag(utils.CompatibleIntFlag):
|
||||||
"""
|
"""
|
||||||
See Supplement to the Bluetooth Core Specification, Part A
|
See Supplement to the Bluetooth Core Specification, Part A
|
||||||
1.7 SECURITY MANAGER OUT OF BAND (OOB)
|
1.7 SECURITY MANAGER OUT OF BAND (OOB)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ from __future__ import annotations
|
|||||||
import dataclasses
|
import dataclasses
|
||||||
import math
|
import math
|
||||||
import struct
|
import struct
|
||||||
from typing import Any, ClassVar, Literal, Optional, TypeVar, Union, overload
|
from typing import Any, ClassVar, Sequence
|
||||||
|
|
||||||
from typing_extensions import Self
|
from typing_extensions import Self
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ class ListOfServiceUUIDs(core.DataType):
|
|||||||
"""Base class for complete or incomplete lists of UUIDs."""
|
"""Base class for complete or incomplete lists of UUIDs."""
|
||||||
|
|
||||||
_uuid_size: ClassVar[int] = 0
|
_uuid_size: ClassVar[int] = 0
|
||||||
uuids: list[core.UUID]
|
uuids: Sequence[core.UUID]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_bytes(cls, data: bytes) -> ListOfServiceUUIDs:
|
def from_bytes(cls, data: bytes) -> ListOfServiceUUIDs:
|
||||||
@@ -215,7 +215,7 @@ class Flags(int, core.DataType):
|
|||||||
return self.to_bytes(length=bytes_length, byteorder="little")
|
return self.to_bytes(length=bytes_length, byteorder="little")
|
||||||
|
|
||||||
def value_string(self) -> str:
|
def value_string(self) -> str:
|
||||||
return core.AdvertisingData.Flags(self).name or ""
|
return core.AdvertisingData.Flags(self).composite_name
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
@dataclasses.dataclass
|
||||||
@@ -293,6 +293,13 @@ class FixedSizeBytesDataType(bytes, core.DataType):
|
|||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return core.DataType.__str__(self)
|
return core.DataType.__str__(self)
|
||||||
|
|
||||||
|
def __bytes__(self) -> bytes: # pylint: disable=E0308
|
||||||
|
# Python < 3.11 compatibility (before 3.11, the byte class does not have
|
||||||
|
# a __bytes__ method).
|
||||||
|
# Concatenate with an empty string to perform a direct conversion without
|
||||||
|
# calling bytes() explicity, which may cause an infinite recursion.
|
||||||
|
return b"" + self
|
||||||
|
|
||||||
|
|
||||||
class ClassOfDevice(core.ClassOfDevice, core.DataType):
|
class ClassOfDevice(core.ClassOfDevice, core.DataType):
|
||||||
"""
|
"""
|
||||||
@@ -416,7 +423,7 @@ class SecurityManagerOutOfBandFlag(int, core.DataType):
|
|||||||
return core.DataType.__str__(self)
|
return core.DataType.__str__(self)
|
||||||
|
|
||||||
def value_string(self) -> str:
|
def value_string(self) -> str:
|
||||||
return core.SecurityManagerOutOfBandFlag(self).name or ""
|
return core.SecurityManagerOutOfBandFlag(self).composite_name
|
||||||
|
|
||||||
|
|
||||||
class SecurityManagerTKValue(FixedSizeBytesDataType):
|
class SecurityManagerTKValue(FixedSizeBytesDataType):
|
||||||
@@ -751,7 +758,7 @@ class LeSupportedFeatures(int, core.DataType):
|
|||||||
return self.to_bytes(length=bytes_length, byteorder="little")
|
return self.to_bytes(length=bytes_length, byteorder="little")
|
||||||
|
|
||||||
def value_string(self) -> str:
|
def value_string(self) -> str:
|
||||||
return hci.LeFeatureMask(self).name or ""
|
return hci.LeFeatureMask(self).composite_name
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
@dataclasses.dataclass
|
||||||
|
|||||||
@@ -1322,7 +1322,7 @@ class LeFeature(SpecableEnum):
|
|||||||
MONITORING_ADVERTISERS = 64
|
MONITORING_ADVERTISERS = 64
|
||||||
FRAME_SPACE_UPDATE = 65
|
FRAME_SPACE_UPDATE = 65
|
||||||
|
|
||||||
class LeFeatureMask(enum.IntFlag):
|
class LeFeatureMask(utils.CompatibleIntFlag):
|
||||||
LE_ENCRYPTION = 1 << LeFeature.LE_ENCRYPTION
|
LE_ENCRYPTION = 1 << LeFeature.LE_ENCRYPTION
|
||||||
CONNECTION_PARAMETERS_REQUEST_PROCEDURE = 1 << LeFeature.CONNECTION_PARAMETERS_REQUEST_PROCEDURE
|
CONNECTION_PARAMETERS_REQUEST_PROCEDURE = 1 << LeFeature.CONNECTION_PARAMETERS_REQUEST_PROCEDURE
|
||||||
EXTENDED_REJECT_INDICATION = 1 << LeFeature.EXTENDED_REJECT_INDICATION
|
EXTENDED_REJECT_INDICATION = 1 << LeFeature.EXTENDED_REJECT_INDICATION
|
||||||
@@ -1463,7 +1463,7 @@ class LmpFeature(SpecableEnum):
|
|||||||
SLOT_AVAILABILITY_MASK = 138
|
SLOT_AVAILABILITY_MASK = 138
|
||||||
TRAIN_NUDGING = 139
|
TRAIN_NUDGING = 139
|
||||||
|
|
||||||
class LmpFeatureMask(enum.IntFlag):
|
class LmpFeatureMask(utils.CompatibleIntFlag):
|
||||||
# Page 0 (Legacy LMP features)
|
# Page 0 (Legacy LMP features)
|
||||||
LMP_3_SLOT_PACKETS = (1 << LmpFeature.LMP_3_SLOT_PACKETS)
|
LMP_3_SLOT_PACKETS = (1 << LmpFeature.LMP_3_SLOT_PACKETS)
|
||||||
LMP_5_SLOT_PACKETS = (1 << LmpFeature.LMP_5_SLOT_PACKETS)
|
LMP_5_SLOT_PACKETS = (1 << LmpFeature.LMP_5_SLOT_PACKETS)
|
||||||
|
|||||||
@@ -500,6 +500,22 @@ class OpenIntEnum(enum.IntEnum):
|
|||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
class CompatibleIntFlag(enum.IntFlag):
|
||||||
|
"""
|
||||||
|
Subclass of `enum.IntFlag` with a `composite_name` property that behaves like the
|
||||||
|
`name` property of the `enum.IntFlag` implementation for python vesions >= 3.11
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def composite_name(self) -> str:
|
||||||
|
return '|'.join(
|
||||||
|
name
|
||||||
|
for flag in self.__class__
|
||||||
|
if self.value & flag.value and (name := flag.name) is not None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
class ByteSerializable(Protocol):
|
class ByteSerializable(Protocol):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user