aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorMathieu Duponchelle <mathieu@centricular.com>2018-04-27 00:33:20 +0200
committerNirbheek Chauhan <nirbheek.chauhan@gmail.com>2018-05-04 15:24:21 +0000
commitf1c92d7c9cafd13877f34746d2cb7d1f79d853dd (patch)
tree951b2a03dfae8b293a6fd04c0a11568e495092df /mesonbuild
parent8b9fe0efffae288e83b60fb722a3ec25f96a335a (diff)
downloadmeson-f1c92d7c9cafd13877f34746d2cb7d1f79d853dd.zip
meson-f1c92d7c9cafd13877f34746d2cb7d1f79d853dd.tar.gz
meson-f1c92d7c9cafd13877f34746d2cb7d1f79d853dd.tar.bz2
Interpreter: don't flatten the arguments of various methods
this fixes eg set_variable('foo', ['bar', 'baz']), which was previously erroring out complaining about the number of arguments. Closes #1481
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/interpreter.py9
-rw-r--r--mesonbuild/interpreterbase.py49
-rw-r--r--mesonbuild/modules/python.py4
-rw-r--r--mesonbuild/modules/unstable_icestorm.py3
4 files changed, 44 insertions, 21 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 24f53e2..7324f67 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -25,7 +25,7 @@ from .mesonlib import FileMode, Popen_safe, listify, extract_as_list, has_path_s
from .dependencies import ExternalProgram
from .dependencies import InternalDependency, Dependency, NotFoundDependency, DependencyException
from .interpreterbase import InterpreterBase
-from .interpreterbase import check_stringlist, noPosargs, noKwargs, stringArgs, permittedKwargs
+from .interpreterbase import check_stringlist, flatten, noPosargs, noKwargs, stringArgs, permittedKwargs, noArgsFlattening
from .interpreterbase import InterpreterException, InvalidArguments, InvalidCode, SubdirDoneRequest
from .interpreterbase import InterpreterObject, MutableInterpreterObject, Disabler
from .modules import ModuleReturnValue
@@ -225,6 +225,7 @@ class ConfigurationDataHolder(MutableInterpreterObject, ObjectHolder):
return name, val, desc
+ @noArgsFlattening
def set_method(self, args, kwargs):
(name, val, desc) = self.validate_args(args, kwargs)
self.held_object.values[name] = (val, desc)
@@ -246,6 +247,7 @@ class ConfigurationDataHolder(MutableInterpreterObject, ObjectHolder):
def has_method(self, args, kwargs):
return args[0] in self.held_object.values
+ @noArgsFlattening
def get_method(self, args, kwargs):
if len(args) < 1 or len(args) > 2:
raise InterpreterException('Get method takes one or two arguments.')
@@ -1389,6 +1391,8 @@ class ModuleHolder(InterpreterObject, ObjectHolder):
raise InvalidArguments('Module %s does not have method %s.' % (self.modname, method_name))
if method_name.startswith('_'):
raise InvalidArguments('Function {!r} in module {!r} is private.'.format(method_name, self.modname))
+ if not getattr(fn, 'no-args-flattening', False):
+ args = flatten(args)
# This is not 100% reliable but we can't use hash()
# because the Build object contains dicts and lists.
num_targets = len(self.interpreter.build.targets)
@@ -1618,6 +1622,7 @@ class MesonMain(InterpreterObject):
def project_name_method(self, args, kwargs):
return self.interpreter.active_projectname
+ @noArgsFlattening
@permittedKwargs({})
def get_cross_property_method(self, args, kwargs):
if len(args) < 1 or len(args) > 2:
@@ -3617,6 +3622,7 @@ This will become a hard error in the future.''')
return self.subproject != ''
@noKwargs
+ @noArgsFlattening
def func_set_variable(self, node, args, kwargs):
if len(args) != 2:
raise InvalidCode('Set_variable takes two arguments.')
@@ -3625,6 +3631,7 @@ This will become a hard error in the future.''')
self.set_variable(varname, value)
@noKwargs
+ @noArgsFlattening
def func_get_variable(self, node, args, kwargs):
if len(args) < 1 or len(args) > 2:
raise InvalidCode('Get_variable takes one or two arguments.')
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py
index bedcf26..60b0465 100644
--- a/mesonbuild/interpreterbase.py
+++ b/mesonbuild/interpreterbase.py
@@ -51,6 +51,22 @@ def _get_callee_args(wrapped_args):
kwargs = kwargs if kwargs is not None else {}
return s, node_or_state, args, kwargs
+def flatten(args):
+ if isinstance(args, mparser.StringNode):
+ return args.value
+ if isinstance(args, (int, str, mesonlib.File, InterpreterObject)):
+ return args
+ result = []
+ for a in args:
+ if isinstance(a, list):
+ rest = flatten(a)
+ result = result + rest
+ elif isinstance(a, mparser.StringNode):
+ result.append(a.value)
+ else:
+ result.append(a)
+ return result
+
def noPosargs(f):
@wraps(f)
def wrapped(*wrapped_args, **wrapped_kwargs):
@@ -78,6 +94,10 @@ def stringArgs(f):
return f(*wrapped_args, **wrapped_kwargs)
return wrapped
+def noArgsFlattening(f):
+ setattr(f, 'no-args-flattening', True)
+ return f
+
class permittedKwargs:
def __init__(self, permitted):
@@ -121,7 +141,10 @@ class InterpreterObject:
def method_call(self, method_name, args, kwargs):
if method_name in self.methods:
- return self.methods[method_name](args, kwargs)
+ method = self.methods[method_name]
+ if not getattr(method, 'no-args-flattening', False):
+ args = flatten(args)
+ return method(args, kwargs)
raise InvalidCode('Unknown method "%s" in object.' % method_name)
class MutableInterpreterObject(InterpreterObject):
@@ -481,7 +504,11 @@ The result of this is undefined and will become a hard error in a future Meson r
if is_disabled(posargs, kwargs):
return Disabler()
if func_name in self.funcs:
- return self.funcs[func_name](node, self.flatten(posargs), kwargs)
+ func = self.funcs[func_name]
+ if not getattr(func, 'no-args-flattening', False):
+ posargs = flatten(posargs)
+
+ return func(node, posargs, kwargs)
else:
self.unknown_function_called(func_name)
@@ -515,7 +542,7 @@ The result of this is undefined and will become a hard error in a future Meson r
return Disabler()
if method_name == 'extract_objects':
self.validate_extraction(obj.held_object)
- return obj.method_call(method_name, self.flatten(args), kwargs)
+ return obj.method_call(method_name, args, kwargs)
def bool_method_call(self, obj, method_name, args):
(posargs, kwargs) = self.reduce_arguments(args)
@@ -675,22 +702,6 @@ The result of this is undefined and will become a hard error in a future Meson r
self.argument_depth -= 1
return reduced_pos, reduced_kw
- def flatten(self, args):
- if isinstance(args, mparser.StringNode):
- return args.value
- if isinstance(args, (int, str, mesonlib.File, InterpreterObject)):
- return args
- result = []
- for a in args:
- if isinstance(a, list):
- rest = self.flatten(a)
- result = result + rest
- elif isinstance(a, mparser.StringNode):
- result.append(a.value)
- else:
- result.append(a)
- return result
-
def assignment(self, node):
assert(isinstance(node, mparser.AssignmentNode))
if self.argument_depth != 0:
diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py
index 0e569a0..a705109 100644
--- a/mesonbuild/modules/python.py
+++ b/mesonbuild/modules/python.py
@@ -25,6 +25,7 @@ from ..interpreterbase import (
InterpreterObject, InvalidArguments
)
from ..interpreter import ExternalProgramHolder
+from ..interpreterbase import flatten
from ..build import known_shmod_kwargs
from .. import mlog
from ..environment import detect_cpu_family
@@ -415,6 +416,9 @@ class PythonInstallation(ExternalProgramHolder, InterpreterObject):
except AttributeError:
raise InvalidArguments('Python object does not have method %s.' % method_name)
+ if not getattr(fn, 'no-args-flattening', False):
+ args = flatten(args)
+
if method_name in ['extension_module', 'dependency', 'install_sources']:
value = fn(self.interpreter, None, args, kwargs)
return self.interpreter.holderify(value)
diff --git a/mesonbuild/modules/unstable_icestorm.py b/mesonbuild/modules/unstable_icestorm.py
index 55c647f..bf06314 100644
--- a/mesonbuild/modules/unstable_icestorm.py
+++ b/mesonbuild/modules/unstable_icestorm.py
@@ -13,6 +13,7 @@
# limitations under the License.
from .. import mesonlib
+from ..interpreterbase import flatten
from . import ExtensionModule
@@ -42,7 +43,7 @@ class IceStormModule(ExtensionModule):
kwarg_sources = kwargs.get('sources', [])
if not isinstance(kwarg_sources, list):
kwarg_sources = [kwarg_sources]
- all_sources = interpreter.source_strings_to_files(interpreter.flatten(arg_sources + kwarg_sources))
+ all_sources = interpreter.source_strings_to_files(flatten(arg_sources + kwarg_sources))
if 'constraint_file' not in kwargs:
raise mesonlib.MesonException('Constraint file not specified.')