Coverage for src / bluetooth_sig / gatt / descriptors / registry.py: 88%
33 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-18 11:17 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-18 11:17 +0000
1"""Descriptor registry and resolution."""
3from __future__ import annotations
5import logging
6from typing import ClassVar
8from ...types.uuid import BluetoothUUID
9from .base import BaseDescriptor
11logger = logging.getLogger(__name__)
14class DescriptorRegistry:
15 """Registry for descriptor classes."""
17 _registry: ClassVar[dict[str, type[BaseDescriptor]]] = {}
19 @classmethod
20 def register(cls, descriptor_class: type[BaseDescriptor]) -> None:
21 """Register a descriptor class."""
22 # Create an instance to resolve the UUID
23 try:
24 instance = descriptor_class()
25 uuid_str = str(instance.uuid)
26 cls._registry[uuid_str] = descriptor_class
27 except (ValueError, TypeError, AttributeError):
28 # If we can't create an instance or resolve UUID, skip registration
29 logger.warning("Failed to register descriptor class %s", descriptor_class.__name__)
31 @classmethod
32 def get_descriptor_class(cls, uuid: str | BluetoothUUID | int) -> type[BaseDescriptor] | None:
33 """Get descriptor class for UUID.
35 Args:
36 uuid: The descriptor UUID
38 Returns:
39 Descriptor class if found, None otherwise
41 Raises:
42 ValueError: If uuid format is invalid
43 """
44 # Convert to BluetoothUUID and use full form for lookup (let ValueError propagate)
45 uuid_obj = BluetoothUUID(uuid)
46 full_uuid_str = uuid_obj.dashed_form
47 return cls._registry.get(full_uuid_str)
49 @classmethod
50 def create_descriptor(cls, uuid: str | BluetoothUUID | int) -> BaseDescriptor | None:
51 """Create descriptor instance for UUID.
53 Args:
54 uuid: The descriptor UUID
56 Returns:
57 Descriptor instance if found, None otherwise
59 Raises:
60 ValueError: If uuid format is invalid
61 """
62 descriptor_class = cls.get_descriptor_class(uuid)
63 if descriptor_class:
64 try:
65 return descriptor_class()
66 except (ValueError, TypeError, AttributeError):
67 return None
68 return None
70 @classmethod
71 def list_registered_descriptors(cls) -> list[str]:
72 """List all registered descriptor UUIDs."""
73 return list(cls._registry.keys())