diff options
author | Mathieu Duponchelle <mathieu@centricular.com> | 2018-04-27 00:33:20 +0200 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek.chauhan@gmail.com> | 2018-05-04 15:24:21 +0000 |
commit | f1c92d7c9cafd13877f34746d2cb7d1f79d853dd (patch) | |
tree | 951b2a03dfae8b293a6fd04c0a11568e495092df /mesonbuild | |
parent | 8b9fe0efffae288e83b60fb722a3ec25f96a335a (diff) | |
download | meson-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.py | 9 | ||||
-rw-r--r-- | mesonbuild/interpreterbase.py | 49 | ||||
-rw-r--r-- | mesonbuild/modules/python.py | 4 | ||||
-rw-r--r-- | mesonbuild/modules/unstable_icestorm.py | 3 |
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.') |