diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2025-05-26 09:04:37 +0200 |
|---|---|---|
| committer | Jussi Pakkanen <jussi.pakkanen@mailbox.org> | 2025-06-18 21:33:19 +0300 |
| commit | e284c0d74240da15e7d62d3d530c69b224130be6 (patch) | |
| tree | 4d4540f5a73d8531df4d8d825f33907ed1e21508 | |
| parent | 723f402ff2afe594581df66ded71ff27b57c3d3d (diff) | |
| download | meson-e284c0d74240da15e7d62d3d530c69b224130be6.tar.gz | |
options: all inputs to OptionStore are OptionKeys
Thanks to several fixes applied between commit d37d649b0 ("Make all
Meson level options overridable per subproject.", 2025-02-13) and now,
OptionStore never gets a string key. Tighten the type of OptionDict,
and use it whenever possible.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
| -rw-r--r-- | mesonbuild/environment.py | 6 | ||||
| -rw-r--r-- | mesonbuild/interpreter/interpreter.py | 20 | ||||
| -rw-r--r-- | mesonbuild/options.py | 48 |
3 files changed, 26 insertions, 48 deletions
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 2a9cf165b..2c3bdecf3 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -43,7 +43,7 @@ from mesonbuild import envconfig if T.TYPE_CHECKING: from .compilers import Compiler from .compilers.mixins.visualstudio import VisualStudioLikeCompiler - from .options import ElementaryOptionValues + from .options import OptionDict, ElementaryOptionValues from .wrap.wrap import Resolver from . import cargo @@ -646,12 +646,12 @@ class Environment: # # Note that order matters because of 'buildtype', if it is after # 'optimization' and 'debug' keys, it override them. - self.options: T.MutableMapping[OptionKey, ElementaryOptionValues] = collections.OrderedDict() + self.options: OptionDict = collections.OrderedDict() # Environment variables with the name converted into an OptionKey type. # These have subtly different behavior compared to machine files, so do # not store them in self.options. See _set_default_options_from_env. - self.env_opts: T.MutableMapping[OptionKey, ElementaryOptionValues] = {} + self.env_opts: OptionDict = {} self.machinestore = machinefile.MachineFileStore(self.coredata.config_files, self.coredata.cross_files, self.source_dir) diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 73aa01a23..b76a265e1 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -115,7 +115,7 @@ if T.TYPE_CHECKING: from . import kwargs as kwtypes from ..backend.backends import Backend from ..interpreterbase.baseobjects import InterpreterObject, TYPE_var, TYPE_kwargs - from ..options import ElementaryOptionValues, OptionDict + from ..options import OptionDict from ..programs import OverrideProgram from .type_checking import SourcesVarargsType @@ -271,7 +271,7 @@ class Interpreter(InterpreterBase, HoldableObject): subproject: str = '', subdir: str = '', subproject_dir: str = 'subprojects', - invoker_method_default_options: T.Optional[T.Dict[OptionKey, ElementaryOptionValues]] = None, + invoker_method_default_options: T.Optional[OptionDict] = None, ast: T.Optional[mparser.CodeBlockNode] = None, relaxations: T.Optional[T.Set[InterpreterRuleRelaxation]] = None, user_defined_options: T.Optional[coredata.SharedCMDOptions] = None, @@ -301,7 +301,7 @@ class Interpreter(InterpreterBase, HoldableObject): self.invoker_method_default_options = invoker_method_default_options else: self.invoker_method_default_options = {} - self.project_default_options: T.Mapping[OptionKey, ElementaryOptionValues] = {} + self.project_default_options: OptionDict = {} self.build_func_dict() self.build_holder_map() self.user_defined_options = user_defined_options @@ -934,7 +934,7 @@ class Interpreter(InterpreterBase, HoldableObject): m += ['method', mlog.bold(method)] mlog.log(*m, '\n', nested=False) - methods_map: T.Dict[wrap.Method, T.Callable[[str, str, T.Dict[OptionKey, ElementaryOptionValues], kwtypes.DoSubproject], + methods_map: T.Dict[wrap.Method, T.Callable[[str, str, OptionDict, kwtypes.DoSubproject], SubprojectHolder]] = { 'meson': self._do_subproject_meson, 'cmake': self._do_subproject_cmake, @@ -957,7 +957,7 @@ class Interpreter(InterpreterBase, HoldableObject): raise e def _do_subproject_meson(self, subp_name: str, subdir: str, - default_options: T.Dict[OptionKey, ElementaryOptionValues], + default_options: OptionDict, kwargs: kwtypes.DoSubproject, ast: T.Optional[mparser.CodeBlockNode] = None, build_def_files: T.Optional[T.List[str]] = None, @@ -1017,7 +1017,7 @@ class Interpreter(InterpreterBase, HoldableObject): return self.subprojects[subp_name] def _do_subproject_cmake(self, subp_name: str, subdir: str, - default_options: T.Dict[OptionKey, ElementaryOptionValues], + default_options: OptionDict, kwargs: kwtypes.DoSubproject) -> SubprojectHolder: from ..cmake import CMakeInterpreter with mlog.nested(subp_name): @@ -1044,7 +1044,7 @@ class Interpreter(InterpreterBase, HoldableObject): return result def _do_subproject_cargo(self, subp_name: str, subdir: str, - default_options: T.Dict[OptionKey, ElementaryOptionValues], + default_options: OptionDict, kwargs: kwtypes.DoSubproject) -> SubprojectHolder: from .. import cargo FeatureNew.single_use('Cargo subproject', '1.3.0', self.subproject, location=self.current_node) @@ -1626,7 +1626,7 @@ class Interpreter(InterpreterBase, HoldableObject): # the host machine. def find_program_impl(self, args: T.List[mesonlib.FileOrString], for_machine: MachineChoice = MachineChoice.HOST, - default_options: T.Optional[T.Dict[OptionKey, options.ElementaryOptionValues]] = None, + default_options: T.Optional[OptionDict] = None, required: bool = True, silent: bool = True, wanted: T.Union[str, T.List[str]] = '', search_dirs: T.Optional[T.List[str]] = None, @@ -1657,7 +1657,7 @@ class Interpreter(InterpreterBase, HoldableObject): return progobj def program_lookup(self, args: T.List[mesonlib.FileOrString], for_machine: MachineChoice, - default_options: T.Optional[T.Dict[OptionKey, options.ElementaryOptionValues]], + default_options: T.Optional[OptionDict], required: bool, search_dirs: T.Optional[T.List[str]], wanted: T.Union[str, T.List[str]], @@ -1725,7 +1725,7 @@ class Interpreter(InterpreterBase, HoldableObject): return True def find_program_fallback(self, fallback: str, args: T.List[mesonlib.FileOrString], - default_options: T.Dict[OptionKey, options.ElementaryOptionValues], + default_options: OptionDict, required: bool, extra_info: T.List[mlog.TV_Loggable] ) -> T.Optional[T.Union[ExternalProgram, build.Executable, OverrideProgram]]: mlog.log('Fallback to subproject', mlog.bold(fallback), 'which provides program', diff --git a/mesonbuild/options.py b/mesonbuild/options.py index 0e0209ca8..eb8cd2c5f 100644 --- a/mesonbuild/options.py +++ b/mesonbuild/options.py @@ -310,7 +310,7 @@ class OptionKey: return self.machine is MachineChoice.BUILD if T.TYPE_CHECKING: - OptionDict: TypeAlias = T.Dict[T.Union[OptionKey, str], ElementaryOptionValues] + OptionDict: TypeAlias = T.Dict[OptionKey, ElementaryOptionValues] @dataclasses.dataclass class UserOption(T.Generic[_T], HoldableObject): @@ -809,13 +809,13 @@ class OptionStore: self.module_options: T.Set[OptionKey] = set() from .compilers import all_languages self.all_languages = set(all_languages) - self.augments: T.Dict[OptionKey, ElementaryOptionValues] = {} + self.augments: OptionDict = {} self.is_cross = is_cross # Pending options are options that need to be initialized later, either # configuration dependent options like compiler options, or options for # a different subproject - self.pending_options: T.Dict[OptionKey, ElementaryOptionValues] = {} + self.pending_options: OptionDict = {} def clear_pending(self) -> None: self.pending_options = {} @@ -1248,7 +1248,7 @@ class OptionStore: prefix = None others_d: OptionDict = {} for k, v in coll.items(): - if k == 'prefix' or (isinstance(k, OptionKey) and k.name == 'prefix'): + if k.name == 'prefix': if not isinstance(v, str): raise MesonException('Incorrect type for prefix option (expected string)') prefix = v @@ -1259,13 +1259,10 @@ class OptionStore: def first_handle_prefix(self, project_default_options: OptionDict, cmd_line_options: OptionDict, - machine_file_options: T.Mapping[OptionKey, ElementaryOptionValues]) \ - -> T.Tuple[OptionDict, - OptionDict, - T.MutableMapping[OptionKey, ElementaryOptionValues]]: + machine_file_options: OptionDict) \ + -> T.Tuple[OptionDict, OptionDict, OptionDict]: # Copy to avoid later mutation - nopref_machine_file_options = T.cast( - 'T.MutableMapping[OptionKey, ElementaryOptionValues]', copy.copy(machine_file_options)) + nopref_machine_file_options = copy.copy(machine_file_options) prefix = None (possible_prefix, nopref_project_default_options) = self.prefix_split_options(project_default_options) @@ -1298,15 +1295,11 @@ class OptionStore: def initialize_from_top_level_project_call(self, project_default_options_in: OptionDict, cmd_line_options_in: OptionDict, - machine_file_options_in: T.Mapping[OptionKey, ElementaryOptionValues]) -> None: + machine_file_options_in: OptionDict) -> None: (project_default_options, cmd_line_options, machine_file_options) = self.first_handle_prefix(project_default_options_in, cmd_line_options_in, machine_file_options_in) - for keystr, valstr in project_default_options.items(): - if isinstance(keystr, str): - key = OptionKey.from_string(keystr) - else: - key = keystr + for key, valstr in project_default_options.items(): # Due to backwards compatibility we ignore build-machine options # when building natively. if not self.is_cross and key.is_for_build(): @@ -1328,11 +1321,7 @@ class OptionStore: self.augments[key] = valstr else: self.set_option_maybe_root(key, valstr, True) - for keystr, valstr in cmd_line_options.items(): - if isinstance(keystr, str): - key = OptionKey.from_string(keystr) - else: - key = keystr + for key, valstr in cmd_line_options.items(): # Due to backwards compatibility we ignore all build-machine options # when building natively. if not self.is_cross and key.is_for_build(): @@ -1361,12 +1350,7 @@ class OptionStore: def validate_cmd_line_options(self, cmd_line_options: OptionDict) -> None: unknown_options = [] - for keystr, valstr in cmd_line_options.items(): - if isinstance(keystr, str): - key = OptionKey.from_string(keystr) - else: - key = keystr - + for key, valstr in cmd_line_options.items(): if key in self.pending_options and not self.accept_as_pending_option(key): unknown_options.append(f'"{key}"') @@ -1379,11 +1363,7 @@ class OptionStore: spcall_default_options: OptionDict, project_default_options: OptionDict, cmd_line_options: OptionDict) -> None: - for keystr, valstr in itertools.chain(project_default_options.items(), spcall_default_options.items()): - if isinstance(keystr, str): - key = OptionKey.from_string(keystr) - else: - key = keystr + for key, valstr in itertools.chain(project_default_options.items(), spcall_default_options.items()): if key.subproject is None: key = key.evolve(subproject=subproject) elif key.subproject == subproject: @@ -1397,9 +1377,7 @@ class OptionStore: self.pending_options.pop(key, None) self.augments[key] = valstr # Check for pending options - for key, valstr in cmd_line_options.items(): # type: ignore [assignment] - if not isinstance(key, OptionKey): - key = OptionKey.from_string(key) + for key, valstr in cmd_line_options.items(): if key.subproject != subproject: continue self.pending_options.pop(key, None) |
