Skip to content
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

Propose using $var syntax if evaluation IF or WHILE condition using ${var} fails #4676

Closed
pekkaklarck opened this issue Mar 7, 2023 · 2 comments

Comments

@pekkaklarck
Copy link
Member

A common error when evaluating expressions with IF or otherwise is using something like

IF    ${x} == 'expected'
    Keyword
END

when the variable ${x} contains a string. Normal variables are resolved before evaluating the expression, so if ${x} contains a string value, the evaluated expression will be value == 'expected'. Evaluating it fails because value isn't quoted, it's thus considered a variable in Python, and no such variable exists. The resulting error is this:

Evaluating IF condition failed: Evaluating expression 'value == 'expected'' failed: NameError: name 'value' is not defined nor importable as module

One solution to this problem is quoting the variable like '${x}' == 'expected', but that doesn't work if the variable value contains quotes or newlines. A better solution is using the special $var syntax like $x == 'value' that makes the variable available in the Python evaluation namespace (#2040). All this is explained in the User Guide, but there are many users who don't know about this and struggle with the syntax.

Because this is a such a common error, we should make the error more informative if the expression contains "normal" variables. We could, for example, show also the original expression and recommend quoting or using the "special" variable syntax. Possibly it could look like this:

Evaluating IF condition failed: Evaluating expression 'value == 'expected'' failed: NameError: name 'value' is not defined nor importable as module
The original expression was '${x} == 'expected''. Try using the '$var' syntax like '$x == 'expected'' to avoid resolving variables before the expression is evaluated. See the Evaluating expression appendix in the User Guide for more details.

There are few problems implementing this:

  1. Variables are solved before the evaluate_expression is called so this function doesn't know the original expression nor did it contain variables. This information needs to be passed to it, but in same cases (at least with inline Python evaluation) it isn't that easy.
  2. It's not easy to detect when exactly this extra information should be included into the error. Including it always when evaluating the expression fails can add confusion when the error isn't related to variables. It would probably better to include it only if evaluation fails for a NameError, but also in that case you could have an expression like '${x}' == value where the variable likely isn't a problem. We could try some heuristics to see what causes the error, but that's probably too much work compared to including the extra info in some cases where it's not needed.
  3. Coming up with a good but somewhat short error message isn't easy. I'm not totally happy with the above, but I guess it would be better than nothing.

Because this extra info is added only if evaluation fails, this should be a totally backwards compatible change. It would be nice to include it already into RF 6.1, but that release is already about to be late and this isn't that easy to implement, so RF 6.2 is probably a better target. If someone is interested to look at this, including it already into RF 6.1 ought to be possible.

@pekkaklarck
Copy link
Member Author

pekkaklarck commented Mar 7, 2023

I decided to prototype this quickly and it seems that at least with IF and WHILE including this extra information is pretty easy. At least with inline Python evaluation that's harder and I haven't yet looked at Run Keyword If. Enhancing just IF and WHILE already helps so much that I move this into RF 6.1 scope.

The error I get with my prototype is as follows. I think it's already pretty good, but enhancement ideas are still appreciated.

Evaluating IF condition failed: Evaluating expression value == 'expected' failed: NameError: name 'value' is not defined nor importable as module

Variables in the original expression ${x} == 'expected' were resolved before the expression was evaluated. Try using $x == 'expected' syntax to avoid that. See the Evaluating expression appendix in the User Guide for more details.

As part of enhancing the error, I replaced single quotes around the expression with backticks (which cause special formatting here on GitHub). Quotes are so common in expression that using something else is probably a good idea. We could consider doing that also with other error messages, but that requires a separate issue and is definitely out of the scope of RF 6.1.

@pekkaklarck
Copy link
Member Author

This is easy with IF and WHILE but not so easy with inline if or any BuiltIn keyword.

The problem with inline if is that variables are resolved inside out so that if you have ${{len(${var}) == 2}}, ${var} is already resolved when the code handling the inline syntax is called I guess that could be changed but it's not easy.

The problem with BuiltIn keywords is that this change requires that variables in arguments aren't resolved. We have mechanism for that, but that mechanism currently also disables timeouts with those keywords. That could be changed, but it's not worth the effort right now.

I believe just enhancing IF and WHILE now is enough.

@pekkaklarck pekkaklarck changed the title Propose using $var syntax in expression if evaluation using ${var} fails Propose using $var syntax if evaluation IF or WHILE condition using ${var} fails Mar 10, 2023
yanne pushed a commit that referenced this issue Mar 18, 2023
For example, `${var} == 'value'` fails for NameError if `${var}` is a
string and using `$var == 'value'` avoids that. Fixes #4676.
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