Ruff: Add and fix UP rules

This commit is contained in:
Josh Wu
2026-01-01 03:07:06 +08:00
parent 8e28f4e159
commit 3f643de4c1
102 changed files with 922 additions and 999 deletions

View File

@@ -22,7 +22,6 @@ from __future__ import annotations
import logging
import struct
from dataclasses import dataclass
from typing import Optional
from bumble import utils
from bumble.att import ATT_Error
@@ -129,7 +128,7 @@ class AudioInputState:
mute: Mute = Mute.NOT_MUTED
gain_mode: GainMode = GainMode.MANUAL
change_counter: int = 0
attribute: Optional[Attribute] = None
attribute: Attribute | None = None
def __bytes__(self) -> bytes:
return bytes(
@@ -316,7 +315,7 @@ class AudioInputDescription:
'''
audio_input_description: str = "Bluetooth"
attribute: Optional[Attribute] = None
attribute: Attribute | None = None
def on_read(self, _connection: Connection) -> str:
return self.audio_input_description
@@ -339,11 +338,11 @@ class AICSService(TemplateService):
def __init__(
self,
audio_input_state: Optional[AudioInputState] = None,
gain_settings_properties: Optional[GainSettingsProperties] = None,
audio_input_state: AudioInputState | None = None,
gain_settings_properties: GainSettingsProperties | None = None,
audio_input_type: str = "local",
audio_input_status: Optional[AudioInputStatus] = None,
audio_input_description: Optional[AudioInputDescription] = None,
audio_input_status: AudioInputStatus | None = None,
audio_input_description: AudioInputDescription | None = None,
):
self.audio_input_state = (
AudioInputState() if audio_input_state is None else audio_input_state

View File

@@ -25,7 +25,7 @@ import asyncio
import dataclasses
import enum
import logging
from typing import Iterable, Optional, Union
from collections.abc import Iterable
from bumble import utils
from bumble.device import Peer
@@ -230,7 +230,7 @@ class AmsClient(utils.EventEmitter):
self.supported_commands = set()
@classmethod
async def for_peer(cls, peer: Peer) -> Optional[AmsClient]:
async def for_peer(cls, peer: Peer) -> AmsClient | None:
ams_proxy = await peer.discover_service_and_create_proxy(AmsProxy)
if ams_proxy is None:
return None
@@ -263,9 +263,7 @@ class AmsClient(utils.EventEmitter):
async def observe(
self,
entity: EntityId,
attributes: Iterable[
Union[PlayerAttributeId, QueueAttributeId, TrackAttributeId]
],
attributes: Iterable[PlayerAttributeId | QueueAttributeId | TrackAttributeId],
) -> None:
await self._ams_proxy.entity_update.write_value(
bytes([entity] + list(attributes)), with_response=True

View File

@@ -27,7 +27,7 @@ import datetime
import enum
import logging
import struct
from typing import Optional, Sequence, Union
from collections.abc import Sequence
from bumble import utils
from bumble.att import ATT_Error
@@ -116,7 +116,7 @@ class NotificationAttributeId(utils.OpenIntEnum):
@dataclasses.dataclass
class NotificationAttribute:
attribute_id: NotificationAttributeId
value: Union[str, int, datetime.datetime]
value: str | int | datetime.datetime
@dataclasses.dataclass
@@ -242,10 +242,10 @@ class AncsProxy(ProfileServiceProxy):
class AncsClient(utils.EventEmitter):
_expected_response_command_id: Optional[CommandId]
_expected_response_notification_uid: Optional[int]
_expected_response_app_identifier: Optional[str]
_expected_app_identifier: Optional[str]
_expected_response_command_id: CommandId | None
_expected_response_notification_uid: int | None
_expected_response_app_identifier: str | None
_expected_app_identifier: str | None
_expected_response_tuples: int
_response_accumulator: bytes
@@ -255,12 +255,12 @@ class AncsClient(utils.EventEmitter):
super().__init__()
self._ancs_proxy = ancs_proxy
self._command_semaphore = asyncio.Semaphore()
self._response: Optional[asyncio.Future] = None
self._response: asyncio.Future | None = None
self._reset_response()
self._started = False
@classmethod
async def for_peer(cls, peer: Peer) -> Optional[AncsClient]:
async def for_peer(cls, peer: Peer) -> AncsClient | None:
ancs_proxy = await peer.discover_service_and_create_proxy(AncsProxy)
if ancs_proxy is None:
return None
@@ -316,7 +316,7 @@ class AncsClient(utils.EventEmitter):
# Not enough data yet.
return
attributes: list[Union[NotificationAttribute, AppAttribute]] = []
attributes: list[NotificationAttribute | AppAttribute] = []
if command_id == CommandId.GET_NOTIFICATION_ATTRIBUTES:
(notification_uid,) = struct.unpack_from(
@@ -342,7 +342,7 @@ class AncsClient(utils.EventEmitter):
str_value = attribute_data[3 : 3 + attribute_data_length].decode(
"utf-8"
)
value: Union[str, int, datetime.datetime]
value: str | int | datetime.datetime
if attribute_id == NotificationAttributeId.MESSAGE_SIZE:
value = int(str_value)
elif attribute_id == NotificationAttributeId.DATE:
@@ -415,7 +415,7 @@ class AncsClient(utils.EventEmitter):
self,
notification_uid: int,
attributes: Sequence[
Union[NotificationAttributeId, tuple[NotificationAttributeId, int]]
NotificationAttributeId | tuple[NotificationAttributeId, int]
],
) -> list[NotificationAttribute]:
if not self._started:

View File

@@ -24,7 +24,7 @@ import logging
import struct
from collections.abc import Sequence
from dataclasses import dataclass, field
from typing import Any, Optional, TypeVar, Union
from typing import Any, TypeVar
from bumble import colors, device, gatt, gatt_client, hci, utils
from bumble.profiles import le_audio
@@ -49,7 +49,7 @@ class ASE_Operation:
classes: dict[int, type[ASE_Operation]] = {}
op_code: Opcode
name: str
fields: Optional[Sequence[Any]] = None
fields: Sequence[Any] | None = None
ase_id: Sequence[int]
class Opcode(enum.IntEnum):
@@ -278,7 +278,7 @@ class AseStateMachine(gatt.Characteristic):
EVENT_STATE_CHANGE = "state_change"
cis_link: Optional[device.CisLink] = None
cis_link: device.CisLink | None = None
# Additional parameters in CODEC_CONFIGURED State
preferred_framing = 0 # Unframed PDU supported
@@ -290,7 +290,7 @@ class AseStateMachine(gatt.Characteristic):
preferred_presentation_delay_min = 0
preferred_presentation_delay_max = 0
codec_id = hci.CodingFormat(hci.CodecID.LC3)
codec_specific_configuration: Union[CodecSpecificConfiguration, bytes] = b''
codec_specific_configuration: CodecSpecificConfiguration | bytes = b''
# Additional parameters in QOS_CONFIGURED State
cig_id = 0
@@ -610,7 +610,7 @@ class AudioStreamControlService(gatt.TemplateService):
ase_state_machines: dict[int, AseStateMachine]
ase_control_point: gatt.Characteristic[bytes]
_active_client: Optional[device.Connection] = None
_active_client: device.Connection | None = None
def __init__(
self,

View File

@@ -19,7 +19,8 @@
import enum
import logging
import struct
from typing import Any, Callable, Optional, Union
from collections.abc import Callable
from typing import Any
from bumble import data_types, gatt, gatt_client, l2cap, utils
from bumble.core import AdvertisingData
@@ -90,20 +91,20 @@ class AshaService(gatt.TemplateService):
EVENT_DISCONNECTED = "disconnected"
EVENT_VOLUME_CHANGED = "volume_changed"
audio_sink: Optional[Callable[[bytes], Any]]
active_codec: Optional[Codec] = None
audio_type: Optional[AudioType] = None
volume: Optional[int] = None
other_state: Optional[int] = None
connection: Optional[Connection] = None
audio_sink: Callable[[bytes], Any] | None
active_codec: Codec | None = None
audio_type: AudioType | None = None
volume: int | None = None
other_state: int | None = None
connection: Connection | None = None
def __init__(
self,
capability: int,
hisyncid: Union[list[int], bytes],
hisyncid: list[int] | bytes,
device: Device,
psm: int = 0,
audio_sink: Optional[Callable[[bytes], Any]] = None,
audio_sink: Callable[[bytes], Any] | None = None,
feature_map: int = FeatureMap.LE_COC_AUDIO_OUTPUT_STREAMING_SUPPORTED,
protocol_version: int = 0x01,
render_delay_milliseconds: int = 0,

View File

@@ -21,7 +21,8 @@ from __future__ import annotations
import dataclasses
import logging
import struct
from typing import ClassVar, Optional, Sequence
from collections.abc import Sequence
from typing import ClassVar
from bumble import core, device, gatt, gatt_adapters, gatt_client, hci, utils
@@ -351,7 +352,7 @@ class BroadcastAudioScanServiceProxy(gatt_client.ProfileServiceProxy):
broadcast_audio_scan_control_point: gatt_client.CharacteristicProxy[bytes]
broadcast_receive_states: list[
gatt_client.CharacteristicProxy[Optional[BroadcastReceiveState]]
gatt_client.CharacteristicProxy[BroadcastReceiveState | None]
]
def __init__(self, service_proxy: gatt_client.ServiceProxy):

View File

@@ -16,7 +16,6 @@
# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
from typing import Optional
from bumble.gatt import (
GATT_BATTERY_LEVEL_CHARACTERISTIC,
@@ -56,7 +55,7 @@ class BatteryService(TemplateService):
class BatteryServiceProxy(ProfileServiceProxy):
SERVICE_CLASS = BatteryService
battery_level: Optional[CharacteristicProxy[int]]
battery_level: CharacteristicProxy[int] | None
def __init__(self, service_proxy):
self.service_proxy = service_proxy

View File

@@ -20,7 +20,6 @@ from __future__ import annotations
import enum
import struct
from typing import Optional
from bumble import core, crypto, device, gatt, gatt_client
@@ -96,17 +95,17 @@ class CoordinatedSetIdentificationService(gatt.TemplateService):
set_identity_resolving_key: bytes
set_identity_resolving_key_characteristic: gatt.Characteristic[bytes]
coordinated_set_size_characteristic: Optional[gatt.Characteristic[bytes]] = None
set_member_lock_characteristic: Optional[gatt.Characteristic[bytes]] = None
set_member_rank_characteristic: Optional[gatt.Characteristic[bytes]] = None
coordinated_set_size_characteristic: gatt.Characteristic[bytes] | None = None
set_member_lock_characteristic: gatt.Characteristic[bytes] | None = None
set_member_rank_characteristic: gatt.Characteristic[bytes] | None = None
def __init__(
self,
set_identity_resolving_key: bytes,
set_identity_resolving_key_type: SirkType,
coordinated_set_size: Optional[int] = None,
set_member_lock: Optional[MemberLock] = None,
set_member_rank: Optional[int] = None,
coordinated_set_size: int | None = None,
set_member_lock: MemberLock | None = None,
set_member_rank: int | None = None,
) -> None:
if len(set_identity_resolving_key) != SET_IDENTITY_RESOLVING_KEY_LENGTH:
raise core.InvalidArgumentError(
@@ -198,9 +197,9 @@ class CoordinatedSetIdentificationProxy(gatt_client.ProfileServiceProxy):
SERVICE_CLASS = CoordinatedSetIdentificationService
set_identity_resolving_key: gatt_client.CharacteristicProxy[bytes]
coordinated_set_size: Optional[gatt_client.CharacteristicProxy[bytes]] = None
set_member_lock: Optional[gatt_client.CharacteristicProxy[bytes]] = None
set_member_rank: Optional[gatt_client.CharacteristicProxy[bytes]] = None
coordinated_set_size: gatt_client.CharacteristicProxy[bytes] | None = None
set_member_lock: gatt_client.CharacteristicProxy[bytes] | None = None
set_member_rank: gatt_client.CharacteristicProxy[bytes] | None = None
def __init__(self, service_proxy: gatt_client.ServiceProxy) -> None:
self.service_proxy = service_proxy

View File

@@ -17,7 +17,6 @@
# Imports
# -----------------------------------------------------------------------------
import struct
from typing import Optional
from bumble.gatt import (
GATT_DEVICE_INFORMATION_SERVICE,
@@ -54,14 +53,14 @@ class DeviceInformationService(TemplateService):
def __init__(
self,
manufacturer_name: Optional[str] = None,
model_number: Optional[str] = None,
serial_number: Optional[str] = None,
hardware_revision: Optional[str] = None,
firmware_revision: Optional[str] = None,
software_revision: Optional[str] = None,
system_id: Optional[tuple[int, int]] = None, # (OUI, Manufacturer ID)
ieee_regulatory_certification_data_list: Optional[bytes] = None,
manufacturer_name: str | None = None,
model_number: str | None = None,
serial_number: str | None = None,
hardware_revision: str | None = None,
firmware_revision: str | None = None,
software_revision: str | None = None,
system_id: tuple[int, int] | None = None, # (OUI, Manufacturer ID)
ieee_regulatory_certification_data_list: bytes | None = None,
# TODO: pnp_id
):
characteristics: list[Characteristic[bytes]] = [
@@ -109,14 +108,14 @@ class DeviceInformationService(TemplateService):
class DeviceInformationServiceProxy(ProfileServiceProxy):
SERVICE_CLASS = DeviceInformationService
manufacturer_name: Optional[CharacteristicProxy[str]]
model_number: Optional[CharacteristicProxy[str]]
serial_number: Optional[CharacteristicProxy[str]]
hardware_revision: Optional[CharacteristicProxy[str]]
firmware_revision: Optional[CharacteristicProxy[str]]
software_revision: Optional[CharacteristicProxy[str]]
system_id: Optional[CharacteristicProxy[tuple[int, int]]]
ieee_regulatory_certification_data_list: Optional[CharacteristicProxy[bytes]]
manufacturer_name: CharacteristicProxy[str] | None
model_number: CharacteristicProxy[str] | None
serial_number: CharacteristicProxy[str] | None
hardware_revision: CharacteristicProxy[str] | None
firmware_revision: CharacteristicProxy[str] | None
software_revision: CharacteristicProxy[str] | None
system_id: CharacteristicProxy[tuple[int, int]] | None
ieee_regulatory_certification_data_list: CharacteristicProxy[bytes] | None
def __init__(self, service_proxy: ServiceProxy):
self.service_proxy = service_proxy

View File

@@ -19,7 +19,6 @@
# -----------------------------------------------------------------------------
import logging
import struct
from typing import Optional, Union
from bumble.core import Appearance
from bumble.gatt import (
@@ -54,7 +53,7 @@ class GenericAccessService(TemplateService):
appearance_characteristic: Characteristic[bytes]
def __init__(
self, device_name: str, appearance: Union[Appearance, tuple[int, int], int] = 0
self, device_name: str, appearance: Appearance | tuple[int, int] | int = 0
):
if isinstance(appearance, int):
appearance_int = appearance
@@ -88,8 +87,8 @@ class GenericAccessService(TemplateService):
class GenericAccessServiceProxy(ProfileServiceProxy):
SERVICE_CLASS = GenericAccessService
device_name: Optional[CharacteristicProxy[str]]
appearance: Optional[CharacteristicProxy[Appearance]]
device_name: CharacteristicProxy[str] | None
appearance: CharacteristicProxy[Appearance] | None
def __init__(self, service_proxy: ServiceProxy):
self.service_proxy = service_proxy

View File

@@ -19,7 +19,6 @@
# -----------------------------------------------------------------------------
import struct
from enum import IntFlag
from typing import Optional
from bumble.gatt import (
GATT_BGR_FEATURES_CHARACTERISTIC,
@@ -77,18 +76,18 @@ class GamingAudioService(TemplateService):
UUID = GATT_GAMING_AUDIO_SERVICE
gmap_role: Characteristic
ugg_features: Optional[Characteristic] = None
ugt_features: Optional[Characteristic] = None
bgs_features: Optional[Characteristic] = None
bgr_features: Optional[Characteristic] = None
ugg_features: Characteristic | None = None
ugt_features: Characteristic | None = None
bgs_features: Characteristic | None = None
bgr_features: Characteristic | None = None
def __init__(
self,
gmap_role: GmapRole,
ugg_features: Optional[UggFeatures] = None,
ugt_features: Optional[UgtFeatures] = None,
bgs_features: Optional[BgsFeatures] = None,
bgr_features: Optional[BgrFeatures] = None,
ugg_features: UggFeatures | None = None,
ugt_features: UgtFeatures | None = None,
bgs_features: BgsFeatures | None = None,
bgr_features: BgrFeatures | None = None,
) -> None:
characteristics = []
@@ -150,10 +149,10 @@ class GamingAudioService(TemplateService):
class GamingAudioServiceProxy(ProfileServiceProxy):
SERVICE_CLASS = GamingAudioService
ugg_features: Optional[CharacteristicProxy[UggFeatures]] = None
ugt_features: Optional[CharacteristicProxy[UgtFeatures]] = None
bgs_features: Optional[CharacteristicProxy[BgsFeatures]] = None
bgr_features: Optional[CharacteristicProxy[BgrFeatures]] = None
ugg_features: CharacteristicProxy[UggFeatures] | None = None
ugt_features: CharacteristicProxy[UgtFeatures] | None = None
bgs_features: CharacteristicProxy[BgsFeatures] | None = None
bgr_features: CharacteristicProxy[BgrFeatures] | None = None
def __init__(self, service_proxy: ServiceProxy) -> None:
self.service_proxy = service_proxy

View File

@@ -20,7 +20,7 @@ from __future__ import annotations
import asyncio
import logging
from dataclasses import dataclass, field
from typing import Any, Optional, Union
from typing import Any
from bumble import att, gatt, gatt_adapters, gatt_client, utils
from bumble.core import InvalidArgumentError, InvalidStateError
@@ -145,7 +145,7 @@ class PresetChangedOperation:
return bytes([self.prev_index]) + bytes(self.preset_record)
change_id: ChangeId
additional_parameters: Union[Generic, int]
additional_parameters: Generic | int
def to_bytes(self, is_last: bool) -> bytes:
if isinstance(self.additional_parameters, PresetChangedOperation.Generic):
@@ -235,7 +235,7 @@ class HearingAccessService(gatt.TemplateService):
preset_records: dict[int, PresetRecord] # key is the preset index
read_presets_request_in_progress: bool
other_server_in_binaural_set: Optional[HearingAccessService] = None
other_server_in_binaural_set: HearingAccessService | None = None
preset_changed_operations_history_per_device: dict[
Address, list[PresetChangedOperation]

View File

@@ -20,7 +20,6 @@ from __future__ import annotations
import struct
from enum import IntEnum
from typing import Optional
from bumble import core
from bumble.att import ATT_Error
@@ -207,13 +206,13 @@ class HeartRateService(TemplateService):
class HeartRateServiceProxy(ProfileServiceProxy):
SERVICE_CLASS = HeartRateService
heart_rate_measurement: Optional[
CharacteristicProxy[HeartRateService.HeartRateMeasurement]
]
body_sensor_location: Optional[
CharacteristicProxy[HeartRateService.BodySensorLocation]
]
heart_rate_control_point: Optional[CharacteristicProxy[int]]
heart_rate_measurement: (
CharacteristicProxy[HeartRateService.HeartRateMeasurement] | None
)
body_sensor_location: (
CharacteristicProxy[HeartRateService.BodySensorLocation] | None
)
heart_rate_control_point: CharacteristicProxy[int] | None
def __init__(self, service_proxy):
self.service_proxy = service_proxy

View File

@@ -22,7 +22,7 @@ import asyncio
import dataclasses
import enum
import struct
from typing import TYPE_CHECKING, ClassVar, Optional
from typing import TYPE_CHECKING, ClassVar
from typing_extensions import Self
@@ -196,7 +196,7 @@ class MediaControlService(gatt.TemplateService):
UUID = gatt.GATT_MEDIA_CONTROL_SERVICE
def __init__(self, media_player_name: Optional[str] = None) -> None:
def __init__(self, media_player_name: str | None = None) -> None:
self.track_position = 0
self.media_player_name_characteristic = gatt.Characteristic(
@@ -337,32 +337,32 @@ class MediaControlServiceProxy(
EVENT_TRACK_DURATION = "track_duration"
EVENT_TRACK_POSITION = "track_position"
media_player_name: Optional[gatt_client.CharacteristicProxy[bytes]] = None
media_player_icon_object_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
media_player_icon_url: Optional[gatt_client.CharacteristicProxy[bytes]] = None
track_changed: Optional[gatt_client.CharacteristicProxy[bytes]] = None
track_title: Optional[gatt_client.CharacteristicProxy[bytes]] = None
track_duration: Optional[gatt_client.CharacteristicProxy[bytes]] = None
track_position: Optional[gatt_client.CharacteristicProxy[bytes]] = None
playback_speed: Optional[gatt_client.CharacteristicProxy[bytes]] = None
seeking_speed: Optional[gatt_client.CharacteristicProxy[bytes]] = None
current_track_segments_object_id: Optional[
gatt_client.CharacteristicProxy[bytes]
] = None
current_track_object_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
next_track_object_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
parent_group_object_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
current_group_object_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
playing_order: Optional[gatt_client.CharacteristicProxy[bytes]] = None
playing_orders_supported: Optional[gatt_client.CharacteristicProxy[bytes]] = None
media_state: Optional[gatt_client.CharacteristicProxy[bytes]] = None
media_control_point: Optional[gatt_client.CharacteristicProxy[bytes]] = None
media_control_point_opcodes_supported: Optional[
gatt_client.CharacteristicProxy[bytes]
] = None
search_control_point: Optional[gatt_client.CharacteristicProxy[bytes]] = None
search_results_object_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
content_control_id: Optional[gatt_client.CharacteristicProxy[bytes]] = None
media_player_name: gatt_client.CharacteristicProxy[bytes] | None = None
media_player_icon_object_id: gatt_client.CharacteristicProxy[bytes] | None = None
media_player_icon_url: gatt_client.CharacteristicProxy[bytes] | None = None
track_changed: gatt_client.CharacteristicProxy[bytes] | None = None
track_title: gatt_client.CharacteristicProxy[bytes] | None = None
track_duration: gatt_client.CharacteristicProxy[bytes] | None = None
track_position: gatt_client.CharacteristicProxy[bytes] | None = None
playback_speed: gatt_client.CharacteristicProxy[bytes] | None = None
seeking_speed: gatt_client.CharacteristicProxy[bytes] | None = None
current_track_segments_object_id: gatt_client.CharacteristicProxy[bytes] | None = (
None
)
current_track_object_id: gatt_client.CharacteristicProxy[bytes] | None = None
next_track_object_id: gatt_client.CharacteristicProxy[bytes] | None = None
parent_group_object_id: gatt_client.CharacteristicProxy[bytes] | None = None
current_group_object_id: gatt_client.CharacteristicProxy[bytes] | None = None
playing_order: gatt_client.CharacteristicProxy[bytes] | None = None
playing_orders_supported: gatt_client.CharacteristicProxy[bytes] | None = None
media_state: gatt_client.CharacteristicProxy[bytes] | None = None
media_control_point: gatt_client.CharacteristicProxy[bytes] | None = None
media_control_point_opcodes_supported: (
gatt_client.CharacteristicProxy[bytes] | None
) = None
search_control_point: gatt_client.CharacteristicProxy[bytes] | None = None
search_results_object_id: gatt_client.CharacteristicProxy[bytes] | None = None
content_control_id: gatt_client.CharacteristicProxy[bytes] | None = None
if TYPE_CHECKING:
media_control_point_notifications: asyncio.Queue[bytes]

View File

@@ -21,7 +21,7 @@ from __future__ import annotations
import dataclasses
import logging
import struct
from typing import Optional, Sequence, Union
from collections.abc import Sequence
from bumble import gatt, gatt_adapters, gatt_client, hci
from bumble.profiles import le_audio
@@ -39,7 +39,7 @@ class PacRecord:
'''Published Audio Capabilities Service, Table 3.2/3.4.'''
coding_format: hci.CodingFormat
codec_specific_capabilities: Union[CodecSpecificCapabilities, bytes]
codec_specific_capabilities: CodecSpecificCapabilities | bytes
metadata: le_audio.Metadata = dataclasses.field(default_factory=le_audio.Metadata)
@classmethod
@@ -56,7 +56,7 @@ class PacRecord:
offset += 1
metadata = le_audio.Metadata.from_bytes(data[offset : offset + metadata_size])
codec_specific_capabilities: Union[CodecSpecificCapabilities, bytes]
codec_specific_capabilities: CodecSpecificCapabilities | bytes
if coding_format.codec_id == hci.CodecID.VENDOR_SPECIFIC:
codec_specific_capabilities = codec_specific_capabilities_bytes
else:
@@ -101,10 +101,10 @@ class PacRecord:
class PublishedAudioCapabilitiesService(gatt.TemplateService):
UUID = gatt.GATT_PUBLISHED_AUDIO_CAPABILITIES_SERVICE
sink_pac: Optional[gatt.Characteristic[bytes]]
sink_audio_locations: Optional[gatt.Characteristic[bytes]]
source_pac: Optional[gatt.Characteristic[bytes]]
source_audio_locations: Optional[gatt.Characteristic[bytes]]
sink_pac: gatt.Characteristic[bytes] | None
sink_audio_locations: gatt.Characteristic[bytes] | None
source_pac: gatt.Characteristic[bytes] | None
source_audio_locations: gatt.Characteristic[bytes] | None
available_audio_contexts: gatt.Characteristic[bytes]
supported_audio_contexts: gatt.Characteristic[bytes]
@@ -115,9 +115,9 @@ class PublishedAudioCapabilitiesService(gatt.TemplateService):
available_source_context: ContextType,
available_sink_context: ContextType,
sink_pac: Sequence[PacRecord] = (),
sink_audio_locations: Optional[AudioLocation] = None,
sink_audio_locations: AudioLocation | None = None,
source_pac: Sequence[PacRecord] = (),
source_audio_locations: Optional[AudioLocation] = None,
source_audio_locations: AudioLocation | None = None,
) -> None:
characteristics = []
@@ -183,14 +183,10 @@ class PublishedAudioCapabilitiesService(gatt.TemplateService):
class PublishedAudioCapabilitiesServiceProxy(gatt_client.ProfileServiceProxy):
SERVICE_CLASS = PublishedAudioCapabilitiesService
sink_pac: Optional[gatt_client.CharacteristicProxy[list[PacRecord]]] = None
sink_audio_locations: Optional[gatt_client.CharacteristicProxy[AudioLocation]] = (
None
)
source_pac: Optional[gatt_client.CharacteristicProxy[list[PacRecord]]] = None
source_audio_locations: Optional[gatt_client.CharacteristicProxy[AudioLocation]] = (
None
)
sink_pac: gatt_client.CharacteristicProxy[list[PacRecord]] | None = None
sink_audio_locations: gatt_client.CharacteristicProxy[AudioLocation] | None = None
source_pac: gatt_client.CharacteristicProxy[list[PacRecord]] | None = None
source_audio_locations: gatt_client.CharacteristicProxy[AudioLocation] | None = None
available_audio_contexts: gatt_client.CharacteristicProxy[tuple[ContextType, ...]]
supported_audio_contexts: gatt_client.CharacteristicProxy[tuple[ContextType, ...]]

View File

@@ -20,7 +20,7 @@ from __future__ import annotations
import dataclasses
import enum
from typing import Sequence
from collections.abc import Sequence
from bumble import att, device, gatt, gatt_adapters, gatt_client

View File

@@ -18,7 +18,6 @@
# -----------------------------------------------------------------------------
import struct
from dataclasses import dataclass
from typing import Optional
from bumble import utils
from bumble.att import ATT_Error
@@ -69,7 +68,7 @@ class ErrorCode(utils.OpenIntEnum):
class VolumeOffsetState:
volume_offset: int = 0
change_counter: int = 0
attribute: Optional[Characteristic] = None
attribute: Characteristic | None = None
def __bytes__(self) -> bytes:
return struct.pack('<hB', self.volume_offset, self.change_counter)
@@ -93,7 +92,7 @@ class VolumeOffsetState:
@dataclass
class VocsAudioLocation:
audio_location: AudioLocation = AudioLocation.NOT_ALLOWED
attribute: Optional[Characteristic] = None
attribute: Characteristic | None = None
def __bytes__(self) -> bytes:
return struct.pack('<I', self.audio_location)
@@ -147,7 +146,7 @@ class VolumeOffsetControlPoint:
@dataclass
class AudioOutputDescription:
audio_output_description: str = ''
attribute: Optional[Characteristic] = None
attribute: Characteristic | None = None
@classmethod
def from_bytes(cls, data: bytes):
@@ -172,9 +171,9 @@ class VolumeOffsetControlService(TemplateService):
def __init__(
self,
volume_offset_state: Optional[VolumeOffsetState] = None,
audio_location: Optional[VocsAudioLocation] = None,
audio_output_description: Optional[AudioOutputDescription] = None,
volume_offset_state: VolumeOffsetState | None = None,
audio_location: VocsAudioLocation | None = None,
audio_output_description: AudioOutputDescription | None = None,
) -> None:
self.volume_offset_state = (
VolumeOffsetState() if volume_offset_state is None else volume_offset_state