diff options
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/interpreter/interpreter.py | 43 | ||||
-rw-r--r-- | mesonbuild/interpreter/interpreterobjects.py | 44 | ||||
-rw-r--r-- | mesonbuild/interpreter/kwargs.py | 3 | ||||
-rw-r--r-- | mesonbuild/interpreter/mesonmain.py | 15 |
4 files changed, 42 insertions, 63 deletions
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index ec5c75c..d640e65 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -42,7 +42,6 @@ from .mesonmain import MesonMain from .dependencyfallbacks import DependencyFallbacksHolder from .interpreterobjects import ( SubprojectHolder, - EnvironmentVariablesObject, ConfigurationDataObject, Test, RunProcess, @@ -396,6 +395,7 @@ class Interpreter(InterpreterBase, HoldableObject): build.Data: OBJ.DataHolder, build.InstallDir: OBJ.InstallDirHolder, build.IncludeDirs: OBJ.IncludeDirsHolder, + build.EnvironmentVariables: OBJ.EnvironmentVariablesObject, compilers.RunResult: compilerOBJ.TryRunResultHolder, dependencies.ExternalLibrary: OBJ.ExternalLibraryHolder, coredata.UserFeatureOption: OBJ.FeatureOptionHolder, @@ -1723,19 +1723,14 @@ This will become a hard error in the future.''' % kwargs['input'], location=self kwargs: 'kwargs.FuncTest') -> None: self.add_test(node, args, kwargs, True) - def unpack_env_kwarg(self, kwargs: T.Union[EnvironmentVariablesObject, T.Dict[str, str], T.List[str]]) -> build.EnvironmentVariables: - envlist = kwargs.get('env', EnvironmentVariablesObject()) - if isinstance(envlist, EnvironmentVariablesObject): - env = envlist.vars - elif isinstance(envlist, dict): - FeatureNew.single_use('environment dictionary', '0.52.0', self.subproject) - env = EnvironmentVariablesObject(envlist) - env = env.vars - else: - # Convert from array to environment object - env = EnvironmentVariablesObject(envlist) - env = env.vars - return env + def unpack_env_kwarg(self, kwargs: T.Union[build.EnvironmentVariables, T.Dict[str, 'TYPE_var'], T.List['TYPE_var'], str]) -> build.EnvironmentVariables: + envlist = kwargs.get('env') + if envlist is None: + return build.EnvironmentVariables() + msg = ENV_KW.validator(envlist) + if msg: + raise InvalidArguments(f'"env": {msg}') + return ENV_KW.convertor(envlist) def make_test(self, node: mparser.BaseNode, args: T.Tuple[str, T.Union[build.Executable, build.Jar, ExternalProgram, mesonlib.File]], @@ -2361,17 +2356,17 @@ This will become a hard error in the future.''' % kwargs['input'], location=self @noKwargs @noArgsFlattening - def func_environment(self, node, args, kwargs): - if len(args) > 1: - raise InterpreterException('environment takes only one optional positional arguments') - elif len(args) == 1: + @typed_pos_args('environment', optargs=[(str, list, dict)]) + def func_environment(self, node: mparser.FunctionNode, args: T.Tuple[T.Union[None, str, T.List['TYPE_var'], T.Dict[str, 'TYPE_var']]], + kwargs: 'TYPE_kwargs') -> build.EnvironmentVariables: + init = args[0] + if init is not None: FeatureNew.single_use('environment positional arguments', '0.52.0', self.subproject) - initial_values = args[0] - if not isinstance(initial_values, dict) and not isinstance(initial_values, list): - raise InterpreterException('environment first argument must be a dictionary or a list') - else: - initial_values = {} - return EnvironmentVariablesObject(initial_values, self.subproject) + msg = ENV_KW.validator(init) + if msg: + raise InvalidArguments(f'"environment": {msg}') + return ENV_KW.convertor(init) + return build.EnvironmentVariables() @typed_pos_args('join_paths', varargs=str, min_varargs=1) @noKwargs diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index c614f09..53a0666 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -229,39 +229,19 @@ class RunProcess(MesonInterpreterObject): def stderr_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> str: return self.stderr -# TODO: Parsing the initial values should be either done directly in the -# `Interpreter` or in `build.EnvironmentVariables`. This way, this class -# can be converted into a pure object holder. -class EnvironmentVariablesObject(MutableInterpreterObject, MesonInterpreterObject): - # TODO: Move the type cheking for initial_values out of this class and replace T.Any - def __init__(self, initial_values: T.Optional[T.Any] = None, subproject: str = ''): - super().__init__(subproject=subproject) - self.vars = build.EnvironmentVariables() + +class EnvironmentVariablesObject(ObjectHolder[build.EnvironmentVariables], MutableInterpreterObject): + + def __init__(self, obj: build.EnvironmentVariables, interpreter: 'Interpreter'): + super().__init__(obj, interpreter) self.methods.update({'set': self.set_method, 'append': self.append_method, 'prepend': self.prepend_method, }) - if isinstance(initial_values, build.EnvironmentVariables): - self.vars = initial_values - elif isinstance(initial_values, dict): - for k, v in initial_values.items(): - self.set_method([k, v], {}) - elif initial_values is not None: - for e in mesonlib.listify(initial_values): - if not isinstance(e, str): - raise InterpreterException('Env var definition must be a list of strings.') - if '=' not in e: - raise InterpreterException('Env var definition must be of type key=val.') - (k, val) = e.split('=', 1) - k = k.strip() - val = val.strip() - if ' ' in k: - raise InterpreterException('Env var key must not have spaces in it.') - self.set_method([k, val], {}) def __repr__(self) -> str: repr_str = "<{0}: {1}>" - return repr_str.format(self.__class__.__name__, self.vars.envvars) + return repr_str.format(self.__class__.__name__, self.held_object.envvars) def unpack_separator(self, kwargs: T.Dict[str, T.Any]) -> str: separator = kwargs.get('separator', os.pathsep) @@ -270,9 +250,13 @@ class EnvironmentVariablesObject(MutableInterpreterObject, MesonInterpreterObjec " argument needs to be a string.") return separator + def __deepcopy__(self, memo: T.Dict[str, object]) -> 'EnvironmentVariablesObject': + # Avoid trying to copy the intepreter + return EnvironmentVariablesObject(copy.deepcopy(self.held_object), self.interpreter) + def warn_if_has_name(self, name: str) -> None: # Multiple append/prepend operations was not supported until 0.58.0. - if self.vars.has_name(name): + if self.held_object.has_name(name): m = f'Overriding previous value of environment variable {name!r} with a new one' FeatureNew('0.58.0', m).use(self.subproject) @@ -282,7 +266,7 @@ class EnvironmentVariablesObject(MutableInterpreterObject, MesonInterpreterObjec def set_method(self, args: T.Tuple[str, T.List[str]], kwargs: T.Dict[str, T.Any]) -> None: name, values = args separator = self.unpack_separator(kwargs) - self.vars.set(name, values, separator) + self.held_object.set(name, values, separator) @stringArgs @permittedKwargs({'separator'}) @@ -291,7 +275,7 @@ class EnvironmentVariablesObject(MutableInterpreterObject, MesonInterpreterObjec name, values = args separator = self.unpack_separator(kwargs) self.warn_if_has_name(name) - self.vars.append(name, values, separator) + self.held_object.append(name, values, separator) @stringArgs @permittedKwargs({'separator'}) @@ -300,7 +284,7 @@ class EnvironmentVariablesObject(MutableInterpreterObject, MesonInterpreterObjec name, values = args separator = self.unpack_separator(kwargs) self.warn_if_has_name(name) - self.vars.prepend(name, values, separator) + self.held_object.prepend(name, values, separator) class ConfigurationDataObject(MutableInterpreterObject, MesonInterpreterObject): diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py index 9eb02be..317f7c6 100644 --- a/mesonbuild/interpreter/kwargs.py +++ b/mesonbuild/interpreter/kwargs.py @@ -11,7 +11,6 @@ from typing_extensions import TypedDict, Literal from .. import build from .. import coredata from ..mesonlib import MachineChoice, File, FileMode, FileOrString -from .interpreterobjects import EnvironmentVariablesObject class FuncAddProjectArgs(TypedDict): @@ -39,7 +38,7 @@ class BaseTest(TypedDict): workdir: T.Optional[str] depends: T.List[T.Union[build.CustomTarget, build.BuildTarget]] priority: int - env: EnvironmentVariablesObject + env: build.EnvironmentVariables suite: T.List[str] diff --git a/mesonbuild/interpreter/mesonmain.py b/mesonbuild/interpreter/mesonmain.py index 5355c47..9c4f50a 100644 --- a/mesonbuild/interpreter/mesonmain.py +++ b/mesonbuild/interpreter/mesonmain.py @@ -7,13 +7,13 @@ from .. import mlog from ..mesonlib import MachineChoice, OptionKey from ..programs import OverrideProgram, ExternalProgram +from ..interpreter.type_checking import ENV_KW from ..interpreterbase import (MesonInterpreterObject, FeatureNew, FeatureDeprecated, typed_pos_args, permittedKwargs, noArgsFlattening, noPosargs, noKwargs, typed_kwargs, KwargInfo, MesonVersionString, InterpreterException) from .interpreterobjects import (ExecutableHolder, ExternalProgramHolder, - CustomTargetHolder, CustomTargetIndexHolder, - EnvironmentVariablesObject) + CustomTargetHolder, CustomTargetIndexHolder) from .type_checking import NATIVE_KW, NoneType import typing as T @@ -415,9 +415,10 @@ class MesonMain(MesonInterpreterObject): @FeatureNew('add_devenv', '0.58.0') @noKwargs - @typed_pos_args('add_devenv', (str, list, dict, EnvironmentVariablesObject)) - def add_devenv_method(self, args: T.Union[str, list, dict, EnvironmentVariablesObject], kwargs: T.Dict[str, T.Any]) -> None: + @typed_pos_args('add_devenv', (str, list, dict, build.EnvironmentVariables)) + def add_devenv_method(self, args: T.Tuple[T.Union[str, list, dict, build.EnvironmentVariables]], kwargs: T.Dict[str, T.Any]) -> None: env = args[0] - if isinstance(env, (str, list, dict)): - env = EnvironmentVariablesObject(env) - self.build.devenv.append(env.vars) + msg = ENV_KW.validator(env) + if msg: + raise build.InvalidArguments(f'"add_devenv": {msg}') + self.build.devenv.append(ENV_KW.convertor(env)) |