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

WIP: see diff #1

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
1d8351a
also allow byte like object to get item by index
bollenn Oct 21, 2019
f47f4a5
review comment: update error message
bollenn Oct 23, 2019
bd79d31
Update scalar_lists.py
bollenn Oct 23, 2019
4491e2c
Merge branch 'master' of https://github.com/robotframework/robotframe…
bollenn Nov 18, 2019
0652ab8
Merge branch 'master' of https://github.com/robotframework/robotframe…
JasperCraeghs Dec 30, 2019
6f34e92
Use presence or lack of __getitem__ method to determine whether a var…
JasperCraeghs Dec 30, 2019
13b64ee
Change Iterable to Sequence and 'dictionary or iterable' to 'subscrip…
JasperCraeghs Dec 30, 2019
24072b3
Fix no-member: `self.item` to `self.items` in `__unicode__`
JasperCraeghs Dec 30, 2019
3a4570b
Enhance lexer tests
pekkaklarck Dec 30, 2019
72b22de
Update tests to changes in #3350
JasperCraeghs Dec 30, 2019
70728d3
Catch all exceptions when the attempt to cast key to int fails
JasperCraeghs Dec 30, 2019
f75c073
Lexer: Yield EOL also at the end of input
pekkaklarck Dec 30, 2019
d861fb9
Extend error messages in case of invalid subscript and update atests …
JasperCraeghs Dec 31, 2019
883e6ed
Add utests for changes in #3350
JasperCraeghs Dec 31, 2019
38981bc
Add support for slicing for non-sequence subscriptables
JasperCraeghs Dec 31, 2019
22929a7
Lexer: Fine tune lexing name statement.
pekkaklarck Dec 31, 2019
96108c2
Extend documentation about accessing items of subscriptable variables
JasperCraeghs Dec 31, 2019
f3ff2b8
Merge branch 'master' of https://github.com/robotframework/robotframe…
JasperCraeghs Dec 31, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion atest/robot/variables/list_variable_items.robot
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Non-existing variable
Non-existing index variable
Check Test Case ${TESTNAME}

Non-list variable
Non-subscriptable variable
Check Test Case ${TESTNAME}

Old syntax with `@` still works but is deprecated
Expand Down
2 changes: 1 addition & 1 deletion atest/robot/variables/nested_item_access.robot
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Invalid nested list access
Invalid nested dict access
Check Test Case ${TESTNAME}

Nested access with non-list/dict
Nested access with non-subscriptable
Check Test Case ${TESTNAME}

Escape nested
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ Expect Error When Access To List Variable Nonexisting Index Syntax 1

Expect Error When Access To List Variable Nonexisting Index Syntax 2
Run Keyword And Expect Error
... List '\${list}' has no item in index 2.
... Sequence '\${list}' has no item in index 2.
... Access To List Variable Nonexisting Index Syntax 2

Expect Error When Access To Dictionary Nonexisting Key Syntax 1
Expand All @@ -204,7 +204,7 @@ Expect Error When Access To Dictionary Nonexisting Key Syntax 1

Expect Error When Access To Dictionary Nonexisting Key Syntax 2
Run Keyword And Expect Error
... Dictionary '\${dict}' has no key 'c'.
... Subscriptable '\${dict}' has no key 'c'.
... Access To Dictionary Variable Nonexisting Key Syntax 2

Expect Error With Explicit GLOB
Expand Down
20 changes: 11 additions & 9 deletions atest/testdata/variables/dict_variable_items.robot
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Library Collections
Library XML

*** Variables ***
${INT} ${15}
&{DICT} A=1 B=2 C=3 ${1}=${2} 3=4 ${NONE}=${NONE} = ${SPACE}=${SPACE}
&{SQUARES} [=open ]=close []=both [x[y]=mixed
${A} A
Expand Down Expand Up @@ -70,23 +71,23 @@ List-like values are not manipulated
Should Be Equal ${dict}[tuple] ${tuple}

Integer key cannot be accessed as string
[Documentation] FAIL Dictionary '\${DICT}' has no key '1'.
[Documentation] FAIL Subscriptable '\${DICT}' has no key '1'.
Log ${DICT}[1]

String key cannot be accessed as integer
[Documentation] FAIL Dictionary '\${DICT}' has no key '3'.
[Documentation] FAIL Subscriptable '\${DICT}' has no key '3'.
Log ${DICT}[${3}]

Invalid key
[Documentation] FAIL Dictionary '\${DICT}' has no key 'nonex'.
[Documentation] FAIL Subscriptable '\${DICT}' has no key 'nonex'.
Log ${DICT}[nonex]

Invalid key using variable
[Documentation] FAIL Dictionary '\${DICT}' has no key 'xxx'.
[Documentation] FAIL Subscriptable '\${DICT}' has no key 'xxx'.
Log ${DICT}[${INVALID}]

Non-hashable key
[Documentation] FAIL STARTS: Dictionary '\${DICT}' used with invalid key:
[Documentation] FAIL STARTS: Subscriptable '\${DICT}' used with invalid key:
Log ${DICT}[@{DICT}]

Non-existing variable
Expand All @@ -99,9 +100,10 @@ Non-existing index variable

Non-dict variable
[Documentation] FAIL
... Variable '\${INVALID}' is string, not list or dictionary, \
... and thus accessing item '${nonex}' from it is not possible.
Log ${INVALID}[${nonex}]
... Variable '\${INT}' is integer, which is not subscriptable, and thus \
... accessing item '0' from it is not possible. To use '[0]' as a \
... literal value, it needs to be escaped like '\\[0]'.
Log ${INT}[0]

Sanity check
@{items} = Create List
Expand All @@ -112,7 +114,7 @@ Sanity check
Should Be Equal ${items} A: 1, B: 2, C: 3, 1: 2, 3: 4, None: None, : , ${SPACE}: ${SPACE}

Old syntax with `&` still works but is deprecated
[Documentation] FAIL Dictionary '\&{DICT}' has no key 'nonex'.
[Documentation] FAIL Subscriptable '\&{DICT}' has no key 'nonex'.
Should Be Equal &{DICT}[A] 1
Should Be Equal &{DICT}[${1}] ${2}
Log &{DICT}[nonex]
57 changes: 41 additions & 16 deletions atest/testdata/variables/list_variable_items.robot
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*** Variables ***
${INT} ${15}
@{LIST} A B C D E F G H I J K
@{NUMBERS} 1 2 3
&{MAP} first=0 last=-1
Expand Down Expand Up @@ -44,43 +45,64 @@ Slicing with variable
... ${LIST[1:]}

Invalid index
[Documentation] FAIL List '\${LIST}' has no item in index 12.
[Documentation] FAIL Sequence '\${LIST}' has no item in index 12.
Log ${LIST}[12]

Invalid index using variable
[Documentation] FAIL List '\${LIST}' has no item in index 13.
[Documentation] FAIL Sequence '\${LIST}' has no item in index 13.
Log ${LIST}[${ONE}${3}]

Non-int index
[Documentation] FAIL List '\${LIST}' used with invalid index 'invalid'.
[Documentation] FAIL \
... Sequence '\${LIST}' used with invalid index 'invalid'. To use \
... '[invalid]' as a literal value, it needs to be escaped like \
... '\\[invalid]'.
Log ${LIST}[invalid]

Non-int index using variable 1
[Documentation] FAIL List '\${LIST}' used with invalid index 'xxx'.
[Documentation] FAIL \
... Sequence '\${LIST}' used with invalid index 'xxx'. To use \
... '[xxx]' as a literal value, it needs to be escaped like '\\[xxx]'.
Log ${LIST}[${INVALID}]

Non-int index using variable 2
[Documentation] FAIL List '\${LIST}' used with invalid index '1.1'.
[Documentation] FAIL \
... Sequence '\${LIST}' used with invalid index '1.1'. To use \
... '[1.1]' as a literal value, it needs to be escaped like '\\[1.1]'.
Log ${LIST}[${1.1}]

Empty index
[Documentation] FAIL List '\${LIST}' used with invalid index ''.
[Documentation] FAIL \
... Sequence '\${LIST}' used with invalid index ''. To use \
... '[]' as a literal value, it needs to be escaped like '\\[]'.
Log ${LIST}[]

Invalid slice
[Documentation] FAIL List '\${LIST}' used with invalid index '1:2:3:4'.
[Documentation] FAIL \
... Sequence '\${LIST}' used with invalid index '1:2:3:4'. To use \
... '[1:2:3:4]' as a literal value, it needs to be escaped like \
... '\\[1:2:3:4]'.
Log ${LIST}[1:2:3:4]

Non-int slice index 1
[Documentation] FAIL List '\${LIST}' used with invalid index 'ooops:'.
[Documentation] FAIL \
... Sequence '\${LIST}' used with invalid index 'ooops:'. To use \
... '[ooops:]' as a literal value, it needs to be escaped like \
... '\\[ooops:]'.
Log ${LIST}[ooops:]

Non-int slice index 2
[Documentation] FAIL List '\${LIST}' used with invalid index '1:ooops'.
[Documentation] FAIL \
... Sequence '\${LIST}' used with invalid index '1:ooops'. To use \
... '[1:ooops]' as a literal value, it needs to be escaped like \
... '\\[1:ooops]'.
Log ${LIST}[1:ooops]

Non-int slice index 3
[Documentation] FAIL List '\${LIST}' used with invalid index '1:2:ooops'.
[Documentation] FAIL \
... Sequence '\${LIST}' used with invalid index '1:2:ooops'. To use \
... '[1:2:ooops]' as a literal value, it needs to be escaped like \
... '\\[1:2:ooops]'.
Log ${LIST}[1:2:ooops]

Non-existing variable
Expand All @@ -91,21 +113,24 @@ Non-existing index variable
[Documentation] FAIL Variable '\${nonex index}' not found.
Log ${LIST}[${nonex index}]

Non-list variable
Non-subscriptable variable
[Documentation] FAIL
... Variable '\${INVALID}' is string, not list or dictionary, \
... and thus accessing item '0' from it is not possible.
Log ${INVALID}[0]
... Variable '\${INT}' is integer, which is not subscriptable, and thus \
... accessing item '0' from it is not possible. To use '[0]' as a \
... literal value, it needs to be escaped like '\\[0]'.
Log ${INT}[0]

Old syntax with `@` still works but is deprecated
[Documentation] `\${list}[1]` and `\@{list}[1]` work same way still.
... In the future latter is deprecated and changed.
... FAIL List '\@{LIST}' has no item in index 99.
... FAIL Sequence '\@{LIST}' has no item in index 99.
Should Be Equal @{LIST}[0] A
Should Be Equal @{LIST}[${-1}] K
Log @{LIST}[99]

Old syntax with `@` doesn't support new slicing syntax
[Documentation] Slicing support should be added in RF 3.3 when `@{list}[index]` changes.
... FAIL List '\@{LIST}' used with invalid index '1:'.
... FAIL Sequence '\@{LIST}' used with invalid index '1:'. \
... To use '[1:]' as a literal value, it needs to be \
... escaped like '\\[1:]'.
Log @{LIST}[1:]
25 changes: 17 additions & 8 deletions atest/testdata/variables/nested_item_access.robot
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Test Template Should Be Equal
${LIST} [['item'], [1, 2, (3, [4]), 5], 'third']
${DICT} {'key': {'key': 'value'}, 1: {2: 3}, 'x': {'y': {'z': ''}}}
${MIXED} {'x': [(1, {'y': {'z': ['foo', 'bar', {'': [42]}]}})]}
${STRING} Robot42

*** Test Cases ***
Nested list access
Expand All @@ -28,31 +29,39 @@ Nested access with slicing
${LIST}[1:-1][-1][-2:1:-2][0][0] ${3}

Non-existing nested list item
[Documentation] FAIL List '\${LIST}[1][2]' has no item in index 666.
[Documentation] FAIL Sequence '\${LIST}[1][2]' has no item in index 666.
${LIST}[1][2][666] whatever

Non-existing nested dict item
[Documentation] FAIL Dictionary '\${DICT}[x][y]' has no key 'nonex'.
[Documentation] FAIL Subscriptable '\${DICT}[x][y]' has no key 'nonex'.
${DICT}[x][y][nonex] whatever

Invalid nested list access
[Documentation] FAIL List '\${LIST}[1][2]' used with invalid index 'inv'.
[Documentation] FAIL
... Sequence '\${LIST}[1][2]' used with invalid index 'inv'. To use \
... '[inv]' as a literal value, it needs to be escaped like '\\[inv]'.
${LIST}[1][2][inv] whatever

Invalid nested dict access
[Documentation] FAIL STARTS: Dictionary '\${DICT}[key]' used with invalid key:
[Documentation] FAIL STARTS: Subscriptable '\${DICT}[key]' used with invalid key:
${DICT}[key][${DICT}] whatever

Nested access with non-list/dict
Invalid nested string access
[Documentation] FAIL Sequence '\${STRING}[1]' used with invalid index 'inv'.
${LIST}[1][inv] whatever

Nested access with non-subscriptable
[Documentation] FAIL
... Variable '\${DICT}[key][key]' is string, not list or dictionary, \
... and thus accessing item '0' from it is not possible.
${DICT}[key][key][0] whatever
... Variable '\${DICT}[\${1}][\${2}]' is integer, which is not \
... subscriptable, and thus accessing item '0' from it is not possible. \
... To use '[0]' as a literal value, it needs to be escaped like '\\[0]'.
${DICT}[${1}][${2}][0] whatever

Escape nested
${LIST}[-1]\[0] third[0]
${DICT}[key][key]\[key] value[key]
${DICT}[key]\[key][key] {'key': 'value'}[key][key]
${STRING}[0]\[-1] R[-1]

Nested access doesn't support old `@` and `&` syntax
@{LIST}[0][0] ['item'][0]
Expand Down
63 changes: 39 additions & 24 deletions doc/userguide/src/CreatingTestData/Variables.rst
Original file line number Diff line number Diff line change
Expand Up @@ -284,62 +284,67 @@ are imports, setups and teardowns where dictionaries can be used as arguments.
Accessing list and dictionary items
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It is possible to access items of lists and dictionaries using special
syntax `${var}[item]`. Accessing items is an old feature, but prior to
Robot Framework 3.1 the syntax was `@{var}[item]` with lists and
`&{var}[item]` with dictionaries. The old syntax was deprecated in
It is possible to access items of subscriptable variables, e.g. lists and
dictionaries, using special syntax `${var}[item]`. Accessing items is an old
feature, but prior to Robot Framework 3.1 the syntax was `@{var}[item]` with
lists and `&{var}[item]` with dictionaries. The old syntax was deprecated in
Robot Framework 3.2 and will not be supported in the future.

Accessing list items
''''''''''''''''''''
.. _sequence items:

Accessing sequence items
''''''''''''''''''''''''

It is possible to access a certain item of a list variable with the syntax
`${var}[index]`, where `index` is the index of the selected value. Indices
start from zero, negative indices can be used to access items from the end,
and trying to access an item with too large an index causes an error.
Indices are automatically converted to integers, and it is also possible to
use variables as indices. List items accessed in this manner can be used
similarly as scalar variables.
It is possible to access a certain item of a `sequence`__ variable (e.g. list,
string and bytes) with the syntax `${var}[index]`, where `index` is the index of
the selected value. Indices start from zero, negative indices can be used to
access items from the end, and trying to access an item with too large an index
causes an error. Indices are automatically converted to integers, and it is also
possible to use variables as indices. Sequence items accessed in this manner can
be used similarly as scalar variables.

.. sourcecode:: robotframework

*** Test Cases ***
List variable item
Sequence variable item
Login ${USER}[0] ${USER}[1]
Title Should Be Welcome ${USER}[0]!

Negative index
Log ${LIST}[-1]
Log ${SEQUENCE}[-1]

Index defined as variable
Log ${LIST}[${INDEX}]
Log ${SEQUENCE}[${INDEX}]

List item access supports also the `same "slice" functionality as Python`__
Sequence item access supports also the `same "slice" functionality as Python`__
with syntax like `${var}[1:]`. With this syntax you do not get a single
item but a slice of the original list. Same way as with Python you can
item but a slice of the original sequence. Same way as with Python you can
specify the start index, the end index, and the step:

.. sourcecode:: robotframework

*** Test Cases ***
Start index
Keyword ${LIST}[1:]
Keyword ${SEQUENCE}[1:]

End index
Keyword ${LIST}[:4]
Keyword ${SEQUENCE}[:4]

Start and end
Keyword ${LIST}[2:-1]
Keyword ${SEQUENCE}[2:-1]

Step
Keyword ${LIST}[::2]
Keyword ${LIST}[1:-1:10]
Keyword ${SEQUENCE}[::2]
Keyword ${SEQUENCE}[1:-1:10]

.. note:: The slice syntax is new in Robot Framework 3.1 and does not work
with the old `@{var}[index]` syntax.

__ https://docs.python.org/3/glossary.html#term-sequence
__ https://docs.python.org/glossary.html#term-slice

.. _dictionary items:

Accessing individual dictionary items
'''''''''''''''''''''''''''''''''''''

Expand Down Expand Up @@ -367,10 +372,20 @@ for more details about this syntax.
Login ${USER.name} ${USER.password}
Title Should Be Welcome ${USER.name}!

Accessing items of a custom object
''''''''''''''''''''''''''''''''''

It is possible to access items of an object of a class that implements the
`__getitem__()`__ method. Depending on the implementation by the class, it is
handled the same as accessing either `sequence items`_ or `dictionary items`_
as explained in the two subsections above.

__ https://docs.python.org/3/reference/datamodel.html#object.__getitem__

Nested item access
''''''''''''''''''

Also nested list and dictionary structures can be accessed using the same
Also nested subscriptable variables can be accessed using the same
item access syntax like `${var}[item1][item2]`. This is especially useful
when working with JSON data often returned by REST services. For example,
if a variable `${DATA}` contains `[{'id': 1, 'name': 'Robot'},
Expand Down
Loading