15 from collections.abc
import Generator
17 from typing
import Optional, TypeAlias, Union
22 YamlValue: TypeAlias = Union[str, int, float, bool]
27 def __init__(self, dictionary: dict[str, YamlValue], key: str):
34 def setValue(self, value: YamlValue) ->
None:
40 Substitution that modifies the given YAML file.
47 source_file: launch.SomeSubstitutionsType,
48 param_rewrites: dict[str, launch.SomeSubstitutionsType],
49 root_key: Optional[launch.SomeSubstitutionsType] =
None,
50 key_rewrites: Optional[dict[str, launch.SomeSubstitutionsType]] =
None,
51 value_rewrites: Optional[dict[str, launch.SomeSubstitutionsType]] =
None,
52 convert_types: bool =
False,
53 out_dir: Optional[launch.SomeSubstitutionsType] =
None,
57 Construct the substitution
59 :param: source_file the original YAML file to modify
60 :param: param_rewrites mappings to replace
61 :param: root_key if provided, the contents are placed under this key
62 :param: key_rewrites keys of mappings to replace
63 :param: value_rewrites values to replace
64 :param: convert_types whether to attempt converting the string to a number or boolean
65 :param: out_dir if provided, the directory where the temporary YAML file will be created
69 from launch.utilities
import normalize_to_list_of_substitutions
71 self.__source_file: list[launch.Substitution] = \
72 normalize_to_list_of_substitutions(source_file)
80 for key
in param_rewrites:
81 self.
__param_rewrites__param_rewrites[key] = normalize_to_list_of_substitutions(
84 if key_rewrites
is not None:
85 for key
in key_rewrites:
86 self.
__key_rewrites__key_rewrites[key] = normalize_to_list_of_substitutions(
89 if value_rewrites
is not None:
90 for value
in value_rewrites:
91 self.
__value_rewrites__value_rewrites[value] = normalize_to_list_of_substitutions(
94 if root_key
is not None:
95 self.
__root_key__root_key = normalize_to_list_of_substitutions(root_key)
97 if out_dir
is not None:
98 self.
__out_dir__out_dir = normalize_to_list_of_substitutions(out_dir)
101 def name(self) -> list[launch.Substitution]:
102 """Getter for name."""
103 return self.__source_file
106 """Return a description of this substitution as a string."""
109 def perform(self, context: launch.LaunchContext) -> str:
110 yaml_filename = launch.utilities.perform_substitutions(context, self.
namename)
114 out_dir = launch.utilities.perform_substitutions(context, self.
__out_dir__out_dir)
116 rewritten_yaml = tempfile.NamedTemporaryFile(mode=
'w', delete=
False, dir=out_dir)
117 param_rewrites, keys_rewrites, value_rewrites = self.
resolve_rewritesresolve_rewrites(context)
119 with open(yaml_filename,
'r')
as yaml_file:
120 data = yaml.safe_load(yaml_file)
123 self.
add_paramsadd_params(data, param_rewrites)
127 root_key = launch.utilities.perform_substitutions(context, self.
__root_key__root_key)
129 data = {root_key: data}
130 yaml.dump(data, rewritten_yaml)
131 rewritten_yaml.close()
132 return rewritten_yaml.name
134 def resolve_rewrites(self, context: launch.LaunchContext) -> \
135 tuple[dict[str, str], dict[str, str], dict[str, str]]:
138 resolved_params[key] = launch.utilities.perform_substitutions(
143 resolved_keys[key] = launch.utilities.perform_substitutions(
148 resolved_values[value] = launch.utilities.perform_substitutions(
151 return resolved_params, resolved_keys, resolved_values
153 def substitute_params(self, yaml: dict[str, YamlValue],
154 param_rewrites: dict[str, str]) ->
None:
157 if key.key()
in param_rewrites:
158 raw_value = param_rewrites[key.key()]
159 key.setValue(self.
convertconvert(raw_value))
162 yaml_paths = self.
pathifypathify(yaml)
163 for path
in yaml_paths:
164 if path
in param_rewrites:
166 rewrite_val = self.
convertconvert(param_rewrites[path])
167 yaml_keys = path.split(
'.')
170 def add_params(self, yaml: dict[str, YamlValue],
171 param_rewrites: dict[str, str]) ->
None:
173 yaml_paths = self.
pathifypathify(yaml)
174 for path
in param_rewrites:
175 if not path
in yaml_paths:
176 new_val = self.
convertconvert(param_rewrites[path])
177 yaml_keys = path.split(
'.')
178 if 'ros__parameters' in yaml_keys:
181 def substitute_values(
182 self, yaml: dict[str, YamlValue],
183 value_rewrites: dict[str, str]) ->
None:
185 def process_value(value: YamlValue) -> YamlValue:
186 if isinstance(value, dict):
187 for k, v
in list(value.items()):
188 value[k] = process_value(v)
190 elif isinstance(value, list):
191 return [process_value(v)
for v
in value]
192 elif str(value)
in value_rewrites:
193 return self.
convertconvert(value_rewrites[str(value)])
196 for key
in list(yaml.keys()):
197 yaml[key] = process_value(yaml[key])
199 def updateYamlPathVals(
200 self, yaml: dict[str, YamlValue],
201 yaml_key_list: list[str], rewrite_val: YamlValue) -> dict[str, YamlValue]:
203 for key
in yaml_key_list:
204 if key == yaml_key_list[-1]:
205 yaml[key] = rewrite_val
207 key = yaml_key_list.pop(0)
208 if isinstance(yaml, list):
210 yaml[int(key)], yaml_key_list, rewrite_val
221 self, yaml: dict[str, YamlValue], key_rewrites: dict[str, str]) ->
None:
222 if len(key_rewrites) != 0:
223 for key
in list(yaml.keys()):
225 if key
in key_rewrites:
226 new_key = key_rewrites[key]
227 yaml[new_key] = yaml[key]
229 if isinstance(val, dict):
232 def getYamlLeafKeys(self, yamlData: dict[str, YamlValue]) -> \
233 Generator[DictItemReference,
None,
None]:
234 if not isinstance(yamlData, dict):
237 for key
in yamlData.keys():
238 child = yamlData[key]
240 if isinstance(child, dict):
247 self, d: Union[dict[str, YamlValue], list[YamlValue], YamlValue],
248 p: Optional[str] =
None,
249 paths: Optional[dict[str, YamlValue]] =
None,
250 joinchar: str =
'.') -> dict[str, YamlValue]:
253 self.
pathifypathify(d,
'', paths, joinchar=joinchar)
256 assert paths
is not None
260 if isinstance(d, dict):
263 self.
pathifypathify(v, str(pn) + str(k), paths, joinchar=joinchar)
264 elif isinstance(d, list):
265 for idx, e
in enumerate(d):
266 self.
pathifypathify(e, pn + str(idx), paths, joinchar=joinchar)
271 def convert(self, text_value: str) -> YamlValue:
275 return float(text_value)
if '.' in text_value
else int(text_value)
280 if text_value.lower() ==
'true':
282 if text_value.lower() ==
'false':
\ tuple[dict[str, str], dict[str, str], dict[str, str]] resolve_rewrites(self, launch.LaunchContext context)
\ Generator[DictItemReference, None, None] getYamlLeafKeys(self, dict[str, YamlValue] yamlData)
list[launch.Substitution] name(self)
None add_params(self, dict[str, YamlValue] yaml, dict[str, str] param_rewrites)
None substitute_params(self, dict[str, YamlValue] yaml, dict[str, str] param_rewrites)
YamlValue convert(self, str text_value)
None substitute_keys(self, dict[str, YamlValue] yaml, dict[str, str] key_rewrites)
dict[str, YamlValue] pathify(self, Union[dict[str, YamlValue], list[YamlValue], YamlValue] d, Optional[str] p=None, Optional[dict[str, YamlValue]] paths=None, str joinchar='.')
dict[str, YamlValue] updateYamlPathVals(self, dict[str, YamlValue] yaml, list[str] yaml_key_list, YamlValue rewrite_val)
None substitute_values(self, dict[str, YamlValue] yaml, dict[str, str] value_rewrites)