diff options
Diffstat (limited to 'mesonbuild/interpreter/interpreter.py')
-rw-r--r-- | mesonbuild/interpreter/interpreter.py | 116 |
1 files changed, 49 insertions, 67 deletions
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 5b58f2c..1a7d2fc 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -188,17 +188,24 @@ known_build_target_kwargs = ( {'target_type'} ) -permitted_test_kwargs = { - 'args', - 'depends', - 'env', - 'priority', - 'protocol', - 'should_fail', - 'suite', - 'timeout', - 'workdir', -} +TEST_KWARGS: T.List[KwargInfo] = [ + KwargInfo('args', ContainerTypeInfo(list, (str, mesonlib.File, TargetHolder)), + listify=True, default=[]), + KwargInfo('should_fail', bool, default=False), + KwargInfo('timeout', int, default=30), + KwargInfo('workdir', str, default=None, + validator=lambda x: 'must be an absolute path' if not os.path.isabs(x) else None), + KwargInfo('protocol', str, + default='exitcode', + validator=lambda x: 'value must be one of "exitcode", "tap", "gtest", "rust"' if x not in {'exitcode', 'tap', 'gtest', 'rust'} else None, + since_values={'gtest': '0.55.0', 'rust': '0.57.0'}), + KwargInfo('depends', ContainerTypeInfo(list, (CustomTargetHolder, BuildTargetHolder)), + listify=True, default=[], since='0.46.0'), + KwargInfo('priority', int, default=0, since='0.52.0'), + # TODO: env needs reworks of the way the environment variable holder itself works probably + KwargInfo('env', (EnvironmentVariablesHolder, list, dict, str)), + KwargInfo('suite', ContainerTypeInfo(list, str), listify=True, default=['']), # yes, a list of empty string +] permitted_dependency_kwargs = { 'allow_fallback', @@ -1952,30 +1959,21 @@ This will become a hard error in the future.''' % kwargs['input'], location=self self.generators.append(gen) return gen - @FeatureNewKwargs('benchmark', '0.46.0', ['depends']) - @FeatureNewKwargs('benchmark', '0.52.0', ['priority']) - @permittedKwargs(permitted_test_kwargs) @typed_pos_args('benchmark', str, (ExecutableHolder, JarHolder, ExternalProgramHolder, mesonlib.File)) - def func_benchmark(self, node: mparser.FunctionNode, + @typed_kwargs('benchmark', *TEST_KWARGS) + def func_benchmark(self, node: mparser.BaseNode, args: T.Tuple[str, T.Union[ExecutableHolder, JarHolder, ExternalProgramHolder, mesonlib.File]], - kwargs) -> None: - # is_parallel isn't valid here, so make sure it isn't passed - if 'is_parallel' in kwargs: - del kwargs['is_parallel'] + kwargs: 'kwargs.FuncBenchmark') -> None: self.add_test(node, args, kwargs, False) - @FeatureNewKwargs('test', '0.46.0', ['depends']) - @FeatureNewKwargs('test', '0.52.0', ['priority']) - @permittedKwargs(permitted_test_kwargs | {'is_parallel'}) @typed_pos_args('test', str, (ExecutableHolder, JarHolder, ExternalProgramHolder, mesonlib.File)) - def func_test(self, node: mparser.FunctionNode, + @typed_kwargs('benchmark', *TEST_KWARGS, KwargInfo('is_parallel', bool, default=True)) + def func_test(self, node: mparser.BaseNode, args: T.Tuple[str, T.Union[ExecutableHolder, JarHolder, ExternalProgramHolder, mesonlib.File]], - kwargs) -> None: - if kwargs.get('protocol') == 'gtest': - FeatureNew.single_use('"gtest" protocol for tests', '0.55.0', self.subproject) + kwargs: 'kwargs.FuncTest') -> None: self.add_test(node, args, kwargs, True) - def unpack_env_kwarg(self, kwargs) -> build.EnvironmentVariables: + def unpack_env_kwarg(self, kwargs: T.Union[EnvironmentVariablesHolder, T.Dict[str, str], T.List[str]]) -> build.EnvironmentVariables: envlist = kwargs.get('env', EnvironmentVariablesHolder()) if isinstance(envlist, EnvironmentVariablesHolder): env = envlist.held_object @@ -1989,9 +1987,9 @@ This will become a hard error in the future.''' % kwargs['input'], location=self env = env.held_object return env - def make_test(self, node: mparser.FunctionNode, + def make_test(self, node: mparser.BaseNode, args: T.Tuple[str, T.Union[ExecutableHolder, JarHolder, ExternalProgramHolder, mesonlib.File]], - kwargs: T.Dict[str, T.Any]) -> Test: + kwargs: 'kwargs.BaseTest') -> Test: name = args[0] if ':' in name: mlog.deprecation(f'":" is not allowed in test name "{name}", it has been replaced with "_"', @@ -2001,48 +1999,32 @@ This will become a hard error in the future.''' % kwargs['input'], location=self if isinstance(exe, mesonlib.File): exe = self.func_find_program(node, args[1], {}) - par = kwargs.get('is_parallel', True) - if not isinstance(par, bool): - raise InterpreterException('Keyword argument is_parallel must be a boolean.') - cmd_args = unholder(extract_as_list(kwargs, 'args')) - for i in cmd_args: - if not isinstance(i, (str, mesonlib.File, build.Target)): - raise InterpreterException('Command line arguments must be strings, files or targets.') env = self.unpack_env_kwarg(kwargs) - should_fail = kwargs.get('should_fail', False) - if not isinstance(should_fail, bool): - raise InterpreterException('Keyword argument should_fail must be a boolean.') - timeout = kwargs.get('timeout', 30) - if not isinstance(timeout, int): - raise InterpreterException('Timeout must be an integer.') - if timeout <= 0: - FeatureNew('test() timeout <= 0', '0.57.0').use(self.subproject) - if 'workdir' in kwargs: - workdir = kwargs['workdir'] - if not isinstance(workdir, str): - raise InterpreterException('Workdir keyword argument must be a string.') - if not os.path.isabs(workdir): - raise InterpreterException('Workdir keyword argument must be an absolute path.') - else: - workdir = None - protocol = kwargs.get('protocol', 'exitcode') - if protocol not in {'exitcode', 'tap', 'gtest', 'rust'}: - raise InterpreterException('Protocol must be one of "exitcode", "tap", "gtest", or "rust".') - suite = [] + + if kwargs['timeout'] <= 0: + FeatureNew.single_use('test() timeout <= 0', '0.57.0', self.subproject) + prj = self.subproject if self.is_subproject() else self.build.project_name - for s in mesonlib.stringlistify(kwargs.get('suite', '')): - if len(s) > 0: + + suite: T.List[str] = [] + for s in kwargs['suite']: + if s: s = ':' + s suite.append(prj.replace(' ', '_').replace(':', '_') + s) - depends = unholder(extract_as_list(kwargs, 'depends')) - for dep in depends: - if not isinstance(dep, (build.CustomTarget, build.BuildTarget)): - raise InterpreterException('Depends items must be build targets.') - priority = kwargs.get('priority', 0) - if not isinstance(priority, int): - raise InterpreterException('Keyword argument priority must be an integer.') - return Test(name, prj, suite, exe.held_object, depends, par, cmd_args, - env, should_fail, timeout, workdir, protocol, priority) + + return Test(name, + prj, + suite, + exe.held_object, + [d.held_object for d in kwargs['depends']], + kwargs.get('is_parallel', False), + [c.held_object if isinstance(c, ObjectHolder) else c for c in kwargs['args']], + env, + kwargs['should_fail'], + kwargs['timeout'], + kwargs['workdir'], + kwargs['protocol'], + kwargs['priority']) def add_test(self, node: mparser.BaseNode, args: T.List, kwargs: T.Dict[str, T.Any], is_base_test: bool): t = self.make_test(node, args, kwargs) |