Skip to content

Commit cdf535f

Browse files
committed
Fix extended assign with @ and & syntax
Fixes robotframework#5405.
1 parent b234901 commit cdf535f

3 files changed

Lines changed: 39 additions & 26 deletions

File tree

atest/robot/variables/extended_assign.robot

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ Set item to list attribute
2020
Set item to dict attribute
2121
Check Test Case ${TESTNAME}
2222

23+
Set using @-syntax
24+
Check Test Case ${TESTNAME}
25+
26+
Set using &-syntax
27+
Check Test Case ${TESTNAME}
28+
2329
Trying to set un-settable attribute
2430
Check Test Case ${TESTNAME}
2531

@@ -37,6 +43,3 @@ Strings and integers do not support extended assign
3743

3844
Attribute name must be valid
3945
Check Test Case ${TESTNAME}
40-
41-
Extended syntax is ignored with list variables
42-
Check Test Case ${TESTNAME}

atest/testdata/variables/extended_assign.robot

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
Variables extended_assign_vars.py
33
Library Collections
44

5+
*** Variables ***
6+
&{DICT} key=value
7+
58
*** Test Cases ***
69
Set attributes to Python object
710
[Setup] Should Be Equal ${VAR.attr}-${VAR.attr2} value-v2
@@ -25,31 +28,47 @@ Set item to list attribute
2528
${body.data}[${0}] = Set Variable firstVal
2629
${body.data}[-1] = Set Variable lastVal
2730
${body.data}[1:3] = Create List ${98} middle ${99}
28-
${EXPECTED_LIST} = Create List firstVal ${98} middle ${99} lastVal
29-
Lists Should Be Equal ${body.data} ${EXPECTED_LIST}
31+
Lists Should Be Equal ${body.data} ${{['firstVal', 98, 'middle', 99, 'lastVal']}}
3032

3133
Set item to dict attribute
3234
&{body} = Evaluate {'data': {'key': 'val', 0: 1}}
3335
${body.data}[key] = Set Variable newVal
3436
${body.data}[${0}] = Set Variable ${2}
3537
${body.data}[newKey] = Set Variable newKeyVal
36-
${EXPECTED_DICT} = Create Dictionary key=newVal ${0}=${2} newKey=newKeyVal
37-
Dictionaries Should Be Equal ${body.data} ${EXPECTED_DICT}
38+
Dictionaries Should Be Equal ${body.data} ${{{'key': 'newVal', 0: 2, 'newKey': 'newKeyVal'}}}
39+
40+
Set using @-syntax
41+
[Documentation] FAIL Setting '\@{VAR.fail}' failed: Expected list-like value, got string.
42+
@{DICT.key} = Create List 1 2 3
43+
Should Be Equal ${DICT} ${{{'key': ['1', '2', '3']}}}
44+
@{VAR.list: int} = Create List 1 2 3
45+
Should Be Equal ${VAR.list} ${{[1, 2, 3]}}
46+
@{VAR.fail} = Set Variable not a list
47+
48+
Set using &-syntax
49+
[Documentation] FAIL Setting '\&{DICT.fail}' failed: Expected dictionary-like value, got integer.
50+
&{VAR.dict} = Create Dictionary key=value
51+
Should Be Equal ${VAR.dict} ${{{'key': 'value'}}}
52+
Should Be Equal ${VAR.dict.key} value
53+
&{DICT.key: int=float} = Create Dictionary 1=2.3 ${4.0}=${5.6}
54+
Should Be Equal ${DICT} ${{{'key': {1: 2.3, 4: 5.6}}}}
55+
Should Be Equal ${DICT.key}[${1}] ${2.3}
56+
&{DICT.fail} = Set Variable ${666}
3857

3958
Trying to set un-settable attribute
40-
[Documentation] FAIL STARTS: Setting attribute 'not_settable' to variable '\${VAR}' failed: AttributeError:
59+
[Documentation] FAIL STARTS: Setting '\${VAR.not_settable}' failed: AttributeError:
4160
${VAR.not_settable} = Set Variable whatever
4261

4362
Un-settable attribute error is catchable
4463
[Documentation] FAIL GLOB:
4564
... Teardown failed:
4665
... Several failures occurred:
4766
...
48-
... 1) Setting attribute 'not_settable' to variable '\${VAR}' failed: AttributeError: *
67+
... 1) Setting '\${VAR.not_settable}' failed: AttributeError: *
4968
...
5069
... 2) AssertionError
5170
Run Keyword And Expect Error
52-
... Setting attribute 'not_settable' to variable '\${VAR}' failed: AttributeError: *
71+
... Setting '\${VAR.not_settable}' failed: AttributeError: *
5372
... Setting unsettable attribute
5473
[Teardown] Run Keywords Setting unsettable attribute Fail
5574

@@ -78,11 +97,6 @@ Attribute name must be valid
7897
Should Be Equal ${VAR.2nd} starts with number
7998
Should Be Equal ${VAR.foo-bar} invalid char
8099

81-
Extended syntax is ignored with list variables
82-
@{list} = Create List 1 2 3
83-
@{list.new} = Create List 1 2 3
84-
Should Be Equal ${list} ${list.new}
85-
86100
*** Keywords ***
87101
Extended assignment is disabled
88102
[Arguments] ${value}

src/robot/variables/assigner.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def assign(self, return_value):
123123
context.info(format_assign_message(name, value, items))
124124

125125
def _extended_assign(self, name, value, variables):
126-
if name[0] != "$" or "." not in name or name in variables:
126+
if "." not in name or name in variables:
127127
return False
128128
base, attr = [token.strip() for token in name[2:-1].rsplit(".", 1)]
129129
try:
@@ -136,12 +136,9 @@ def _extended_assign(self, name, value, variables):
136136
):
137137
return False
138138
try:
139-
setattr(var, attr, value)
139+
setattr(var, attr, self._handle_list_and_dict(value, name[0]))
140140
except Exception:
141-
raise VariableError(
142-
f"Setting attribute '{attr}' to variable '${{{base}}}' failed: "
143-
f"{get_error_message()}"
144-
)
141+
raise VariableError(f"Setting '{name}' failed: {get_error_message()}")
145142
return True
146143

147144
def _variable_supports_extended_assign(self, var):
@@ -168,12 +165,12 @@ def _raise_cannot_set_type(self, value, expected):
168165
value_type = type_name(value)
169166
raise VariableError(f"Expected {expected}-like value, got {value_type}.")
170167

171-
def _validate_item_assign(self, name, value):
172-
if name[0] == "@":
168+
def _handle_list_and_dict(self, value, identifier):
169+
if identifier == "@":
173170
if not is_list_like(value):
174171
self._raise_cannot_set_type(value, "list")
175172
value = list(value)
176-
if name[0] == "&":
173+
if identifier == "&":
177174
if not is_dict_like(value):
178175
self._raise_cannot_set_type(value, "dictionary")
179176
value = DotDict(value)
@@ -195,8 +192,7 @@ def _item_assign(self, name, items, value, variables):
195192
except ValueError:
196193
pass
197194
try:
198-
value = self._validate_item_assign(name, value)
199-
var[selector] = value
195+
var[selector] = self._handle_list_and_dict(value, name[0])
200196
except (IndexError, TypeError, Exception):
201197
raise VariableError(
202198
f"Setting value to {type_name(var)} variable "

0 commit comments

Comments
 (0)