aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mensinger <daniel@mensinger-ka.de>2021-06-19 18:02:19 +0200
committerDaniel Mensinger <daniel@mensinger-ka.de>2021-06-20 00:26:02 +0200
commitf1ac7db2e657c77b4319cbcd0bfbdef489dec802 (patch)
tree49c13b9e7bdb8fae377d8888cc19a495409637d5
parent2e8729a7e6cee460f8e75e231ecdd01933fbd277 (diff)
downloadmeson-f1ac7db2e657c77b4319cbcd0bfbdef489dec802.zip
meson-f1ac7db2e657c77b4319cbcd0bfbdef489dec802.tar.gz
meson-f1ac7db2e657c77b4319cbcd0bfbdef489dec802.tar.bz2
fix: Fix set_variable not holderifying (fixes #8904)
-rw-r--r--mesonbuild/interpreter/interpreter.py2
-rw-r--r--mesonbuild/interpreterbase/interpreterbase.py27
-rw-r--r--test cases/common/242 set and get variable/meson.build37
-rw-r--r--test cases/common/242 set and get variable/test1.txt0
-rw-r--r--test cases/common/242 set and get variable/test2.txt0
5 files changed, 58 insertions, 8 deletions
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index be17c9a..482ba82 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -2671,7 +2671,7 @@ This will become a hard error in the future.''', location=self.current_node)
if len(args) != 2:
raise InvalidCode('Set_variable takes two arguments.')
varname, value = args
- self.set_variable(varname, value)
+ self.set_variable(varname, value, holderify=True)
@noKwargs
@noArgsFlattening
diff --git a/mesonbuild/interpreterbase/interpreterbase.py b/mesonbuild/interpreterbase/interpreterbase.py
index 0acb699..8ef13c9 100644
--- a/mesonbuild/interpreterbase/interpreterbase.py
+++ b/mesonbuild/interpreterbase/interpreterbase.py
@@ -16,7 +16,7 @@
# or an interpreter-based tool.
from .. import mparser, mesonlib, mlog
-from .. import environment, dependencies
+from .. import environment
from .baseobjects import (
InterpreterObject,
@@ -592,7 +592,7 @@ The result of this is undefined and will become a hard error in a future Meson r
obj.current_node = node
return self._holderify(obj.method_call(method_name, args, kwargs))
- def _holderify(self, res: T.Optional[TYPE_var]) -> T.Union[TYPE_elementary, InterpreterObject]:
+ def _holderify(self, res: T.Union[TYPE_var, InterpreterObject, None]) -> T.Union[TYPE_elementary, InterpreterObject]:
if res is None:
return None
if isinstance(res, (int, bool, str)):
@@ -909,20 +909,34 @@ To specify a keyword argument, use : instead of =.''')
raise InvalidArguments('Tried to assign value to a non-variable.')
value = self.evaluate_statement(node.value)
if not self.is_assignable(value):
- raise InvalidCode('Tried to assign an invalid value to variable.')
+ raise InvalidCode(f'Tried to assign the invalid value "{value}" of type {type(value).__name__} to variable.')
# For mutable objects we need to make a copy on assignment
if isinstance(value, MutableInterpreterObject):
value = copy.deepcopy(value)
self.set_variable(var_name, value)
return None
- def set_variable(self, varname: str, variable: T.Union[TYPE_var, InterpreterObject]) -> None:
+ def set_variable(self, varname: str, variable: T.Union[TYPE_var, InterpreterObject], *, holderify: bool = False) -> None:
if variable is None:
raise InvalidCode('Can not assign None to variable.')
+ if holderify:
+ variable = self._holderify(variable)
+ else:
+ # Ensure that we are never storing a HoldableObject
+ def check(x: T.Union[TYPE_var, InterpreterObject]) -> None:
+ if isinstance(x, mesonlib.HoldableObject):
+ raise mesonlib.MesonBugException(f'set_variable in InterpreterBase called with a HoldableObject {x} of type {type(x).__name__}')
+ elif isinstance(x, list):
+ for y in x:
+ check(y)
+ elif isinstance(x, dict):
+ for v in x.values():
+ check(v)
+ check(variable)
if not isinstance(varname, str):
raise InvalidCode('First argument to set_variable must be a string.')
if not self.is_assignable(variable):
- raise InvalidCode('Assigned value not of assignable type.')
+ raise InvalidCode(f'Assigned value "{variable}" of type {type(variable).__name__} is not an assignable type.')
if re.match('[_a-zA-Z][_0-9a-zA-Z]*$', varname) is None:
raise InvalidCode('Invalid variable name: ' + varname)
if varname in self.builtin:
@@ -937,8 +951,7 @@ To specify a keyword argument, use : instead of =.''')
raise InvalidCode('Unknown variable "%s".' % varname)
def is_assignable(self, value: T.Any) -> bool:
- return isinstance(value, (InterpreterObject, dependencies.Dependency,
- str, int, list, dict, mesonlib.File))
+ return isinstance(value, (InterpreterObject, str, int, list, dict))
def validate_extraction(self, buildtarget: mesonlib.HoldableObject) -> None:
raise InterpreterException('validate_extraction is not implemented in this context (please file a bug)')
diff --git a/test cases/common/242 set and get variable/meson.build b/test cases/common/242 set and get variable/meson.build
new file mode 100644
index 0000000..ae6dadc
--- /dev/null
+++ b/test cases/common/242 set and get variable/meson.build
@@ -0,0 +1,37 @@
+project('set and get')
+
+var1 = 'test1.txt'
+var2 = files('test1.txt')
+
+# Use is_disabler for accessing variables
+assert(var1 == 'test1.txt')
+assert(not is_disabler(var2))
+
+# Ensure that set variables behave correctly
+set_variable('var3', 'test2.txt')
+set_variable('var4', files('test2.txt'))
+
+assert(var3 == 'test2.txt')
+assert(not is_disabler(var4))
+
+# Test get_variable directly
+assert(get_variable('var1') == 'test1.txt')
+assert(not is_disabler(get_variable('var2')))
+assert(get_variable('var3') == 'test2.txt')
+assert(not is_disabler(get_variable('var4')))
+
+# Test get_variable indirectly
+
+var5 = get_variable('var1')
+var6 = get_variable('var2')
+var7 = get_variable('var3')
+var8 = get_variable('var4')
+set_variable('var9', get_variable('var7'))
+set_variable('var0', get_variable('var8'))
+
+assert(var5 == 'test1.txt')
+assert(not is_disabler(var6))
+assert(var7 == 'test2.txt')
+assert(not is_disabler(var8))
+assert(get_variable('var9') == 'test2.txt')
+assert(not is_disabler(get_variable('var0')))
diff --git a/test cases/common/242 set and get variable/test1.txt b/test cases/common/242 set and get variable/test1.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/242 set and get variable/test1.txt
diff --git a/test cases/common/242 set and get variable/test2.txt b/test cases/common/242 set and get variable/test2.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/242 set and get variable/test2.txt