Coverage for src / bluetooth_sig / registry / uuids / members.py: 85%

26 statements  

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

1"""Members registry for Bluetooth SIG member UUIDs.""" 

2 

3from __future__ import annotations 

4 

5from bluetooth_sig.registry.base import BaseUUIDRegistry 

6from bluetooth_sig.types.registry.member_uuids import MemberInfo 

7from bluetooth_sig.types.uuid import BluetoothUUID 

8 

9 

10class MembersRegistry(BaseUUIDRegistry[MemberInfo]): 

11 """Registry for Bluetooth SIG member company UUIDs.""" 

12 

13 def _load_yaml_path(self) -> str: 

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

15 return "assigned_numbers/uuids/member_uuids.yaml" 

16 

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

18 """Create MemberInfo from YAML data.""" 

19 return MemberInfo( 

20 uuid=uuid, 

21 name=uuid_data["name"], 

22 ) 

23 

24 def _create_runtime_info(self, entry: object, uuid: BluetoothUUID) -> MemberInfo: 

25 """Create runtime MemberInfo from entry.""" 

26 return MemberInfo( 

27 uuid=uuid, 

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

29 ) 

30 

31 def get_member_name(self, uuid: str | BluetoothUUID) -> str | None: 

32 """Get member company name by UUID. 

33 

34 Args: 

35 uuid: 16-bit UUID as string (with or without 0x), int, or BluetoothUUID 

36 

37 Returns: 

38 Member company name, or None if not found 

39 """ 

40 info = self.get_info(uuid) 

41 return info.name if info else None 

42 

43 def is_member_uuid(self, uuid: str | BluetoothUUID) -> bool: 

44 """Check if a UUID is a registered member company UUID. 

45 

46 Args: 

47 uuid: UUID to check 

48 

49 Returns: 

50 True if the UUID is a member UUID, False otherwise 

51 """ 

52 return self.get_info(uuid) is not None 

53 

54 def get_all_members(self) -> list[MemberInfo]: 

55 """Get all registered member companies. 

56 

57 Returns: 

58 List of all MemberInfo objects 

59 """ 

60 self._ensure_loaded() 

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

62 

63 def get_member_info_by_name(self, name: str) -> MemberInfo | None: 

64 """Get member information by company name. 

65 

66 Args: 

67 name: Company name (case-insensitive) 

68 

69 Returns: 

70 MemberInfo object, or None if not found 

71 """ 

72 self._ensure_loaded() 

73 for info in self._canonical_store.values(): 

74 if info.name.lower() == name.lower(): 

75 return info 

76 return None 

77 

78 

79# Global instance 

80members_registry = MembersRegistry.get_instance()