Skip to content

Commit b324915

Browse files
committed
Handle binary arguments recursively
1 parent 75deb48 commit b324915

File tree

4 files changed

+38
-9
lines changed

4 files changed

+38
-9
lines changed

src/robotremoteserver.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,8 @@ def __init__(self, keyword):
357357
self._keyword = keyword
358358

359359
def run_keyword(self, args, kwargs=None):
360-
# TODO: Handle binary in lists/dicts in args/kwargs
361-
args, kwargs = self._handle_binary_args(args, kwargs or {})
360+
args = self._handle_binary(args)
361+
kwargs = self._handle_binary(kwargs or {})
362362
result = KeywordResult()
363363
with StandardStreamInterceptor() as interceptor:
364364
try:
@@ -375,13 +375,17 @@ def run_keyword(self, args, kwargs=None):
375375
result.set_output(interceptor.output)
376376
return result.data
377377

378-
def _handle_binary_args(self, args, kwargs):
379-
args = [self._handle_binary_arg(a) for a in args]
380-
kwargs = dict((k, self._handle_binary_arg(v)) for k, v in kwargs.items())
381-
return args, kwargs
382-
383-
def _handle_binary_arg(self, arg):
384-
return arg if not isinstance(arg, Binary) else arg.data
378+
def _handle_binary(self, arg):
379+
# No need to compare against other iterables or mappings because we
380+
# only get actual lists and dicts over XML-RPC. Binary cannot be
381+
# a dictionary key either.
382+
if isinstance(arg, list):
383+
return [self._handle_binary(item) for item in arg]
384+
if isinstance(arg, dict):
385+
return dict((key, self._handle_binary(arg[key])) for key in arg)
386+
if isinstance(arg, Binary):
387+
return arg.data
388+
return arg
385389

386390

387391
class StandardStreamInterceptor(object):

test/atest/argument_types.robot

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ Dictionary With Non-String Keys
6868
[Documentation] XML-RPC supports only strings as keys so must convert them
6969
{42: 42, True: False, None: None} {'42': 42, 'True': False, '': ''}
7070

71+
Binary in lists and dicts
72+
[Documentation] Binary values should be handled recursively
73+
(b'\x01', [b'\x02', set([u'\x03'])]) [b'\x01', [b'\x02', [b'\x03']]]
74+
{'k1': b'\x01', 'k2': [b'\x02', {'k3': b'\x03'}]}
75+
7176
*** Keywords ***
7277
Argument Should Be Correct
7378
[Arguments] ${argument} ${expected}=

test/atest/kwargs.robot

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,8 @@ Non-string kwargs
5757
${list} = Create List 1 ${2}
5858
${result} = Kwargs a=${1} b=${True} c=${list}
5959
Should Be Equal ${result} a:1 (int), b:True (bool), c:['1', 2] (list)
60+
61+
Binary kwargs
62+
${tuple} = Evaluate ('\x02',)
63+
${result} = Kwargs a=\x00 b=\x01 c=${tuple}
64+
Should Be Equal ${result} a:\x00, b:\x01, c:['\\x02'] (list)

test/libs/Arguments.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from robotremoteserver import Binary
2+
13
try:
24
basestring
35
except:
@@ -10,6 +12,18 @@ def argument_should_be_correct(self, argument, expected):
1012
expected = eval(expected)
1113
if argument != expected:
1214
raise AssertionError('%r != %r' % (argument, expected))
15+
self.should_not_contain_binary(argument)
16+
17+
def should_not_contain_binary(self, argument):
18+
if isinstance(argument, Binary):
19+
raise AssertionError('Binary with data %r found!' % argument.data)
20+
if isinstance(argument, dict):
21+
for key, value in argument.items():
22+
self.should_not_contain_binary(key)
23+
self.should_not_contain_binary(value)
24+
if isinstance(argument, list):
25+
for item in argument:
26+
self.should_not_contain_binary(item)
1327

1428
def no_arguments(self):
1529
return self._format_args()
@@ -33,6 +47,7 @@ def required_defaults_and_varargs(self, req, default='world', *varargs):
3347
return self._format_args(req, default, *varargs)
3448

3549
def kwargs(self, **kwargs):
50+
self.should_not_contain_binary(kwargs)
3651
return self._format_args(**kwargs)
3752

3853
def args_and_kwargs(self, arg1, arg2='default', **kwargs):

0 commit comments

Comments
 (0)