Source code for bluetooth_numbers.dicts

"""Module with specialized dictionary classes for UUIDs, CICs and OUIs."""
from __future__ import annotations

from typing import Dict, Union
from uuid import UUID

from bluetooth_numbers.exceptions import (
    No16BitIntegerError,
    NonStandardUUIDError,
    UnknownCICError,
    UnknownOUIError,
    UnknownUUIDError,
)
from bluetooth_numbers.utils import (
    is_normalized_oui,
    is_uint16,
    normalize_oui,
    uuid128_to_uuid16,
)


[docs]class CICDict(Dict[int, str]): """Dictionary class to hold 16-bit company codes and their names. You can use this class as a dict with the following differences: - If you check for a key that doesn't exist, this raises an :class:`~bluetooth_numbers.exceptions.UnknownCICError`. - If you check for a key that isn't a 16-bit unsigned integer, this raises a :class:`~bluetooth_numbers.exceptions.No16BitIntegerError`. Examples: >>> from bluetooth_numbers import company >>> company[0x004C] 'Apple, Inc.' >>> company[-1] Traceback (most recent call last): bluetooth_numbers.exceptions.No16BitIntegerError: -1 >>> company[65534] Traceback (most recent call last): bluetooth_numbers.exceptions.UnknownCICError: 65534 """ def __missing__(self, key: int) -> str: """Try the key and raise exception when it's invalid. Args: key (int): The key to check. Raises: No16BitIntegerError: If ``key`` isn't a 16-bit unsigned integer. UnknownCICError: If ``key`` isn't in this CICDict instance. """ if is_uint16(key): raise UnknownCICError(key) raise No16BitIntegerError(key)
[docs]class OUIDict(Dict[str, str]): """Dictionary class to hold OUIs and their names. You can use this class as a dict with the following differences: - You can check for an OUI in the formats "xx:yy:zz", "xx-yy-zz" or "xxyyzz". Both lowercase and uppercase letters are supported. - If you check for a key that doesn't exist, this raises an :class:`~bluetooth_numbers.exceptions.UnknownOUIError`. - If you check for a key that doesn't have one of the supported formats, this raises a :class:`~bluetooth_numbers.exceptions.WrongOUIFormatError`. Examples: >>> from bluetooth_numbers import oui >>> oui["98:E7:43"] 'Dell Inc.' >>> oui["c4-29-96"] 'Signify B.V.' >>> oui["A44519"] 'Xiaomi Communications Co Ltd' >>> oui["FOOBAR"] Traceback (most recent call last): bluetooth_numbers.exceptions.WrongOUIFormatError: 'FOOBAR' >>> oui["AB:CD:EF"] Traceback (most recent call last): bluetooth_numbers.exceptions.UnknownOUIError: AB:CD:EF """ def __missing__(self, key: str) -> str: """Try the key and raise exception when it's invalid. Args: key (str): The key to check. Raises: UnknownOUIError: If ``key`` isn't in this OUIDict instance. WrongOUIFormatError: If ``key`` doesn't have one of the supported formats. Returns: str: The name corresponding to ``key``. """ if is_normalized_oui(key): raise UnknownOUIError(key) return self[normalize_oui(key)]
[docs]class UUIDDict(Dict[Union[UUID, int], str]): """Dictionary class to hold 16-bit and 128-bit standard UUID keys and descriptions. You can use this class as a dict for Bluetooth UUIDs, with the following differences: - If you check for a 128-bit standard UUID and this UUID doesn't exist in the dictionary, it will check for the corresponding 16-bit UUID. - If you check for a UUID that doesn't exist, this raises an :class:`~bluetooth_numbers.exceptions.UnknownUUIDError`. - If you check for a key that isn't a 16-bit unsigned integer, this raises a :class:`~bluetooth_numbers.exceptions.No16BitIntegerError`. Examples: >>> from bluetooth_numbers import service >>> from uuid import UUID >>> service[UUID("0000180F-0000-1000-8000-00805F9B34FB")] 'Battery Service' >>> service[0x180F] 'Battery Service' >>> service[0] Traceback (most recent call last): bluetooth_numbers.exceptions.UnknownUUIDError: 0 >>> service[6.5] Traceback (most recent call last): bluetooth_numbers.exceptions.No16BitIntegerError: 6.5 """ def __missing__(self, key: UUID | int) -> str: """Try the key converted to 16-bit UUID. Args: key (UUID | int): The 128-bit or 16-bit UUID to check. Raises: No16BitIntegerError: If ``key`` isn't a 16-bit unsigned integer. UnknownUUIDError: If ``key`` isn't in this UUIDDict instance. Returns: str: The name corresponding to ``key``. """ if isinstance(key, UUID): try: return self[uuid128_to_uuid16(key)] except NonStandardUUIDError as error: raise UnknownUUIDError(key) from error elif is_uint16(key): raise UnknownUUIDError(key) raise No16BitIntegerError(key)