Home Assistant Unofficial Reference 2024.12.1
dumper.py
Go to the documentation of this file.
1 """Custom dumper and representers."""
2 
3 from collections import OrderedDict
4 from typing import Any
5 
6 import yaml
7 
8 from .objects import Input, NodeDictClass, NodeListClass, NodeStrClass
9 
10 # mypy: allow-untyped-calls, no-warn-return-any
11 
12 
13 try:
14  from yaml import CSafeDumper as FastestAvailableSafeDumper
15 except ImportError:
16  from yaml import ( # type: ignore[assignment]
17  SafeDumper as FastestAvailableSafeDumper,
18  )
19 
20 
21 def dump(_dict: dict | list) -> str:
22  """Dump YAML to a string and remove null."""
23  return yaml.dump(
24  _dict,
25  default_flow_style=False,
26  allow_unicode=True,
27  sort_keys=False,
28  Dumper=FastestAvailableSafeDumper,
29  ).replace(": null\n", ":\n")
30 
31 
32 def save_yaml(path: str, data: dict) -> None:
33  """Save YAML to a file."""
34  # Dump before writing to not truncate the file if dumping fails
35  str_data = dump(data)
36  with open(path, "w", encoding="utf-8") as outfile:
37  outfile.write(str_data)
38 
39 
40 # From: https://gist.github.com/miracle2k/3184458
41 def represent_odict( # type: ignore[no-untyped-def]
42  dumper, tag, mapping, flow_style=None
43 ) -> yaml.MappingNode:
44  """Like BaseRepresenter.represent_mapping but does not issue the sort()."""
45  value: list = []
46  node = yaml.MappingNode(tag, value, flow_style=flow_style)
47  if dumper.alias_key is not None:
48  dumper.represented_objects[dumper.alias_key] = node
49  best_style = True
50  if hasattr(mapping, "items"):
51  mapping = mapping.items()
52  for item_key, item_value in mapping:
53  node_key = dumper.represent_data(item_key)
54  node_value = dumper.represent_data(item_value)
55  if not (isinstance(node_key, yaml.ScalarNode) and not node_key.style):
56  best_style = False
57  if not (isinstance(node_value, yaml.ScalarNode) and not node_value.style):
58  best_style = False
59  value.append((node_key, node_value))
60  if flow_style is None:
61  if dumper.default_flow_style is not None:
62  node.flow_style = dumper.default_flow_style
63  else:
64  node.flow_style = best_style
65  return node
66 
67 
68 def add_representer(klass: Any, representer: Any) -> None:
69  """Add to representer to the dumper."""
70  FastestAvailableSafeDumper.add_representer(klass, representer)
71 
72 
74  OrderedDict,
75  lambda dumper, value: represent_odict(dumper, "tag:yaml.org,2002:map", value),
76 )
77 
79  NodeDictClass,
80  lambda dumper, value: represent_odict(dumper, "tag:yaml.org,2002:map", value),
81 )
82 
84  NodeListClass,
85  lambda dumper, value: dumper.represent_sequence("tag:yaml.org,2002:seq", value),
86 )
87 
89  NodeStrClass,
90  lambda dumper, value: dumper.represent_scalar("tag:yaml.org,2002:str", str(value)),
91 )
92 
94  Input,
95  lambda dumper, value: dumper.represent_scalar("!input", value.name),
96 )
None open(self, **Any kwargs)
Definition: lock.py:86
None add_representer(Any klass, Any representer)
Definition: dumper.py:68
str dump(dict|list _dict)
Definition: dumper.py:21
None save_yaml(str path, dict data)
Definition: dumper.py:32
yaml.MappingNode represent_odict(dumper, tag, mapping, flow_style=None)
Definition: dumper.py:43