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

1"""Miscellaneous helper functions. 

2 

3No dependencies permitted 

4""" 

5 

6from dataclasses import dataclass, field 

7from typing import Any 

8 

9 

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) 

13 

14 

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 

25 

26 

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] 

35 

36 

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} 

45 

46 

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) 

57 

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