Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions launch_ros/launch_ros/parameter_descriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def __init__(
self,
param_file: Union[FilePath, SomeSubstitutionsType],
*,
allow_substs: [bool, SomeSubstitutionsType] = False
allow_substs: Union[bool, SomeSubstitutionsType] = False
) -> None:
"""
Construct a parameter file description.
Expand All @@ -185,6 +185,8 @@ def __init__(
# during cleanup, so make sure to initialize them here.
self.__evaluated_param_file: Optional[Path] = None
self.__created_tmp_file = False
self.__allow_substs: Union[bool, List[Substitution]] = False
self.__evaluated_allow_substs: Optional[bool] = None

ensure_argument_type(
param_file,
Expand All @@ -194,15 +196,14 @@ def __init__(
)
ensure_argument_type(
allow_substs,
bool,
SomeSubstitutionsType_types_tuple + (bool,),
'allow_subst',
'ParameterFile()'
)
self.__param_file: Union[List[Substitution], FilePath] = param_file
if isinstance(param_file, SomeSubstitutionsType_types_tuple):
self.__param_file = normalize_to_list_of_substitutions(param_file)
self.__allow_substs = normalize_typed_substitution(allow_substs, data_type=bool)
self.__evaluated_allow_substs: Optional[bool] = None

@property
def param_file(self) -> Union[FilePath, List[Substitution]]:
Expand Down Expand Up @@ -249,6 +250,7 @@ def evaluate(self, context: LaunchContext) -> Path:
h.write(parsed)
param_file_path = Path(h.name)
self.__created_tmp_file = True
self.__evaluated_allow_substs = allow_substs
self.__evaluated_param_file = param_file_path
return param_file_path

Expand All @@ -259,7 +261,12 @@ def cleanup(self):
os.unlink(self.__evaluated_param_file)
except FileNotFoundError:
pass
self.__created_tmp_file = False
self.__evaluated_param_file = None
self.__evaluated_allow_substs = None
elif isinstance(self.__allow_substs, list):
self.__evaluated_param_file = None
self.__evaluated_allow_substs = None

def __del__(self):
self.cleanup()
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"""Tests for launch_ros.descriptions.ParameterFile."""

from contextlib import contextmanager
import gc
import os
import sys
from tempfile import NamedTemporaryFile

from launch import Substitution
Expand Down Expand Up @@ -52,6 +54,9 @@ def __init__(self, text):
def perform(self, context):
return self.__text

def set_text(self, text):
self.__text = text


@expose_substitution('test')
def parse_test_substitution(data):
Expand Down Expand Up @@ -136,3 +141,53 @@ def test_parameter_file_description(original_contents, expected_contents, allow_
else:
assert param_file.exists()
assert os.fspath(desc.param_file) == os.fspath(file_name)


def test_parameter_file_allow_substs_substitution():
lc = MockContext()
with get_parameter_file('{}') as file_name:
desc = ParameterFile(
file_name,
allow_substs=CustomSubstitution('true'),
)
assert isinstance(desc.allow_substs, list)
desc.evaluate(lc)
assert desc.allow_substs is True
desc.cleanup()
assert isinstance(desc.allow_substs, list)


def test_parameter_file_invalid_allow_substs_does_not_fail_cleanup():
unraisable = []
original_unraisablehook = sys.unraisablehook
sys.unraisablehook = unraisable.append
try:
with pytest.raises(TypeError, match='allow_subst'):
ParameterFile('params.yaml', allow_substs=object())
gc.collect()
finally:
sys.unraisablehook = original_unraisablehook

assert not unraisable


@pytest.mark.parametrize('first, second', [('false', 'true'), ('true', 'false')])
def test_parameter_file_allow_substs_re_evaluates_after_cleanup(first, second):
lc = MockContext()
allow_substs = CustomSubstitution(first)
with get_parameter_file('{}') as file_name:
desc = ParameterFile(file_name, allow_substs=allow_substs)

first_path = desc.evaluate(lc)
assert desc.allow_substs is (first == 'true')
assert (os.fspath(first_path) != file_name) is (first == 'true')
desc.cleanup()
assert os.path.exists(file_name)

allow_substs.set_text(second)
second_path = desc.evaluate(lc)
assert desc.allow_substs is (second == 'true')
assert (os.fspath(second_path) != file_name) is (second == 'true')
desc.cleanup()
assert os.path.exists(file_name)
assert isinstance(desc.allow_substs, list)
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def test_launch_frontend_xml():
<param name="param14" value="'2', '5', '8'" value-sep=", " type="list_of_str"/>
<param name="param15" value="2, 5, 8" value-sep=", " type="list_of_str"/>
</param>
<param from="{}"/>
<param from="{}" allow_substs="$(eval False)"/>
<env name="var" value="1"/>
<remap from="foo" to="bar"/>
<remap from="baz" to="foobar"/>
Expand Down Expand Up @@ -131,6 +131,7 @@ def test_launch_frontend_yaml():
value: ['2', '5', '8']
type: list_of_str
- from: {}
allow_substs: $(eval False)
env:
- name: var
value: '1'
Expand Down