Coverage for src / bluetooth_sig / registry / uuids / service_classes.py: 92%

24 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-11 20:14 +0000

1"""Service classes registry for Bluetooth SIG service class UUIDs.""" 

2 

3from __future__ import annotations 

4 

5from bluetooth_sig.registry.base import BaseUUIDRegistry 

6from bluetooth_sig.types.registry.service_class import ServiceClassInfo 

7from bluetooth_sig.types.uuid import BluetoothUUID 

8 

9 

10class ServiceClassesRegistry(BaseUUIDRegistry[ServiceClassInfo]): 

11 """Registry for Bluetooth SIG service class definitions.""" 

12 

13 def _load_yaml_path(self) -> str: 

14 """Return the YAML file path relative to bluetooth_sig/ root.""" 

15 return "assigned_numbers/uuids/service_classes.yaml" 

16 

17 def _create_info_from_yaml(self, uuid_data: dict[str, str], uuid: BluetoothUUID) -> ServiceClassInfo: 

18 """Create ServiceClassInfo from YAML data.""" 

19 return ServiceClassInfo( 

20 uuid=uuid, 

21 name=uuid_data["name"], 

22 id=uuid_data["id"], 

23 ) 

24 

25 def _create_runtime_info(self, entry: object, uuid: BluetoothUUID) -> ServiceClassInfo: 

26 """Create runtime ServiceClassInfo from entry.""" 

27 return ServiceClassInfo( 

28 uuid=uuid, 

29 name=getattr(entry, "name", ""), 

30 id=getattr(entry, "id", ""), 

31 ) 

32 

33 def get_service_class_info(self, uuid: str | BluetoothUUID) -> ServiceClassInfo | None: 

34 """Get service class information by UUID. 

35 

36 Args: 

37 uuid: The UUID to look up (string, int, or BluetoothUUID) 

38 

39 Returns: 

40 ServiceClassInfo if found, None otherwise 

41 """ 

42 return self.get_info(uuid) 

43 

44 def get_service_class_info_by_name(self, name: str) -> ServiceClassInfo | None: 

45 """Get service class information by name (case insensitive). 

46 

47 Args: 

48 name: The service class name to look up 

49 

50 Returns: 

51 ServiceClassInfo if found, None otherwise 

52 """ 

53 return self.get_info(name) 

54 

55 def get_service_class_info_by_id(self, service_class_id: str) -> ServiceClassInfo | None: 

56 """Get service class information by service class ID. 

57 

58 Args: 

59 service_class_id: The service class ID to look up 

60 

61 Returns: 

62 ServiceClassInfo if found, None otherwise 

63 """ 

64 return self.get_info(service_class_id) 

65 

66 def is_service_class_uuid(self, uuid: str | BluetoothUUID) -> bool: 

67 """Check if a UUID corresponds to a known service class. 

68 

69 Args: 

70 uuid: The UUID to check 

71 

72 Returns: 

73 True if the UUID is a known service class, False otherwise 

74 """ 

75 return self.get_service_class_info(uuid) is not None 

76 

77 def get_all_service_classes(self) -> list[ServiceClassInfo]: 

78 """Get all service classes in the registry. 

79 

80 Returns: 

81 List of all ServiceClassInfo objects 

82 """ 

83 self._ensure_loaded() 

84 with self._lock: 

85 return list(self._canonical_store.values()) 

86 

87 

88# Global instance for convenience 

89service_classes_registry = ServiceClassesRegistry.get_instance()