aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2018-07-18 09:57:34 -0400
committerJussi Pakkanen <jpakkane@gmail.com>2018-08-14 23:46:42 +0300
commit4f088365e49d28e0d413d42eb024c3ff6cbfee35 (patch)
tree819356912328d5ffd278fbad2f63bc29b2d12e11
parent219dec39c09789f2b296e5af00305fe05fa3362b (diff)
downloadmeson-4f088365e49d28e0d413d42eb024c3ff6cbfee35.zip
meson-4f088365e49d28e0d413d42eb024c3ff6cbfee35.tar.gz
meson-4f088365e49d28e0d413d42eb024c3ff6cbfee35.tar.bz2
interpreter: Add support for dict addition
-rw-r--r--docs/markdown/Reference-manual.md3
-rw-r--r--docs/markdown/snippets/dict_add.md10
-rw-r--r--mesonbuild/interpreterbase.py14
-rw-r--r--test cases/common/197 dict/meson.build12
4 files changed, 35 insertions, 4 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index a7b8a2b..3ae740d 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1859,6 +1859,9 @@ statement](Syntax.md#foreach-statements).
Dictionaries are available since 0.47.0.
+Since 0.48.0 dictionaries can be added (e.g. `d1 = d2 + d3` and `d1 += d2`).
+Values from the second dictionary overrides values from the first.
+
## Returned objects
These are objects returned by the [functions listed above](#functions).
diff --git a/docs/markdown/snippets/dict_add.md b/docs/markdown/snippets/dict_add.md
new file mode 100644
index 0000000..cde5b57
--- /dev/null
+++ b/docs/markdown/snippets/dict_add.md
@@ -0,0 +1,10 @@
+## Dictionary addition
+
+Dictionaries can now be added, values from the second dictionary overrides values
+from the first
+
+```meson
+d1 = {'a' : 'b'}
+d3 = d1 + {'a' : 'c'}
+d3 += {'d' : 'e'}
+```
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py
index fd732bc..1c74eeb 100644
--- a/mesonbuild/interpreterbase.py
+++ b/mesonbuild/interpreterbase.py
@@ -573,6 +573,8 @@ The result of this is undefined and will become a hard error in a future Meson r
return r
if cur.operation == 'add':
+ if isinstance(l, dict) and isinstance(r, dict):
+ return {**l, **r}
try:
return l + r
except Exception as e:
@@ -651,14 +653,18 @@ The result of this is undefined and will become a hard error in a future Meson r
if not isinstance(addition, int):
raise InvalidArguments('The += operator requires an int on the right hand side if the variable on the left is an int')
new_value = old_variable + addition
- elif not isinstance(old_variable, list):
- raise InvalidArguments('The += operator currently only works with arrays, strings or ints ')
- # Add other data types here.
- else:
+ elif isinstance(old_variable, list):
if isinstance(addition, list):
new_value = old_variable + addition
else:
new_value = old_variable + [addition]
+ elif isinstance(old_variable, dict):
+ if not isinstance(addition, dict):
+ raise InvalidArguments('The += operator requires a dict on the right hand side if the variable on the left is a dict')
+ new_value = {**old_variable, **addition}
+ # Add other data types here.
+ else:
+ raise InvalidArguments('The += operator currently only works with arrays, dicts, strings or ints ')
self.set_variable(varname, new_value)
def evaluate_indexing(self, node):
diff --git a/test cases/common/197 dict/meson.build b/test cases/common/197 dict/meson.build
index e1ee2e3..41eea31 100644
--- a/test cases/common/197 dict/meson.build
+++ b/test cases/common/197 dict/meson.build
@@ -21,3 +21,15 @@ empty_dict = {}
foreach key, value : empty_dict
assert(false, 'This dict should be empty')
endforeach
+
+d1 = empty_dict + {'a' : 'b'}
+assert(d1 == {'a' : 'b'}, 'dict addition is not working')
+
+d2 = d1 + {'a' : 'b2', 'c' : 'd'}
+assert(d2 == {'a' : 'b2', 'c' : 'd'}, 'dict addition is not working')
+assert(d1 == {'a' : 'b'}, 'dict should be immutable')
+
+d3 = d2
+d3 += {'e' : 'f'}
+assert(d3 == {'a' : 'b2', 'c' : 'd', 'e' : 'f'}, 'dict plusassign is not working')
+assert(d2 == {'a' : 'b2', 'c' : 'd'}, 'dict should be immutable')