Skip to content

Commit

Permalink
Add to_string !eval tag (#9)
Browse files Browse the repository at this point in the history
Signed-off-by: Joni Pöllänen <[email protected]>
  • Loading branch information
jonipol authored Jul 25, 2024
1 parent 944113f commit 29d99c7
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 6 deletions.
5 changes: 4 additions & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,13 @@ Examples and tutorials can be found in link:examples[examples] folder.
|param_configuration.configuration.get_resolved_yaml
|Resolves the given YAML file and returns a path to it.

|!eval to_string()
|str()
|Converts the given value to a string. Handy when using nested evaluations.

|!eval var.<var_name>
|-
|Allows using variables which are defined in the beginning of the same file, under ".variables" -key. This key will be removed from the result file.

|===


Expand Down
19 changes: 14 additions & 5 deletions param_configuration/tags/eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,19 @@ def __getattr__(self, item, *args, **kwargs) -> Any:
return dict.get(item, *args, **kwargs)


def names(var: dict[str, Any]) -> dict[str, Any]:
"""Function proving additional variables for simple eval."""
def additional_names(var: dict[str, Any]) -> dict[str, Any]:
"""Function providing additional variables for simple eval."""
return {"env": os.environ, "m": math, "np": numpy, "var": Dotdict(var)}


def functions() -> dict[str, Any]:
def additional_functions() -> dict[str, Any]:
"""Function providing additional function for simple eval."""
return {
"path_to": get_package_share_directory,
"join": os.path.join,
"round": round,
"get_resolved_yaml": get_resolved_yaml,
"to_string": str,
}


Expand All @@ -71,8 +72,10 @@ def constructor(self, tag_value: str, file: str, loader: BaseConstructor) -> Any
self._vars = self.extract_variables(loader)

default_functions = simpleeval.DEFAULT_FUNCTIONS
default_functions.update(functions())
res = simpleeval.simple_eval(expr=tag_value, functions=default_functions, names=names(var=self._vars))
default_functions.update(additional_functions())
res = self.eval_with_compound_types(
tag_value, functions=default_functions, names=additional_names(var=self._vars)
)
return res

@staticmethod
Expand Down Expand Up @@ -103,6 +106,12 @@ def extract_variables(loader) -> dict:
variables |= var
return variables

@staticmethod
def eval_with_compound_types(tag_value: str, functions: dict[str, Any], names: dict[str, Any]) -> Any:
"""Evaluates the tag value with compound types."""
obj = simpleeval.EvalWithCompoundTypes(functions=functions, names=names)
return obj.eval(tag_value)


# Add the constructor.
Configuration().add_config_constructor(const=EvalConfigConstructor)
32 changes: 32 additions & 0 deletions test/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,38 @@ def test_eval_tag_from_string(yaml_string: str) -> None:
assert data_str == expected_str


def test_eval_round() -> None:
"""Test the !eval directive with the round function."""
yaml_string = """
round: !eval round(3.141592653589793, 2)
"""
expected_string = "round: 3.14"

configuration = Configuration()
data = configuration.load(yaml_string)
data_str = configuration.dump(data)
assert data_str == expected_string


def test_eval_to_string() -> None:
"""Test the !eval directive with the to_string function."""
yaml_string = """
float_to_string: !eval to_string(3.141592653589793)
array_to_string: !eval to_string([[1.0, 1.0], [2.0, 2.0]])
"""
# fmt: off
expected_string = (
"float_to_string: '3.141592653589793'\n"
"array_to_string: '[[1.0, 1.0], [2.0, 2.0]]'"
)
# fmt: on

configuration = Configuration()
data = configuration.load(yaml_string)
data_str = configuration.dump(data)
assert data_str == expected_string


def test_eval_small_numbers() -> None:
"""Test the loading and dumping !eval directive from a string."""
configuration = Configuration()
Expand Down

0 comments on commit 29d99c7

Please sign in to comment.