diff options
author | Xavier Claessens <xavier.claessens@collabora.com> | 2019-12-03 23:34:47 -0500 |
---|---|---|
committer | Xavier Claessens <xclaesse@gmail.com> | 2019-12-04 16:45:56 -0500 |
commit | 9b1a85747334e3e1c21e9a27f4aa79f7f44c1f2d (patch) | |
tree | 07868682f01264aad85710ee28fa19a9f711c37a /mesonbuild | |
parent | b1c8f765fa6e2af0d185d2a20dc68c7567c916eb (diff) | |
download | meson-9b1a85747334e3e1c21e9a27f4aa79f7f44c1f2d.zip meson-9b1a85747334e3e1c21e9a27f4aa79f7f44c1f2d.tar.gz meson-9b1a85747334e3e1c21e9a27f4aa79f7f44c1f2d.tar.bz2 |
dict: Fully evaluate keys
The only restriction is keys must be string after evaluation. This fix
various inconsistencies.
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/interpreterbase.py | 25 | ||||
-rw-r--r-- | mesonbuild/mparser.py | 14 |
2 files changed, 15 insertions, 24 deletions
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py index 46f578e..2a976d3 100644 --- a/mesonbuild/interpreterbase.py +++ b/mesonbuild/interpreterbase.py @@ -496,7 +496,19 @@ class InterpreterBase: def evaluate_dictstatement(self, cur): (arguments, kwargs) = self.reduce_arguments(cur.args) assert (not arguments) - return kwargs + result = {} + self.argument_depth += 1 + for key, value in kwargs.items(): + if not isinstance(key, mparser.StringNode): + FeatureNew('Dictionary entry using non literal key', '0.53.0').use(self.subproject) + key = self.evaluate_statement(key) + if not isinstance(key, str): + raise InvalidArguments('Key must be a string') + if key in result: + raise InvalidArguments('Duplicate dictionary key: {}'.format(key)) + result[key] = value + self.argument_depth -= 1 + return result def evaluate_notstatement(self, cur): v = self.evaluate_statement(cur.value) @@ -731,16 +743,7 @@ The result of this is undefined and will become a hard error in a future Meson r 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_addition = {} - for (key, value) in addition.items(): - if isinstance(key, str): - new_addition[key] = value - elif isinstance(key, mparser.IdNode) and isinstance(self.get_variable(key.value), str): - FeatureNew('Adding dictionary entry using string variable as key', '0.53.0').use(self.subproject) - new_addition[self.get_variable(key.value)] = value - else: - raise InvalidArguments('Dictionary key must be a string or string variable') - new_value = {**old_variable, **new_addition} + new_value = {**old_variable, **addition} # Add other data types here. else: raise InvalidArguments('The += operator currently only works with arrays, dicts, strings or ints ') diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py index 80ffefd..76ad374 100644 --- a/mesonbuild/mparser.py +++ b/mesonbuild/mparser.py @@ -676,19 +676,7 @@ class Parser: while not isinstance(s, EmptyNode): potential = self.current if self.accept('colon'): - key_value = self.statement() - if isinstance(s, StringNode): - if s.value in a.kwargs: - # + 1 to colno to point to the actual string, not the opening quote - raise ParseException('Duplicate dictionary key: {}'.format(s.value), self.getline(), s.lineno, s.colno + 1) - a.set_kwarg(s.value, key_value) - elif isinstance(s, IdNode) and isinstance(s.value, str): - for key in a.kwargs: - if s.value == key.value: - raise ParseException('Duplicate dictionary variable key: {}'.format(s.value), self.getline(), s.lineno, s.colno) - a.set_kwarg(s, key_value) - else: - raise ParseException('Key must be a string or string variable', self.getline(), s.lineno, s.colno) + a.set_kwarg(s, self.statement()) potential = self.current if not self.accept('comma'): return a |