diff options
author | Mark Asselstine <mark.asselstine@windriver.com> | 2022-11-07 11:46:52 -0500 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-11-10 14:43:06 +0000 |
commit | 361ae80a31649594a6be2ae7a237206d18291d67 (patch) | |
tree | 85654591a80aab34ddfbb918766396d328b7a507 /bitbake/lib/bb/tests | |
parent | ac9ea453b34fe8f438af07c28441dba9d4e77531 (diff) | |
download | poky-361ae80a31649594a6be2ae7a237206d18291d67.tar.gz |
bitbake: data_smart: allow python snippets to include a dictionary
[YOCTO #14917]
Attempting to use a dictionary in a python code snippet for variable
assignment results in an error. For example attempting something such
as
IDX = "green"
VAL = "${@{ 'green': 1, 'blue': 2 }[d.getVar('IDX')]}"
produces the error
expansion of VAL threw ExpansionError: Failure expanding variable
VAL, expression was ${@{ 'green': 1, 'blue': 2 }[d.getVar('IDX')]}
which triggered exception SyntaxError: '{' was never closed (Var
<VAL>, line 1)
The existing __expand_python_regexp__, "\${@.+?}", will match the
first close curly bracket encountered, resulting in incomplete and
un-parsable code, and thus produce the error. We can correct this by
allowing a single depth of nested curly brackets in
__expand_python_regexp__ by using "\${@(?:{.*?}|.)+?}", which will
match up to and including the matching close curly bracket to the
open, '${@', curly bracket, even if there are one or more singly
nested curly brackets present. This change allows the usecase
described above to function.
This change can't be made on its own though. The old regex would, in
an obscure way, handle the case where a python snippet contained an
unexpandable variable. Since the unexpandable variable is in curly
brackets it would cause incomplete/un-parsable python code and thus
remain unparsed. So something like
VAL = "${@d.getVar('foo') + ${unsetvar}}"
would remain unparsed as the close curly bracket in "${unsetvar}"
would match and terminate the snippet prematurely. This quirk resulted
in the proper handling of python snippets with unexpanded
variables. With the change to __expand_python_regexp__ the full
snippet will match and be parsed, but to match the old/correct
behavior we would not want to parse it until ${unsetvar} can be
expanded. To ensure the old/correct behavior for python snippets with
unexpanded variables remains in place we add a check for unexpanded
variables in the python snippets before running them.
This handling of unparsed variables brings two benefits. The first we
now have an explicit check visible to all for unexpanded variables
instead of a somewhat hidden behavior. The second is that if there are
multiple python snippets the old behavior would run the code for each
but a single snippet with unexpanded variables would mean all snippets
would remain unparsed, meaning more and repeated processing at a later
time.
For example:
"${@2*2},${@d.getVar('foo') ${unsetvar}}"
old behavior would give:
"${@2*2},${@d.getVar('foo') ${unsetvar}}"
new behavior will give:
"4,${@d.getVar('foo') ${unsetvar}}"
The old behavior would calculate '2*2' but toss the result when the
second snippet would fail to parse resulting in future recalculations
(or fetching from cache), while the new behavior avoids this.
(Bitbake rev: 94e49b9b9e409c29eb04603b1305d96ebe661a4b)
Signed-off-by: Mark Asselstine <mark.asselstine@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/tests')
-rw-r--r-- | bitbake/lib/bb/tests/data.py | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/bitbake/lib/bb/tests/data.py b/bitbake/lib/bb/tests/data.py index e667c7c7d3..8c043b709d 100644 --- a/bitbake/lib/bb/tests/data.py +++ b/bitbake/lib/bb/tests/data.py | |||
@@ -60,6 +60,15 @@ class DataExpansions(unittest.TestCase): | |||
60 | val = self.d.expand("${@5*12}") | 60 | val = self.d.expand("${@5*12}") |
61 | self.assertEqual(str(val), "60") | 61 | self.assertEqual(str(val), "60") |
62 | 62 | ||
63 | def test_python_snippet_w_dict(self): | ||
64 | val = self.d.expand("${@{ 'green': 1, 'blue': 2 }['green']}") | ||
65 | self.assertEqual(str(val), "1") | ||
66 | |||
67 | def test_python_unexpanded_multi(self): | ||
68 | self.d.setVar("bar", "${unsetvar}") | ||
69 | val = self.d.expand("${@2*2},${foo},${@d.getVar('foo') + ' ${bar}'},${foo}") | ||
70 | self.assertEqual(str(val), "4,value_of_foo,${@d.getVar('foo') + ' ${unsetvar}'},value_of_foo") | ||
71 | |||
63 | def test_expand_in_python_snippet(self): | 72 | def test_expand_in_python_snippet(self): |
64 | val = self.d.expand("${@'boo ' + '${foo}'}") | 73 | val = self.d.expand("${@'boo ' + '${foo}'}") |
65 | self.assertEqual(str(val), "boo value_of_foo") | 74 | self.assertEqual(str(val), "boo value_of_foo") |