summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-05-05 13:10:13 +0200
committerDylan Baker <dylan@pnwbakers.com>2025-05-07 09:43:43 -0700
commit8f55a24cfb1fb02e428fcf3a1952fe80f4978fca (patch)
treef8729fdd8dcf8cfd26498aa60304dadb4ffeafd1
parent26870c2bdcaae4c126489c0896f3e277a66eda5d (diff)
downloadmeson-8f55a24cfb1fb02e428fcf3a1952fe80f4978fca.tar.gz
options: support non-string data types in more places
Allow OptionStringLikeDict to use non-string data types, and use it as much as possible instead of string-valued dictionaries. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--mesonbuild/ast/introspection.py5
-rw-r--r--mesonbuild/interpreter/interpreter.py3
-rw-r--r--mesonbuild/options.py38
3 files changed, 24 insertions, 22 deletions
diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py
index a270dfec2..bb1e241e5 100644
--- a/mesonbuild/ast/introspection.py
+++ b/mesonbuild/ast/introspection.py
@@ -22,6 +22,7 @@ from .interpreter import AstInterpreter
if T.TYPE_CHECKING:
from ..build import BuildTarget
from ..interpreterbase import TYPE_var
+ from ..options import OptionDict
from .visitor import AstVisitor
@@ -130,14 +131,14 @@ class IntrospectionInterpreter(AstInterpreter):
if self.environment.first_invocation or (self.subproject != '' and self.subproject not in self.coredata.initialized_subprojects):
if self.subproject == '':
self.coredata.optstore.initialize_from_top_level_project_call(
- T.cast('T.Dict[T.Union[OptionKey, str], str]', self.project_default_options),
+ T.cast('OptionDict', self.project_default_options),
{}, # TODO: not handled by this Interpreter.
self.environment.options)
else:
self.coredata.optstore.initialize_from_subproject_call(
self.subproject,
{}, # TODO: this isn't handled by the introspection interpreter...
- T.cast('T.Dict[T.Union[OptionKey, str], str]', self.project_default_options),
+ T.cast('OptionDict', self.project_default_options),
{}) # TODO: this isn't handled by the introspection interpreter...
self.coredata.initialized_subprojects.add(self.subproject)
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 44209d097..2113362d8 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -115,6 +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 OptionDict
from ..programs import OverrideProgram
from .type_checking import SourcesVarargsType
@@ -868,7 +869,7 @@ class Interpreter(InterpreterBase, HoldableObject):
return sub
def do_subproject(self, subp_name: str, kwargs: kwtypes.DoSubproject, force_method: T.Optional[wrap.Method] = None,
- extra_default_options: T.Optional[T.Dict[str, options.ElementaryOptionValues]] = None) -> SubprojectHolder:
+ extra_default_options: T.Optional[OptionDict] = None) -> SubprojectHolder:
if subp_name == 'sub_static':
pass
disabled, required, feature = extract_required_kwarg(kwargs, self.subproject)
diff --git a/mesonbuild/options.py b/mesonbuild/options.py
index f8408bb72..0e637dcba 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:
- OptionStringLikeDict: TypeAlias = T.Dict[T.Union[OptionKey, str], str]
+ OptionDict: TypeAlias = T.Dict[T.Union[OptionKey, str], ElementaryOptionValues]
@dataclasses.dataclass
class UserOption(T.Generic[_T], HoldableObject):
@@ -1222,31 +1222,31 @@ class OptionStore:
perproject_global_options.append(strvaluetuple)
return (global_options, perproject_global_options, project_options)
- def optlist2optdict(self, optlist: T.List[str]) -> OptionStringLikeDict:
- optdict: OptionStringLikeDict = {}
+ 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: OptionStringLikeDict) -> T.Tuple[str, OptionStringLikeDict]:
+ def prefix_split_options(self, coll: OptionDict) -> T.Tuple[T.Optional[str], OptionDict]:
prefix = None
- others_d: OptionStringLikeDict = {}
+ others_d: OptionDict = {}
for k, v in coll.items():
- if isinstance(k, OptionKey) and k.name == 'prefix':
- prefix = v
- elif k == 'prefix':
+ if k == 'prefix' or (isinstance(k, OptionKey) and k.name == 'prefix'):
+ if not isinstance(v, str):
+ raise MesonException('Incorrect type for prefix option (expected string)')
prefix = v
else:
others_d[k] = v
return (prefix, others_d)
def first_handle_prefix(self,
- project_default_options: OptionStringLikeDict,
- cmd_line_options: OptionStringLikeDict,
+ project_default_options: OptionDict,
+ cmd_line_options: OptionDict,
machine_file_options: T.Mapping[OptionKey, ElementaryOptionValues]) \
- -> T.Tuple[OptionStringLikeDict,
- OptionStringLikeDict,
+ -> T.Tuple[OptionDict,
+ OptionDict,
T.MutableMapping[OptionKey, ElementaryOptionValues]]:
# Copy to avoid later mutation
nopref_machine_file_options = T.cast(
@@ -1281,8 +1281,8 @@ class OptionStore:
self.options[OptionKey('prefix')].set_value(prefix)
def initialize_from_top_level_project_call(self,
- project_default_options_in: T.Union[T.List[str], OptionStringLikeDict],
- cmd_line_options_in: OptionStringLikeDict,
+ project_default_options_in: T.Union[T.List[str], OptionDict],
+ cmd_line_options_in: OptionDict,
machine_file_options_in: T.Mapping[OptionKey, ElementaryOptionValues]) -> None:
first_invocation = True
if isinstance(project_default_options_in, list):
@@ -1362,7 +1362,7 @@ class OptionStore:
else:
self.pending_options[key] = valstr
- def validate_cmd_line_options(self, cmd_line_options: OptionStringLikeDict) -> None:
+ 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):
@@ -1382,16 +1382,16 @@ class OptionStore:
keys = ', '.join(unknown_options)
raise MesonException(f'Unknown options: {keys}')
- def hacky_mchackface_back_to_list(self, optdict: T.Union[T.List[str], OptionStringLikeDict]) -> T.List[str]:
+ def hacky_mchackface_back_to_list(self, optdict: T.Union[T.List[str], OptionDict]) -> T.List[str]:
if isinstance(optdict, dict):
return [f'{k}={v}' for k, v in optdict.items()]
return optdict
def initialize_from_subproject_call(self,
subproject: str,
- spcall_default_options_in: OptionStringLikeDict,
- project_default_options_in: T.Union[T.List[str], OptionStringLikeDict],
- cmd_line_options: OptionStringLikeDict) -> None:
+ spcall_default_options_in: OptionDict,
+ project_default_options_in: T.Union[T.List[str], OptionDict],
+ cmd_line_options: OptionDict) -> None:
is_first_invocation = True
spcall_default_options = self.hacky_mchackface_back_to_list(spcall_default_options_in)
project_default_options = self.hacky_mchackface_back_to_list(project_default_options_in)