Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Nicer API for setting keyword call arguments programmatically #5000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
pekkaklarck opened this issue Jan 4, 2024 · 1 comment
Closed

Nicer API for setting keyword call arguments programmatically #5000

pekkaklarck opened this issue Jan 4, 2024 · 1 comment

Comments

@pekkaklarck
Copy link
Member

pekkaklarck commented Jan 4, 2024

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.

@pekkaklarck
Copy link
Member Author

How this enhancement was implemented caused issues with BuiltIn.run_keyword in some cases. As explained in #5031, problems mostly occur when using it programmatically, but in special cases there can also be issues when using just normal data.

There doesn't seem to be any good way to avoid these problems and, now that I look at this again, the approach used here feels pretty hacky in general. We have thus made a decision to revert this change and to do it already in RF 7.0.1.

The original motivation for the enhancement was fine. I will open a new issue about that and propose a less hacky solution. It's probably best to wait for RF 7.1 until implementing it, though.

pekkaklarck added a commit that referenced this issue Jun 2, 2024
This basically reverts the following changes done as part of #5000:

- It isn't anymore possible to specify named argumens as two-item
  tuples like `('name', 'value')` where the value could also be a
  non-string.

- It isn't anymore possible to specify positional and named arguments
  separately like `(['pos', 'args'], {'name': 'value'})`.

The main reason this functionality was reverted is that it caused
problems when using `BuiltIn.run_keyword` if arguments used with it
accidentally matched the special syntax explained below. In general
the whole API was too hacky.

Fixes #5031.
pekkaklarck added a commit that referenced this issue Jun 4, 2024
This is part of issue #5031 that in practice reverted #5000.
pekkaklarck added a commit that referenced this issue Aug 26, 2024
This is a new stable API that is planned to replace the temporary API
(#5031) that was added after the failed attempt to add an API for this
purpose in RF 7.0 (#5000).

Fixes #5143.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant