summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-05-26 09:04:37 +0200
committerJussi Pakkanen <jussi.pakkanen@mailbox.org>2025-06-18 21:33:19 +0300
commite284c0d74240da15e7d62d3d530c69b224130be6 (patch)
tree4d4540f5a73d8531df4d8d825f33907ed1e21508
parent723f402ff2afe594581df66ded71ff27b57c3d3d (diff)
downloadmeson-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.py6
-rw-r--r--mesonbuild/interpreter/interpreter.py20
-rw-r--r--mesonbuild/options.py48
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)