Mixing positional and named arguments

3,174 views
Skip to first unread message

Bob Le

unread,
Apr 20, 2016, 2:10:54 AM4/20/16
to robotframework-users
I'm noticing that when mixing positional and named arguments, Robot Framework is not detecting a bogus named argument.

I defined the following Python keyword library:

class Robot(object):
    def passing_positional_and_named_arguments(self, a, b, named_arg=False):
        info("a='%s', b='%s', named_arg='%s'" % (a, b, named_arg))
        return {'a': a, 'b': b, 'named_arg': named_arg}

In the followings, Test 1-3 have expected behaviors. In Test 4, it appears the named argument is read in as a string.

Test 1)
I called:
  passing positional and named arguments    a=${10}    b=${20}    named_arg=${true}

result:
  20160419 16:46:31.726 - INFO - +-- START KW: Robot.Passing Positional And Named Arguments [ a=${10} | b=${20} | named_arg=${true} ]
  20160419 16:46:31.746 - INFO - a='10', b='20', named_arg='True'
    

Test 2)
I called:
  passing positional and named arguments    ${10}      ${20}      named_arg=${30}

result:
  20160419 16:46:31.747 - INFO - +-- START KW: Robot.Passing Positional And Named Arguments [ ${10} | ${20} | named_arg=${30} ]
  20160419 16:46:31.749 - INFO - a='10', b='20', named_arg='30'


Test 3)
I call:
  passing positional and named arguments    a=${10}    b=${20}    bogus_named_arg=${30}

result:
  20160419 16:46:31.752 - INFO - +-- START KW: Robot.Passing Positional And Named Arguments [ a=${10} | b=${20} | bogus_named_arg=${30} ]
  20160419 16:46:31.752 - FAIL - Keyword 'Robot.Passing Positional And Named Arguments' got positional argument after named arguments.


Test 4)
I called:
  passing positional and named arguments    ${10}      ${20}      bogus_named_arg=${30}

result:
  20160419 16:46:31.749 - INFO - +-- START KW: Robot.Passing Positional And Named Arguments [ ${10} | ${20} | bogus_named_arg=${30} ]
  20160419 16:46:31.751 - INFO - a='10', b='20', named_arg='bogus_named_arg=30'

 Is this a bug, or am I missing something?

Thanks for your help.
Bob

Pekka Klärck

unread,
Apr 20, 2016, 8:06:22 AM4/20/16
to ame...@gmail.com, robotframework-users
2016-04-20 3:02 GMT+03:00 Bob Le <ame...@gmail.com>:
> I'm noticing that when mixing positional and named arguments, Robot
> Framework is not detecting a bogus named argument.

You are right that bogus named argument are not detected. You don't
need to mix positional and named arguments, though. This is probably
the simplest example demonstrating the issue:

def keyword(arg):
print arg

*** Test Cases ***
Example
Keyword arg=foo # prints `foo`
Keyword foo=bar # prints `foo=bar`


The first usage of `Keyword` above uses the named argument syntax. It
is detected by Robot Framework because the passed in argument contains
`=` and the part before it matches an argument the keyword has. In the
latter usage there is not such match and thus `=` is considered to be
a literal value.

The reason for this behavior is that when the named argument syntax
was introduced in RF 2.5 [1], we didn't want to break existing tests
that used `=` as a literal value. Breaking backwards compatibility
would have been bad, but the current situation is not ideal either:

- As pointed out, the behavior is somewhat confusing.
- Typos when using the named argument syntax (e.g. `Keyword
argh=foo`) do not cause clear errors.
- When argument names are changed, named argument syntax usage breaks
without clear errors.
- When argument names are changed, new names may accidentally match
arguments where `=` is to be used literally.

I've encountered these problems many times enough to think that it
would be better if `=` would always mean named argument syntax and it
would need to be escaped like `\=` when used literally. The change
would be massively backwards incompatible, though, because `=` is used
so often in test data and many libraries also give it a special
meaning. For example, Selenium2Library uses `=` when specifying a
custom locator like `xpath=//h1` and `css=h1`.

In practice the change could only be done with a very long deprecation
period to give users time to escape `=` and library authors to come up
with alternative syntax to use instead of or in addition to it. Should
also consider adding a separate command line option to disable the
deprecation warning and possibly also to turn it into an error. All
this requires quite a bit of effort and I'm not sure is it worth it.
What do others think about this?

Cheers,
.peke
--
Agile Tester/Developer/Consultant :: http://eliga.fi
Lead Developer of Robot Framework :: http://robotframework.org

Tatu Aalto

unread,
Apr 20, 2016, 10:05:34 AM4/20/16
to Pekka Klärck, robotframework-users, ame...@gmail.com

Ugh

I don't like the current situation, from the reason Pekka did mention. I would like take steps to the direction where foo=bar would be always treated as named argument.

Also from the reason Pekka did mention I am on favour of long depreciation period.

-Tatu

--
You received this message because you are subscribed to the Google Groups "robotframework-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-u...@googlegroups.com.
To post to this group, send email to robotframe...@googlegroups.com.
Visit this group at https://groups.google.com/group/robotframework-users.
For more options, visit https://groups.google.com/d/optout.

Bob Le

unread,
Apr 20, 2016, 12:35:22 PM4/20/16
to robotframework-users, pekka....@gmail.com, ame...@gmail.com
Thank you for the detailed explanation and historical perspective, Pekka.

Like Tatu, I would prefer the direction where '=' means named arguments as well. The current behavior can result in rather difficult to debug tests with possible false positive tests also. The long depreciation period sounds good. 
To unsubscribe from this group and stop receiving emails from it, send an email to robotframework-users+unsub...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages