interpreter: reintroduce a convertor for override_options and default_options

Replace optlist2optdict with a convertor.  However, while default_options
should use OptionKeys like it did before the option refactoring,
override_options keeps using strings.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2025-05-06 18:53:26 +02:00 committed by Dylan Baker
parent 3a020bbd65
commit 5558453e18
5 changed files with 25 additions and 41 deletions

View File

@ -656,29 +656,11 @@ class Target(HoldableObject, metaclass=abc.ABCMeta):
# set, use the value of 'install' if it's enabled. # set, use the value of 'install' if it's enabled.
self.build_by_default = True self.build_by_default = True
self.raw_overrides = self.parse_overrides(kwargs) self.raw_overrides = kwargs.get('override_options', {})
def get_override(self, name: str) -> T.Optional[str]: def get_override(self, name: str) -> T.Optional[str]:
return self.raw_overrides.get(name, None) return self.raw_overrides.get(name, None)
@staticmethod
def parse_overrides(kwargs: T.Dict[str, T.Any]) -> T.Dict[str, str]:
opts = kwargs.get('override_options', [])
# In this case we have an already parsed and ready to go dictionary
# provided by typed_kwargs
if isinstance(opts, dict):
return T.cast('T.Dict[OptionKey, str]', opts)
result: T.Dict[str, str] = {}
overrides = stringlistify(opts)
for o in overrides:
if '=' not in o:
raise InvalidArguments('Overrides must be of form "key=value"')
k, v = o.split('=', 1)
result[k] = v
return result
def is_linkable_target(self) -> bool: def is_linkable_target(self) -> bool:
return False return False

View File

@ -126,7 +126,7 @@ class DependencyFallbacksHolder(MesonInterpreterObject):
if static is not None: if static is not None:
default_library = 'static' if static else 'shared' default_library = 'static' if static else 'shared'
mlog.log(f'Building fallback subproject with default_library={default_library}') mlog.log(f'Building fallback subproject with default_library={default_library}')
extra_default_options['default_library'] = default_library extra_default_options[OptionKey('default_library')] = default_library
# Configure the subproject # Configure the subproject
subp_name = self.subproject_name subp_name = self.subproject_name

View File

@ -879,10 +879,6 @@ class Interpreter(InterpreterBase, HoldableObject):
return self.disabled_subproject(subp_name, disabled_feature=feature) return self.disabled_subproject(subp_name, disabled_feature=feature)
default_options = kwargs['default_options'] default_options = kwargs['default_options']
if isinstance(default_options, str):
default_options = [default_options]
if isinstance(default_options, list):
default_options = dict((x.split('=', 1) for x in default_options))
if extra_default_options: if extra_default_options:
default_options = {**extra_default_options, **default_options} default_options = {**extra_default_options, **default_options}

View File

@ -11,10 +11,10 @@ from .. import compilers
from ..build import (CustomTarget, BuildTarget, from ..build import (CustomTarget, BuildTarget,
CustomTargetIndex, ExtractedObjects, GeneratedList, IncludeDirs, CustomTargetIndex, ExtractedObjects, GeneratedList, IncludeDirs,
BothLibraries, SharedLibrary, StaticLibrary, Jar, Executable, StructuredSources) BothLibraries, SharedLibrary, StaticLibrary, Jar, Executable, StructuredSources)
from ..options import UserFeatureOption from ..options import OptionKey, UserFeatureOption
from ..dependencies import Dependency, InternalDependency from ..dependencies import Dependency, InternalDependency
from ..interpreterbase.decorators import KwargInfo, ContainerTypeInfo from ..interpreterbase.decorators import KwargInfo, ContainerTypeInfo
from ..mesonlib import (File, FileMode, MachineChoice, listify, has_path_sep, from ..mesonlib import (File, FileMode, MachineChoice, has_path_sep, listify, stringlistify,
EnvironmentVariables) EnvironmentVariables)
from ..programs import ExternalProgram from ..programs import ExternalProgram
@ -293,11 +293,22 @@ COMMAND_KW: KwargInfo[T.List[T.Union[str, BuildTarget, CustomTarget, CustomTarge
) )
OVERRIDE_OPTIONS_KW: KwargInfo[T.Union[str, T.Dict[str, ElementaryOptionValues], T.List[str]]] = KwargInfo( def _override_options_convertor(raw: T.Union[str, T.List[str], T.Dict[str, ElementaryOptionValues]]) -> T.Dict[str, ElementaryOptionValues]:
if isinstance(raw, dict):
return raw
raw = stringlistify(raw)
output: T.Dict[str, ElementaryOptionValues] = {}
for each in raw:
k, v = split_equal_string(each)
output[k] = v
return output
OVERRIDE_OPTIONS_KW: KwargInfo[T.Union[str, T.List[str], T.Dict[str, ElementaryOptionValues]]] = KwargInfo(
'override_options', 'override_options',
(str, ContainerTypeInfo(list, str), ContainerTypeInfo(dict, (str, int, bool, list))), (str, ContainerTypeInfo(list, str), ContainerTypeInfo(dict, (str, int, bool, list))),
default={}, default={},
validator=_options_validator, validator=_options_validator,
convertor=_override_options_convertor,
since_values={dict: '1.2.0'}, since_values={dict: '1.2.0'},
) )
@ -394,7 +405,13 @@ INCLUDE_DIRECTORIES: KwargInfo[T.List[T.Union[str, IncludeDirs]]] = KwargInfo(
default=[], default=[],
) )
DEFAULT_OPTIONS = OVERRIDE_OPTIONS_KW.evolve(name='default_options') def _default_options_convertor(raw: T.Union[str, T.List[str], T.Dict[str, ElementaryOptionValues]]) -> T.Dict[OptionKey, ElementaryOptionValues]:
d = _override_options_convertor(raw)
return {OptionKey.from_string(k): v for k, v in d.items()}
DEFAULT_OPTIONS = OVERRIDE_OPTIONS_KW.evolve(
name='default_options',
convertor=_default_options_convertor)
ENV_METHOD_KW = KwargInfo('method', str, default='set', since='0.62.0', ENV_METHOD_KW = KwargInfo('method', str, default='set', since='0.62.0',
validator=in_set_validator({'set', 'prepend', 'append'})) validator=in_set_validator({'set', 'prepend', 'append'}))

View File

@ -1220,13 +1220,6 @@ class OptionStore:
perproject_global_options.append(valuetuple) perproject_global_options.append(valuetuple)
return (global_options, perproject_global_options, project_options) return (global_options, perproject_global_options, project_options)
def optlist2optdict(self, optlist: T.List[str]) -> OptionDict:
optdict: OptionDict = {}
for p in optlist:
k, v = p.split('=', 1)
optdict[k] = v
return optdict
def prefix_split_options(self, coll: OptionDict) -> T.Tuple[T.Optional[str], OptionDict]: def prefix_split_options(self, coll: OptionDict) -> T.Tuple[T.Optional[str], OptionDict]:
prefix = None prefix = None
others_d: OptionDict = {} others_d: OptionDict = {}
@ -1279,12 +1272,10 @@ class OptionStore:
self.options[OptionKey('prefix')].set_value(prefix) self.options[OptionKey('prefix')].set_value(prefix)
def initialize_from_top_level_project_call(self, def initialize_from_top_level_project_call(self,
project_default_options_in: T.Union[T.List[str], OptionDict], project_default_options_in: OptionDict,
cmd_line_options_in: OptionDict, cmd_line_options_in: OptionDict,
machine_file_options_in: T.Mapping[OptionKey, ElementaryOptionValues]) -> None: machine_file_options_in: T.Mapping[OptionKey, ElementaryOptionValues]) -> None:
first_invocation = True first_invocation = True
if isinstance(project_default_options_in, list):
project_default_options_in = self.optlist2optdict(project_default_options_in)
(project_default_options, cmd_line_options, machine_file_options) = self.first_handle_prefix(project_default_options_in, (project_default_options, cmd_line_options, machine_file_options) = self.first_handle_prefix(project_default_options_in,
cmd_line_options_in, cmd_line_options_in,
machine_file_options_in) machine_file_options_in)
@ -1380,11 +1371,9 @@ class OptionStore:
def initialize_from_subproject_call(self, def initialize_from_subproject_call(self,
subproject: str, subproject: str,
spcall_default_options: OptionDict, spcall_default_options: OptionDict,
project_default_options: T.Union[T.List[str], OptionDict], project_default_options: OptionDict,
cmd_line_options: OptionDict) -> None: cmd_line_options: OptionDict) -> None:
is_first_invocation = True is_first_invocation = True
if isinstance(project_default_options, list):
project_default_options = self.optlist2optdict(project_default_options)
for keystr, valstr in itertools.chain(project_default_options.items(), spcall_default_options.items()): for keystr, valstr in itertools.chain(project_default_options.items(), spcall_default_options.items()):
if isinstance(keystr, str): if isinstance(keystr, str):
key = OptionKey.from_string(keystr) key = OptionKey.from_string(keystr)