Skip to content

Nicer API for setting keyword call arguments programmatically #5000

@pekkaklarck

Description

@pekkaklarck

robot.running.Keyword.args contains arguments used in a keyword call as a list. Arguments originating from normal Robot Framework data are always strings and they are in the exact same format as in the data. This means that arguments can contain variables and escape characters, and that named arguments are represented using the name=value syntax.

If arguments are modified programmatically, it is possible to use also other objects than strings. This doesn't, however, work with named arguments because in the name=value syntax the value is always a string. Automatic argument conversion handles conversion in common cases, but especially with more complex objects being able to use them directly would be convenient. Another pretty common and unexpected annoyance is that arguments that are strings need to follow the same escaping rules as normal data. Most importantly, \ needs to be doubled and, because it's an escape character also in Python, we need to use data like 'c:\\\\temp\\\\new' or r'c:\\temp\\new'.

I propose we enhance setting arguments as follows:

  1. Support specifying named arguments as two-item tuples like ('name', 'value') to allow using also non-strings as values. To avoid ambiguity with arguments possibly containing a literal =, we should also support positional arguments as one-item tuples like ('value',). In this usage we should still resolve variables, which requires users handling escaping themselves.

    Example: [('positional',), ('name', 'value'), ('path', r'c:\\temp\\new')]

    We support tuples like this also with the dynamic library API with arguments having default values. The approach thus has precedence and it has worked well.

  2. Support giving arguments directly as a list of positional arguments and a dictionary of named arguments. In this usage we should use arguments directly without handling escapes. That then means that variables aren't resolved either, but automatic argument conversion and validation will still be done.

    Example: [['positional'], {'name': 'value', 'path': 'c:\\temp\\new'}]

The above is pretty easy to implement. During execution we just need to handle different ways arguments can be specified when resolving arguments. No code changes are needed with robot.running.Keyword, but this new functionality needs to be documented and typing needs to be set accordingly. We also need to enhance robot.result.Keyword. With it it's better to always store arguments as strings, which means that we need to convert other arguments when they are set.

It's a bit questionable is this a good idea this late in RF 7.0 release cycle, we already have a release candidate out, but this makes some of the usages of the new start/end_keyword listener v3 methods (#3296) so much more convenient that we decided to still implement this. Changes are pretty small and ought to be safe, but big enough to warrant a second release candidate.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions