From 8c9886672c11a20aeaf77f9320becef2a1f5d25e Mon Sep 17 00:00:00 2001 From: Immanuel Martini <35950815+martiniil@users.noreply.github.com> Date: Wed, 22 Dec 2021 22:05:44 +0100 Subject: [PATCH] Evaluate math symbols and functions in python expression (#557) (#562) * Evaluate math symbols and functions in python expression Signed-off-by: Immanuel Martini Co-authored-by: Jacob Perron --- launch/launch/substitutions/python_expression.py | 4 +++- launch/test/launch/frontend/test_substitutions.py | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/launch/launch/substitutions/python_expression.py b/launch/launch/substitutions/python_expression.py index a13a2449d..3ee4fe957 100644 --- a/launch/launch/substitutions/python_expression.py +++ b/launch/launch/substitutions/python_expression.py @@ -15,6 +15,7 @@ """Module for the PythonExpression substitution.""" import collections.abc +import math from typing import Iterable from typing import List from typing import Text @@ -33,6 +34,7 @@ class PythonExpression(Substitution): The expression may contain Substitutions, but must return something that can be converted to a string with `str()`. + It also may contain math symbols and functions. """ def __init__(self, expression: SomeSubstitutionsType) -> None: @@ -67,4 +69,4 @@ def describe(self) -> Text: def perform(self, context: LaunchContext) -> Text: """Perform the substitution by evaluating the expression.""" from ..utilities import perform_substitutions - return str(eval(perform_substitutions(context, self.expression))) + return str(eval(perform_substitutions(context, self.expression), {}, math.__dict__)) diff --git a/launch/test/launch/frontend/test_substitutions.py b/launch/test/launch/frontend/test_substitutions.py index aad0d5641..9fabbc6a9 100644 --- a/launch/test/launch/frontend/test_substitutions.py +++ b/launch/test/launch/frontend/test_substitutions.py @@ -205,6 +205,14 @@ def test_eval_subst(): assert 'asdbsd' == expr.perform(LaunchContext()) +def test_eval_subst_of_math_expr(): + subst = parse_substitution(r'$(eval "ceil(1.3)")') + assert len(subst) == 1 + expr = subst[0] + assert isinstance(expr, PythonExpression) + assert '2' == expr.perform(LaunchContext()) + + def expand_cmd_subs(cmd_subs: List[SomeSubstitutionsType]): return [perform_substitutions_without_context(x) for x in cmd_subs]