Skip to content

Commit e284c0d

Browse files
bonzinijpakkane
authored andcommitted
options: all inputs to OptionStore are OptionKeys
Thanks to several fixes applied between commit d37d649 ("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 <[email protected]>
1 parent 723f402 commit e284c0d

File tree

3 files changed

+26
-48
lines changed

3 files changed

+26
-48
lines changed

mesonbuild/environment.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
if T.TYPE_CHECKING:
4444
from .compilers import Compiler
4545
from .compilers.mixins.visualstudio import VisualStudioLikeCompiler
46-
from .options import ElementaryOptionValues
46+
from .options import OptionDict, ElementaryOptionValues
4747
from .wrap.wrap import Resolver
4848
from . import cargo
4949

@@ -646,12 +646,12 @@ def __init__(self, source_dir: str, build_dir: T.Optional[str], cmd_options: cor
646646
#
647647
# Note that order matters because of 'buildtype', if it is after
648648
# 'optimization' and 'debug' keys, it override them.
649-
self.options: T.MutableMapping[OptionKey, ElementaryOptionValues] = collections.OrderedDict()
649+
self.options: OptionDict = collections.OrderedDict()
650650

651651
# Environment variables with the name converted into an OptionKey type.
652652
# These have subtly different behavior compared to machine files, so do
653653
# not store them in self.options. See _set_default_options_from_env.
654-
self.env_opts: T.MutableMapping[OptionKey, ElementaryOptionValues] = {}
654+
self.env_opts: OptionDict = {}
655655

656656
self.machinestore = machinefile.MachineFileStore(self.coredata.config_files, self.coredata.cross_files, self.source_dir)
657657

mesonbuild/interpreter/interpreter.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
from . import kwargs as kwtypes
116116
from ..backend.backends import Backend
117117
from ..interpreterbase.baseobjects import InterpreterObject, TYPE_var, TYPE_kwargs
118-
from ..options import ElementaryOptionValues, OptionDict
118+
from ..options import OptionDict
119119
from ..programs import OverrideProgram
120120
from .type_checking import SourcesVarargsType
121121

@@ -271,7 +271,7 @@ def __init__(
271271
subproject: str = '',
272272
subdir: str = '',
273273
subproject_dir: str = 'subprojects',
274-
invoker_method_default_options: T.Optional[T.Dict[OptionKey, ElementaryOptionValues]] = None,
274+
invoker_method_default_options: T.Optional[OptionDict] = None,
275275
ast: T.Optional[mparser.CodeBlockNode] = None,
276276
relaxations: T.Optional[T.Set[InterpreterRuleRelaxation]] = None,
277277
user_defined_options: T.Optional[coredata.SharedCMDOptions] = None,
@@ -301,7 +301,7 @@ def __init__(
301301
self.invoker_method_default_options = invoker_method_default_options
302302
else:
303303
self.invoker_method_default_options = {}
304-
self.project_default_options: T.Mapping[OptionKey, ElementaryOptionValues] = {}
304+
self.project_default_options: OptionDict = {}
305305
self.build_func_dict()
306306
self.build_holder_map()
307307
self.user_defined_options = user_defined_options
@@ -934,7 +934,7 @@ def do_subproject(self, subp_name: str, kwargs: kwtypes.DoSubproject, force_meth
934934
m += ['method', mlog.bold(method)]
935935
mlog.log(*m, '\n', nested=False)
936936

937-
methods_map: T.Dict[wrap.Method, T.Callable[[str, str, T.Dict[OptionKey, ElementaryOptionValues], kwtypes.DoSubproject],
937+
methods_map: T.Dict[wrap.Method, T.Callable[[str, str, OptionDict, kwtypes.DoSubproject],
938938
SubprojectHolder]] = {
939939
'meson': self._do_subproject_meson,
940940
'cmake': self._do_subproject_cmake,
@@ -957,7 +957,7 @@ def do_subproject(self, subp_name: str, kwargs: kwtypes.DoSubproject, force_meth
957957
raise e
958958

959959
def _do_subproject_meson(self, subp_name: str, subdir: str,
960-
default_options: T.Dict[OptionKey, ElementaryOptionValues],
960+
default_options: OptionDict,
961961
kwargs: kwtypes.DoSubproject,
962962
ast: T.Optional[mparser.CodeBlockNode] = None,
963963
build_def_files: T.Optional[T.List[str]] = None,
@@ -1017,7 +1017,7 @@ def _do_subproject_meson(self, subp_name: str, subdir: str,
10171017
return self.subprojects[subp_name]
10181018

10191019
def _do_subproject_cmake(self, subp_name: str, subdir: str,
1020-
default_options: T.Dict[OptionKey, ElementaryOptionValues],
1020+
default_options: OptionDict,
10211021
kwargs: kwtypes.DoSubproject) -> SubprojectHolder:
10221022
from ..cmake import CMakeInterpreter
10231023
with mlog.nested(subp_name):
@@ -1044,7 +1044,7 @@ def _do_subproject_cmake(self, subp_name: str, subdir: str,
10441044
return result
10451045

10461046
def _do_subproject_cargo(self, subp_name: str, subdir: str,
1047-
default_options: T.Dict[OptionKey, ElementaryOptionValues],
1047+
default_options: OptionDict,
10481048
kwargs: kwtypes.DoSubproject) -> SubprojectHolder:
10491049
from .. import cargo
10501050
FeatureNew.single_use('Cargo subproject', '1.3.0', self.subproject, location=self.current_node)
@@ -1626,7 +1626,7 @@ def notfound_program(self, args: T.List[mesonlib.FileOrString]) -> ExternalProgr
16261626
# the host machine.
16271627
def find_program_impl(self, args: T.List[mesonlib.FileOrString],
16281628
for_machine: MachineChoice = MachineChoice.HOST,
1629-
default_options: T.Optional[T.Dict[OptionKey, options.ElementaryOptionValues]] = None,
1629+
default_options: T.Optional[OptionDict] = None,
16301630
required: bool = True, silent: bool = True,
16311631
wanted: T.Union[str, T.List[str]] = '',
16321632
search_dirs: T.Optional[T.List[str]] = None,
@@ -1657,7 +1657,7 @@ def find_program_impl(self, args: T.List[mesonlib.FileOrString],
16571657
return progobj
16581658

16591659
def program_lookup(self, args: T.List[mesonlib.FileOrString], for_machine: MachineChoice,
1660-
default_options: T.Optional[T.Dict[OptionKey, options.ElementaryOptionValues]],
1660+
default_options: T.Optional[OptionDict],
16611661
required: bool,
16621662
search_dirs: T.Optional[T.List[str]],
16631663
wanted: T.Union[str, T.List[str]],
@@ -1725,7 +1725,7 @@ def check_program_version(self, progobj: T.Union[ExternalProgram, build.Executab
17251725
return True
17261726

17271727
def find_program_fallback(self, fallback: str, args: T.List[mesonlib.FileOrString],
1728-
default_options: T.Dict[OptionKey, options.ElementaryOptionValues],
1728+
default_options: OptionDict,
17291729
required: bool, extra_info: T.List[mlog.TV_Loggable]
17301730
) -> T.Optional[T.Union[ExternalProgram, build.Executable, OverrideProgram]]:
17311731
mlog.log('Fallback to subproject', mlog.bold(fallback), 'which provides program',

mesonbuild/options.py

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ def is_for_build(self) -> bool:
310310
return self.machine is MachineChoice.BUILD
311311

312312
if T.TYPE_CHECKING:
313-
OptionDict: TypeAlias = T.Dict[T.Union[OptionKey, str], ElementaryOptionValues]
313+
OptionDict: TypeAlias = T.Dict[OptionKey, ElementaryOptionValues]
314314

315315
@dataclasses.dataclass
316316
class UserOption(T.Generic[_T], HoldableObject):
@@ -809,13 +809,13 @@ def __init__(self, is_cross: bool) -> None:
809809
self.module_options: T.Set[OptionKey] = set()
810810
from .compilers import all_languages
811811
self.all_languages = set(all_languages)
812-
self.augments: T.Dict[OptionKey, ElementaryOptionValues] = {}
812+
self.augments: OptionDict = {}
813813
self.is_cross = is_cross
814814

815815
# Pending options are options that need to be initialized later, either
816816
# configuration dependent options like compiler options, or options for
817817
# a different subproject
818-
self.pending_options: T.Dict[OptionKey, ElementaryOptionValues] = {}
818+
self.pending_options: OptionDict = {}
819819

820820
def clear_pending(self) -> None:
821821
self.pending_options = {}
@@ -1248,7 +1248,7 @@ def prefix_split_options(self, coll: OptionDict) -> T.Tuple[T.Optional[str], Opt
12481248
prefix = None
12491249
others_d: OptionDict = {}
12501250
for k, v in coll.items():
1251-
if k == 'prefix' or (isinstance(k, OptionKey) and k.name == 'prefix'):
1251+
if k.name == 'prefix':
12521252
if not isinstance(v, str):
12531253
raise MesonException('Incorrect type for prefix option (expected string)')
12541254
prefix = v
@@ -1259,13 +1259,10 @@ def prefix_split_options(self, coll: OptionDict) -> T.Tuple[T.Optional[str], Opt
12591259
def first_handle_prefix(self,
12601260
project_default_options: OptionDict,
12611261
cmd_line_options: OptionDict,
1262-
machine_file_options: T.Mapping[OptionKey, ElementaryOptionValues]) \
1263-
-> T.Tuple[OptionDict,
1264-
OptionDict,
1265-
T.MutableMapping[OptionKey, ElementaryOptionValues]]:
1262+
machine_file_options: OptionDict) \
1263+
-> T.Tuple[OptionDict, OptionDict, OptionDict]:
12661264
# Copy to avoid later mutation
1267-
nopref_machine_file_options = T.cast(
1268-
'T.MutableMapping[OptionKey, ElementaryOptionValues]', copy.copy(machine_file_options))
1265+
nopref_machine_file_options = copy.copy(machine_file_options)
12691266

12701267
prefix = None
12711268
(possible_prefix, nopref_project_default_options) = self.prefix_split_options(project_default_options)
@@ -1298,15 +1295,11 @@ def hard_reset_from_prefix(self, prefix: str) -> None:
12981295
def initialize_from_top_level_project_call(self,
12991296
project_default_options_in: OptionDict,
13001297
cmd_line_options_in: OptionDict,
1301-
machine_file_options_in: T.Mapping[OptionKey, ElementaryOptionValues]) -> None:
1298+
machine_file_options_in: OptionDict) -> None:
13021299
(project_default_options, cmd_line_options, machine_file_options) = self.first_handle_prefix(project_default_options_in,
13031300
cmd_line_options_in,
13041301
machine_file_options_in)
1305-
for keystr, valstr in project_default_options.items():
1306-
if isinstance(keystr, str):
1307-
key = OptionKey.from_string(keystr)
1308-
else:
1309-
key = keystr
1302+
for key, valstr in project_default_options.items():
13101303
# Due to backwards compatibility we ignore build-machine options
13111304
# when building natively.
13121305
if not self.is_cross and key.is_for_build():
@@ -1328,11 +1321,7 @@ def initialize_from_top_level_project_call(self,
13281321
self.augments[key] = valstr
13291322
else:
13301323
self.set_option_maybe_root(key, valstr, True)
1331-
for keystr, valstr in cmd_line_options.items():
1332-
if isinstance(keystr, str):
1333-
key = OptionKey.from_string(keystr)
1334-
else:
1335-
key = keystr
1324+
for key, valstr in cmd_line_options.items():
13361325
# Due to backwards compatibility we ignore all build-machine options
13371326
# when building natively.
13381327
if not self.is_cross and key.is_for_build():
@@ -1361,12 +1350,7 @@ def accept_as_pending_option(self, key: OptionKey, known_subprojects: T.Optional
13611350

13621351
def validate_cmd_line_options(self, cmd_line_options: OptionDict) -> None:
13631352
unknown_options = []
1364-
for keystr, valstr in cmd_line_options.items():
1365-
if isinstance(keystr, str):
1366-
key = OptionKey.from_string(keystr)
1367-
else:
1368-
key = keystr
1369-
1353+
for key, valstr in cmd_line_options.items():
13701354
if key in self.pending_options and not self.accept_as_pending_option(key):
13711355
unknown_options.append(f'"{key}"')
13721356

@@ -1379,11 +1363,7 @@ def initialize_from_subproject_call(self,
13791363
spcall_default_options: OptionDict,
13801364
project_default_options: OptionDict,
13811365
cmd_line_options: OptionDict) -> None:
1382-
for keystr, valstr in itertools.chain(project_default_options.items(), spcall_default_options.items()):
1383-
if isinstance(keystr, str):
1384-
key = OptionKey.from_string(keystr)
1385-
else:
1386-
key = keystr
1366+
for key, valstr in itertools.chain(project_default_options.items(), spcall_default_options.items()):
13871367
if key.subproject is None:
13881368
key = key.evolve(subproject=subproject)
13891369
elif key.subproject == subproject:
@@ -1397,9 +1377,7 @@ def initialize_from_subproject_call(self,
13971377
self.pending_options.pop(key, None)
13981378
self.augments[key] = valstr
13991379
# Check for pending options
1400-
for key, valstr in cmd_line_options.items(): # type: ignore [assignment]
1401-
if not isinstance(key, OptionKey):
1402-
key = OptionKey.from_string(key)
1380+
for key, valstr in cmd_line_options.items():
14031381
if key.subproject != subproject:
14041382
continue
14051383
self.pending_options.pop(key, None)

0 commit comments

Comments
 (0)