diff options
author | Dylan Baker <dylan@pnwbakers.com> | 2021-12-06 15:27:45 -0800 |
---|---|---|
committer | Eli Schwartz <eschwartz93@gmail.com> | 2022-01-18 17:53:29 -0500 |
commit | 5074e2d3b5837f64ef008b359e50765675c528ab (patch) | |
tree | ddea2131d2acc9e53c091add12a618ca8d7042fb /mesonbuild | |
parent | 23af9e4c1a77072218bc3123bc1151b4845049d5 (diff) | |
download | meson-5074e2d3b5837f64ef008b359e50765675c528ab.zip meson-5074e2d3b5837f64ef008b359e50765675c528ab.tar.gz meson-5074e2d3b5837f64ef008b359e50765675c528ab.tar.bz2 |
interpreter: replace ConfigurationDataObject with ConfigurationDataHolder
This is much cleaner, and more in line with the way we handle
interpreter objects in modern meson practice
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/interpreter/__init__.py | 4 | ||||
-rw-r--r-- | mesonbuild/interpreter/interpreter.py | 29 | ||||
-rw-r--r-- | mesonbuild/interpreter/interpreterobjects.py | 50 | ||||
-rw-r--r-- | mesonbuild/modules/cmake.py | 8 | ||||
-rw-r--r-- | mesonbuild/modules/sourceset.py | 8 | ||||
-rw-r--r-- | mesonbuild/modules/unstable_simd.py | 6 |
6 files changed, 55 insertions, 50 deletions
diff --git a/mesonbuild/interpreter/__init__.py b/mesonbuild/interpreter/__init__.py index 2269837..016e4dc 100644 --- a/mesonbuild/interpreter/__init__.py +++ b/mesonbuild/interpreter/__init__.py @@ -28,7 +28,7 @@ __all__ = [ 'CustomTargetIndexHolder', 'MachineHolder', 'Test', - 'ConfigurationDataObject', + 'ConfigurationDataHolder', 'SubprojectHolder', 'DependencyHolder', 'GeneratedListHolder', @@ -46,7 +46,7 @@ from .interpreter import Interpreter, permitted_dependency_kwargs from .compiler import CompilerHolder from .interpreterobjects import (ExecutableHolder, BuildTargetHolder, CustomTargetHolder, CustomTargetIndexHolder, MachineHolder, Test, - ConfigurationDataObject, SubprojectHolder, DependencyHolder, + ConfigurationDataHolder, SubprojectHolder, DependencyHolder, GeneratedListHolder, ExternalProgramHolder, extract_required_kwarg) diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index a81f986..bd71f78 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -43,7 +43,6 @@ from .mesonmain import MesonMain from .dependencyfallbacks import DependencyFallbacksHolder from .interpreterobjects import ( SubprojectHolder, - ConfigurationDataObject, Test, RunProcess, extract_required_kwarg, @@ -433,6 +432,7 @@ class Interpreter(InterpreterBase, HoldableObject): dependencies.ExternalLibrary: OBJ.ExternalLibraryHolder, coredata.UserFeatureOption: OBJ.FeatureOptionHolder, envconfig.MachineInfo: OBJ.MachineHolder, + build.ConfigurationData: OBJ.ConfigurationDataHolder, }) ''' @@ -488,7 +488,7 @@ class Interpreter(InterpreterBase, HoldableObject): elif isinstance(v, Test): self.build.tests.append(v) elif isinstance(v, (int, str, bool, Disabler, ObjectHolder, build.GeneratedList, - ExternalProgram)): + ExternalProgram, build.ConfigurationData)): pass else: raise InterpreterException(f'Module returned a value of unknown type {v!r}.') @@ -1020,13 +1020,16 @@ external dependencies (including libraries) must go to "dependencies".''') @typed_pos_args('configuration_data', optargs=[dict]) @noKwargs - def func_configuration_data(self, node: mparser.BaseNode, args: T.Optional[dict], kwargs: 'TYPE_kwargs') -> ConfigurationDataObject: + def func_configuration_data(self, node: mparser.BaseNode, args: T.Tuple[T.Optional[T.Dict[str, T.Any]]], + kwargs: 'TYPE_kwargs') -> build.ConfigurationData: initial_values = args[0] if initial_values is not None: FeatureNew.single_use('configuration_data dictionary', '0.49.0', self.subproject) - else: - initial_values = {} - return ConfigurationDataObject(self.subproject, initial_values) + for k, v in initial_values.items(): + if not isinstance(v, (str, int ,bool)): + raise InvalidArguments( + f'"configuration_data": initial value dictionary key "{k!r}"" must be "str | int | bool", not "{v!r}"') + return build.ConfigurationData(initial_values) def set_backend(self): # The backend is already set when parsing subprojects @@ -2235,8 +2238,12 @@ external dependencies (including libraries) must go to "dependencies".''') conf = kwargs['configuration'] if isinstance(conf, dict): FeatureNew.single_use('configure_file.configuration dictionary', '0.49.0', self.subproject) - conf = ConfigurationDataObject(self.subproject, conf) - elif not isinstance(conf, ConfigurationDataObject): + for k, v in conf.items(): + if not isinstance(v, (str, int ,bool)): + raise InvalidArguments( + f'"configuration_data": initial value dictionary key "{k!r}"" must be "str | int | bool", not "{v!r}"') + conf = build.ConfigurationData(conf) + elif not isinstance(conf, build.ConfigurationData): raise InterpreterException('Argument "configuration" is not of type configuration_data') mlog.log('Configuring', mlog.bold(output), 'using configuration') if len(inputs) > 1: @@ -2245,7 +2252,7 @@ external dependencies (including libraries) must go to "dependencies".''') os.makedirs(os.path.join(self.environment.build_dir, self.subdir), exist_ok=True) file_encoding = kwargs.setdefault('encoding', 'utf-8') missing_variables, confdata_useless = \ - mesonlib.do_conf_file(inputs_abs[0], ofile_abs, conf.conf_data, + mesonlib.do_conf_file(inputs_abs[0], ofile_abs, conf, fmt, file_encoding) if missing_variables: var_list = ", ".join(map(repr, sorted(missing_variables))) @@ -2261,8 +2268,8 @@ external dependencies (including libraries) must go to "dependencies".''') 'copy a file to the build dir, use the \'copy:\' keyword ' 'argument added in 0.47.0', location=node) else: - mesonlib.dump_conf_header(ofile_abs, conf.conf_data, output_format) - conf.mark_used() + mesonlib.dump_conf_header(ofile_abs, conf, output_format) + conf.used = True elif 'command' in kwargs: if len(inputs) > 1: FeatureNew.single_use('multiple inputs in configure_file()', '0.52.0', self.subproject) diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index b2b5493..8ea729b 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -279,11 +279,10 @@ class EnvironmentVariablesHolder(ObjectHolder[build.EnvironmentVariables], Mutab _CONF_DATA_SET_KWS: KwargInfo[T.Optional[str]] = KwargInfo('description', (str, NoneType)) -class ConfigurationDataObject(MutableInterpreterObject, MesonInterpreterObject): - def __init__(self, subproject: str, initial_values: T.Optional[T.Dict[str, T.Union[str, int, bool]]] = None) -> None: - self.used = False # These objects become immutable after use in configure_file. - super().__init__(subproject=subproject) - self.conf_data = build.ConfigurationData() +class ConfigurationDataHolder(ObjectHolder[build.ConfigurationData], MutableInterpreterObject): + + def __init__(self, obj: build.ConfigurationData, interpreter: 'Interpreter'): + super().__init__(obj, interpreter) self.methods.update({'set': self.set_method, 'set10': self.set10_method, 'set_quoted': self.set_quoted_method, @@ -293,43 +292,40 @@ class ConfigurationDataObject(MutableInterpreterObject, MesonInterpreterObject): 'get_unquoted': self.get_unquoted_method, 'merge_from': self.merge_from_method, }) - if initial_values: - for k, v in initial_values.items(): - self.conf_data.values[k] = (v, None) - def is_used(self) -> bool: - return self.used + def __deepcopy__(self, memo: T.Dict) -> 'ConfigurationDataHolder': + return ConfigurationDataHolder(copy.deepcopy(self.held_object), self.interpreter) - def mark_used(self) -> None: - self.used = True + def is_used(self) -> bool: + return self.held_object.used def __check_used(self) -> None: - if self.used: + if self.is_used(): raise InterpreterException("Can not set values on configuration object that has been used.") @typed_pos_args('configuration_data.set', str, (str, int, bool)) @typed_kwargs('configuration_data.set', _CONF_DATA_SET_KWS) def set_method(self, args: T.Tuple[str, T.Union[str, int, bool]], kwargs: 'kwargs.ConfigurationDataSet') -> None: self.__check_used() - self.conf_data.values[args[0]] = (args[1], kwargs['description']) + self.held_object.values[args[0]] = (args[1], kwargs['description']) @typed_pos_args('configuration_data.set_quoted', str, str) @typed_kwargs('configuration_data.set_quoted', _CONF_DATA_SET_KWS) def set_quoted_method(self, args: T.Tuple[str, str], kwargs: 'kwargs.ConfigurationDataSet') -> None: self.__check_used() escaped_val = '\\"'.join(args[1].split('"')) - self.conf_data.values[args[0]] = (f'"{escaped_val}"', kwargs['description']) + self.held_object.values[args[0]] = (f'"{escaped_val}"', kwargs['description']) @typed_pos_args('configuration_data.set10', str, (int, bool)) @typed_kwargs('configuration_data.set10', _CONF_DATA_SET_KWS) def set10_method(self, args: T.Tuple[str, T.Union[int, bool]], kwargs: 'kwargs.ConfigurationDataSet') -> None: self.__check_used() - self.conf_data.values[args[0]] = (int(args[1]), kwargs['description']) + self.held_object.values[args[0]] = (int(args[1]), kwargs['description']) @typed_pos_args('configuration_data.has', (str, int, bool)) @noKwargs def has_method(self, args: T.Tuple[T.Union[str, int, bool]], kwargs: TYPE_kwargs) -> bool: - return args[0] in self.conf_data.values + return args[0] in self.held_object.values @FeatureNew('configuration_data.get()', '0.38.0') @noArgsFlattening @@ -338,8 +334,8 @@ class ConfigurationDataObject(MutableInterpreterObject, MesonInterpreterObject): def get_method(self, args: T.Tuple[str, T.Optional[T.Union[str, int, bool]]], kwargs: TYPE_kwargs) -> T.Union[str, int, bool]: name = args[0] - if name in self.conf_data: - return self.conf_data.get(name)[0] + if name in self.held_object: + return self.held_object.get(name)[0] elif args[1] is not None: return args[1] raise InterpreterException(f'Entry {name} not in configuration data.') @@ -350,8 +346,8 @@ class ConfigurationDataObject(MutableInterpreterObject, MesonInterpreterObject): def get_unquoted_method(self, args: T.Tuple[str, T.Optional[T.Union[str, int, bool]]], kwargs: TYPE_kwargs) -> T.Union[str, int, bool]: name = args[0] - if name in self.conf_data: - val = self.conf_data.get(name)[0] + if name in self.held_object: + val = self.held_object.get(name)[0] elif args[1] is not None: val = args[1] else: @@ -361,7 +357,7 @@ class ConfigurationDataObject(MutableInterpreterObject, MesonInterpreterObject): return val def get(self, name: str) -> T.Tuple[T.Union[str, int, bool], T.Optional[str]]: - return self.conf_data.values[name] + return self.held_object.values[name] @FeatureNew('configuration_data.keys()', '0.57.0') @noPosargs @@ -369,15 +365,13 @@ class ConfigurationDataObject(MutableInterpreterObject, MesonInterpreterObject): return sorted(self.keys()) def keys(self) -> T.List[str]: - return list(self.conf_data.values.keys()) + return list(self.held_object.values.keys()) - @typed_pos_args('configuration_data.merge_from', object) # yay for recursive type validation! + @typed_pos_args('configuration_data.merge_from', build.ConfigurationData) @noKwargs - def merge_from_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> None: + def merge_from_method(self, args: T.Tuple[build.ConfigurationData], kwargs: TYPE_kwargs) -> None: from_object = args[0] - if not isinstance(from_object, ConfigurationDataObject): - raise InterpreterException('Merge_from argument must be a configuration data object.') - self.conf_data.values.update(from_object.conf_data.values) + self.held_object.values.update(from_object.values) _PARTIAL_DEP_KWARGS = [ diff --git a/mesonbuild/modules/cmake.py b/mesonbuild/modules/cmake.py index 0c61b47..0f325f5 100644 --- a/mesonbuild/modules/cmake.py +++ b/mesonbuild/modules/cmake.py @@ -20,7 +20,7 @@ from . import ExtensionModule, ModuleReturnValue, ModuleObject from .. import build, mesonlib, mlog, dependencies from ..cmake import SingleTargetOptions, TargetOptions, cmake_defines_to_args -from ..interpreter import ConfigurationDataObject, SubprojectHolder +from ..interpreter import SubprojectHolder from ..interpreterbase import ( FeatureNew, FeatureNewKwargs, @@ -358,7 +358,7 @@ class CmakeModule(ExtensionModule): if 'configuration' not in kwargs: raise mesonlib.MesonException('"configuration" not specified.') conf = kwargs['configuration'] - if not isinstance(conf, ConfigurationDataObject): + if not isinstance(conf, build.ConfigurationData): raise mesonlib.MesonException('Argument "configuration" is not of type configuration_data') prefix = state.environment.coredata.get_option(mesonlib.OptionKey('prefix')) @@ -372,8 +372,8 @@ class CmakeModule(ExtensionModule): extra = PACKAGE_INIT_EXT.replace('@absInstallDir@', abs_install_dir) extra = extra.replace('@installPrefix@', prefix) - self.create_package_file(ifile_abs, ofile_abs, PACKAGE_RELATIVE_PATH, extra, conf.conf_data) - conf.mark_used() + self.create_package_file(ifile_abs, ofile_abs, PACKAGE_RELATIVE_PATH, extra, conf) + conf.used = True conffile = os.path.normpath(inputfile.relative_name()) if conffile not in self.interpreter.build_def_files: diff --git a/mesonbuild/modules/sourceset.py b/mesonbuild/modules/sourceset.py index ba8b300..515e670 100644 --- a/mesonbuild/modules/sourceset.py +++ b/mesonbuild/modules/sourceset.py @@ -154,8 +154,12 @@ class SourceSet(MutableModuleObject): def _get_from_config_data(key): nonlocal config_cache if key not in config_cache: - args = [key] if strict else [key, False] - config_cache[key] = config_data.get_method(args, {}) + if key in config_data: + config_cache[key] = config_data.get(key)[0] + elif strict: + raise InvalidArguments(f'sourceset.apply: key "{key}" not in passed configuration, and strict set.') + else: + config_cache[key] = False return config_cache[key] files = self.collect(_get_from_config_data, False) diff --git a/mesonbuild/modules/unstable_simd.py b/mesonbuild/modules/unstable_simd.py index 3339cea..8715a14 100644 --- a/mesonbuild/modules/unstable_simd.py +++ b/mesonbuild/modules/unstable_simd.py @@ -13,6 +13,7 @@ # limitations under the License. from .. import mesonlib, compilers, mlog +from .. import build from . import ExtensionModule @@ -57,8 +58,7 @@ class SimdModule(ExtensionModule): compiler = kwargs['compiler'] if not isinstance(compiler, compilers.compilers.Compiler): raise mesonlib.MesonException('Compiler argument must be a compiler object.') - cdata = self.interpreter.func_configuration_data(None, [], {}) - conf = cdata.conf_data + conf = build.ConfigurationData() for iset in self.isets: if iset not in kwargs: continue @@ -82,7 +82,7 @@ class SimdModule(ExtensionModule): all_lang_args = old_lang_args + args lib_kwargs[langarg_key] = all_lang_args result.append(self.interpreter.func_static_lib(None, [libname], lib_kwargs)) - return [result, cdata] + return [result, conf] def initialize(*args, **kwargs): return SimdModule(*args, **kwargs) |