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

Cannot access dict variable value by attribute access syntax which is set by Set Test Variable #3257

Open
kanchi240 opened this issue Aug 7, 2019 · 3 comments

Comments

@kanchi240
Copy link
Contributor

Hi,

Test library is:

from robot.libraries.BuiltIn import BuiltIn

class MyLib:
    def set_a_dict_var(self):
        d = {'k1': 'v1'}
        BuiltIn().set_test_variable('${d}', d)

And test case is:

*** Settings ***
Library           MyLib

*** Test Cases ***
test
    set_a_dict_var
    log    ${d}[k1]
    log    ${d.k1}

And test log is:
20190807175100

And I see the user guide said:

https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#id575

If a key is a string, it is possible to access its value also using attribute access syntax ${NAME.key}.

Is it an issue? Thanks

@pekkaklarck
Copy link
Member

When you create a dict variable in Robot data, Robot automatically converts it into its own DotDict instance that supports the dict.key syntax. In your case the variable is a normal Python dict that doesn't have such support. You should be able to get the desired behavior by simply using

BuiltIn().set_test_variable('&{d}', d)

to tell Robot that this is a dict variable. If that doesn't work, then it's a bug in set_test_variable. A workaround would be constructing a DotDict yourself.

@kanchi240
Copy link
Contributor Author

Covert d to DotDict then access value using attribute access syntax is ok,
but using BuiltIn().set_test_variable('&{d}', d) failed, error message is:

TypeError: unhashable type: 'slice'
Traceback (most recent call last):
  File "D:\CBS2.0\lib\MyLib.py", line 8, in set_dict_var
    BuiltIn().set_test_variable('&{d}', d)
  File "d:\pyenv\robot\lib\site-packages\robot\libraries\BuiltIn.py", line 1427, in set_test_variable
    value = self._get_var_value(name, values)
  File "d:\pyenv\robot\lib\site-packages\robot\libraries\BuiltIn.py", line 1572, in _get_var_value
    return VariableTableValue(values, name).resolve(self._variables)
  File "d:\pyenv\robot\lib\site-packages\robot\variables\tablesetter.py", line 56, in VariableTableValue
    return VariableTableValue(value, error_reporter)
  File "d:\pyenv\robot\lib\site-packages\robot\variables\tablesetter.py", line 62, in __init__
    self._values = self._format_values(values)
  File "d:\pyenv\robot\lib\site-packages\robot\variables\tablesetter.py", line 123, in _format_values
    return list(self._yield_formatted(values))
  File "d:\pyenv\robot\lib\site-packages\robot\variables\tablesetter.py", line 130, in _yield_formatted
    name, value = split_from_equals(item)
  File "d:\pyenv\robot\lib\site-packages\robot\utils\escaping.py", line 129, in split_from_equals
    index = _get_split_index(string)
  File "d:\pyenv\robot\lib\site-packages\robot\utils\escaping.py", line 136, in _get_split_index
    while '=' in string[index:]:

@pekkaklarck
Copy link
Member

Yeah, in this case set_test_variable expects second (and subsequent) arguments to be strings in format name=value. I guess it could be special cased to handle values that are dicts, but same approach wouldn't work with @{list} variables and inconsistency wouldn't be good. Alternatively we could change these keywords accept also **kwargs but that has its own issues as well. I'll leave this issue open and think about this later. Explicitly using DotDict in custom libraries is a good solution anyway.

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

No branches or pull requests

2 participants