You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hopefully I'm not misunderstanding something major about substitutions here, please let me know if I am.
I'm attempting to set a parameter value with a substitution that returns a list of strings.
Everything is fine if I set the parameter value with a normal list i.e: 'ingredients': ['apples', 'oranges', 'berries']. However, when I use a Substitution that returns the same list I get an error.
Simple test node that gets a string list parameter:
I expect the parameter to be set to the result of the substitution. In this case, a list of strings (in the example: ['berries', 'chocolate', 'grapes', 'apples', 'oranges']).
This feels like it should be in line with the description of possible parameter values in normalize_parameters.py
Actual behavior
It seems like it's being treated as a list of substitutions:
def perform_substitutions(context: LaunchContext, subs: List[Substitution]) -> Text:
"""Resolve a list of Substitutions with a context into a single string."""
return ''.join([context.perform_substitution(sub) for sub in subs])
Which results in: TypeError: sequence item 0: expected str instance, list found
However this is just a single substitution. It would be great if it wasn't treated as a list of them.
Full stacktrace:
[DEBUG] [launch]: An exception was raised in an async action/event
[DEBUG] [launch]: Traceback (most recent call last):
File "/home/frivold/kef_env/warm_dep_ws/build/launch/launch/launch_service.py", line 336, in run_async
raise completed_tasks_exceptions[0]
File "/home/frivold/kef_env/warm_dep_ws/build/launch/launch/launch_service.py", line 230, in _process_one_event
await self.__process_event(next_event)
File "/home/frivold/kef_env/warm_dep_ws/build/launch/launch/launch_service.py", line 250, in __process_event
visit_all_entities_and_collect_futures(entity, self.__context))
File "/home/frivold/kef_env/warm_dep_ws/build/launch/launch/utilities/visit_all_entities_and_collect_futures_impl.py", line 45, in visit_all_entities_and_collect_futures
futures_to_return += visit_all_entities_and_collect_futures(sub_entity, context)
File "/home/frivold/kef_env/warm_dep_ws/build/launch/launch/utilities/visit_all_entities_and_collect_futures_impl.py", line 45, in visit_all_entities_and_collect_futures
futures_to_return += visit_all_entities_and_collect_futures(sub_entity, context)
File "/home/frivold/kef_env/warm_dep_ws/build/launch/launch/utilities/visit_all_entities_and_collect_futures_impl.py", line 45, in visit_all_entities_and_collect_futures
futures_to_return += visit_all_entities_and_collect_futures(sub_entity, context)
[Previous line repeated 1 more time]
File "/home/frivold/kef_env/warm_dep_ws/build/launch/launch/utilities/visit_all_entities_and_collect_futures_impl.py", line 38, in visit_all_entities_and_collect_futures
sub_entities = entity.visit(context)
File "/home/frivold/kef_env/warm_dep_ws/build/launch/launch/action.py", line 108, in visit
return self.execute(context)
File "/home/frivold/kef_env/warm_dep_ws/build/launch_ros/launch_ros/actions/node.py", line 490, in execute
self._perform_substitutions(context)
File "/home/frivold/kef_env/warm_dep_ws/build/launch_ros/launch_ros/actions/node.py", line 445, in _perform_substitutions
evaluated_parameters = evaluate_parameters(context, self.__parameters)
File "/home/frivold/kef_env/warm_dep_ws/build/launch_ros/launch_ros/utilities/evaluate_parameters.py", line 178, in evaluate_parameters
output_params.append(evaluate_parameter_dict(context, param))
File "/home/frivold/kef_env/warm_dep_ws/build/launch_ros/launch_ros/utilities/evaluate_parameters.py", line 72, in evaluate_parameter_dict
evaluated_value = perform_substitutions(context, list(value))
File "/home/frivold/kef_env/warm_dep_ws/build/launch/launch/utilities/perform_substitutions_impl.py", line 26, in perform_substitutions
return ''.join([context.perform_substitution(sub) for sub in subs])
TypeError: sequence item 0: expected str instance, list found
[ERROR] [launch]: Caught exception in launch (see debug for traceback): sequence item 0: expected str instance, list found
Additional information
I was able to hack my way around this by adding a ListSubstitution type to launch/substitutions, and modifying evaluate_parameters.py to check for a ListSubstitution.
if isinstance(value, tuple) and len(value):
if len(value) == 1 and isinstance(value[0], ListSubstitution):
evaluated_value = value[0].perform(context)
elif isinstance(value[0], Substitution):
# Value is a list of substitutions, so perform them to make a string
evaluated_value = perform_substitutions(context, list(value))
But I don't really know my way around the launch / launch_ros codebase, so I'm not sure that's a very clean solution.
The text was updated successfully, but these errors were encountered:
I now realize that I can work around this issue by having the substitution return a string with the list specified in yaml format.
Would still be nice to be able to use a singular substitution that returns a non-string.
I'm also having the same traceback on Humble and workedaround it for the moment. I haven't yet pinpointed where the issue comes from to create a minimal reproducible example, I'll try to find some time for it
Bug report
Required Info:
Steps to reproduce issue
Hopefully I'm not misunderstanding something major about substitutions here, please let me know if I am.
I'm attempting to set a parameter value with a substitution that returns a list of strings.
Everything is fine if I set the parameter value with a normal list i.e:
'ingredients': ['apples', 'oranges', 'berries']
. However, when I use a Substitution that returns the same list I get an error.Simple test node that gets a string list parameter:
Launch file example:
Expected behavior
I expect the parameter to be set to the result of the substitution. In this case, a list of strings (in the example: ['berries', 'chocolate', 'grapes', 'apples', 'oranges']).
This feels like it should be in line with the description of possible parameter values in normalize_parameters.py
Actual behavior
It seems like it's being treated as a list of substitutions:
launch_ros/launch_ros/launch_ros/utilities/evaluate_parameters.py
Lines 69 to 72 in bc60978
And therefore an attempt is made to convert it into a string:
https://github.com/ros2/launch/blob/dd6ab0edf19c2f35b8e71aa8151df50b8a2feff9/launch/launch/utilities/perform_substitutions_impl.py#L24-L26
Which results in:
TypeError: sequence item 0: expected str instance, list found
However this is just a single substitution. It would be great if it wasn't treated as a list of them.
Full stacktrace:
Additional information
I was able to hack my way around this by adding a ListSubstitution type to launch/substitutions, and modifying evaluate_parameters.py to check for a ListSubstitution.
But I don't really know my way around the launch / launch_ros codebase, so I'm not sure that's a very clean solution.
The text was updated successfully, but these errors were encountered: