Skip to content

Commit da53e71

Browse files
Enable ros2service call to accept YAML input without escaping special characters
Signed-off-by: Leander Stephen D'Souza <leanderdsouza1234@gmail.com>
1 parent 767c794 commit da53e71

2 files changed

Lines changed: 19 additions & 3 deletions

File tree

ros2service/ros2service/api/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,5 @@ def __init__(self, *, service_type_key=None):
140140

141141
def __call__(self, prefix, parsed_args, **kwargs):
142142
service = get_service(getattr(parsed_args, self.service_type_key))
143-
return [message_to_yaml(service.Request())]
143+
yaml_snippet = "'" + message_to_yaml(service.Request()) + "'"
144+
return [yaml_snippet]

ros2service/ros2service/verb/call.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
import time
1616
from typing import Optional
1717

18+
import argcomplete
19+
1820
import rclpy
1921
from rclpy.qos import QoSPresetProfiles
2022
from rclpy.qos import QoSProfile
2123

22-
from ros2cli.helpers import collect_stdin
24+
from ros2cli.helpers import collect_stdin, UnescapedCompletionFinder
2325
from ros2cli.helpers import interactive_select
2426
from ros2cli.node import NODE_NAME_PREFIX
2527
from ros2cli.node.strategy import NodeStrategy
@@ -71,6 +73,10 @@ def add_arguments(self, parser, cli_name):
7173
'--timeout', metavar='N', type=float,
7274
help='Maximum time to wait for service response in seconds. '
7375
'If not specified, waits indefinitely.')
76+
77+
# Prevent argcomplete from escaping special characters in the YAML string
78+
argcomplete.autocomplete = UnescapedCompletionFinder(parser)
79+
7480
add_qos_arguments(parser, 'service client', 'services_default')
7581

7682
def main(self, *, args):
@@ -122,7 +128,16 @@ def requester(service_type: str, service_name: str, values, period: Optional[flo
122128
except (AttributeError, ModuleNotFoundError):
123129
raise RuntimeError('The passed service type is invalid')
124130

125-
values_dictionary = yaml.safe_load(values)
131+
try:
132+
# Handle cases where the user pastes the autocompleted bash safe string
133+
if '^J' in values:
134+
values = values.replace("'", '')
135+
values = values.replace('^J', '\n')
136+
137+
values_dictionary = yaml.safe_load(values)
138+
139+
except (yaml.parser.ParserError, yaml.scanner.ScannerError):
140+
return 'The passed value needs to be in YAML string or a dictionary'
126141

127142
with rclpy.init():
128143
node = rclpy.create_node(NODE_NAME_PREFIX + '_requester_%s_%s' % (package_name, srv_name))

0 commit comments

Comments
 (0)