Coverage for custom_components/supernotify/common.py: 98%
50 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-21 23:31 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-21 23:31 +0000
1"""Miscellaneous helper functions.
3No dependencies permitted
4"""
6from dataclasses import dataclass, field
7from typing import Any
10def safe_get(probably_a_dict: dict[Any, Any] | None, key: Any, default: Any = None) -> Any:
11 probably_a_dict = probably_a_dict or {}
12 return probably_a_dict.get(key, default)
15def safe_extend(target: list[Any], extension: list[Any] | tuple[Any] | Any) -> list[Any]:
16 if target is None:
17 target = []
18 elif not isinstance(target, list):
19 target = [target]
20 if isinstance(extension, list | tuple):
21 target.extend(extension)
22 elif extension:
23 target.append(extension)
24 return target
27def ensure_list(v: Any) -> list[Any]:
28 if v is None:
29 return []
30 if isinstance(v, list):
31 return v
32 if isinstance(v, tuple):
33 return list(v)
34 return [v]
37def ensure_dict(v: Any, default: Any = None) -> dict[Any, Any]:
38 if v is None:
39 return {}
40 if isinstance(v, dict):
41 return v
42 if isinstance(v, set | list):
43 return dict.fromkeys(v, default)
44 return {v: default}
47@dataclass
48class CallRecord:
49 elapsed: float = field()
50 domain: str | None = field(default=None)
51 action: str | None = field(default=None)
52 action_data: dict[str, Any] | None = field(default=None)
53 target_data: dict[str, Any] | None = field(default=None)
54 exception: str | None = field(default=None)
55 debug: bool = field(default=False)
56 service_response: dict[str, Any] | None = field(default=None)
58 def contents(self) -> dict[str, Any]:
59 result = {
60 "domain": self.domain,
61 "action": self.action,
62 "action_data": self.action_data,
63 "elapsed": self.elapsed,
64 "debug": self.debug,
65 }
66 if self.target_data is not None:
67 result["target_data"] = self.target_data
68 if self.exception is not None:
69 result["exception"] = self.exception
70 if self.service_response is not None:
71 result["service_response"] = self.service_response
72 return result