Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mesonbuild/interpreterbase/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ def get_callee_args(wrapped_args: T.Tuple[ModuleObject, ModuleState, T.List[TYPE

Comment thread
bonzini marked this conversation as resolved.

@T.overload
def get_callee_args(wrapped_args: T.Tuple[OptionInterpreter, str, str, T.List[TYPE_var], TYPE_kwargs]) -> CalleeArgs: ...
def get_callee_args(wrapped_args: T.Tuple[OptionInterpreter, T.List[TYPE_var], TYPE_kwargs]) -> CalleeArgs: ...


def get_callee_args(wrapped_args: T.Union[
T.Tuple[InterpreterObject, T.List[TYPE_var], TYPE_kwargs],
T.Tuple[ObjectHolder, object],
T.Tuple[InterpreterBase, FunctionNode, T.List[TYPE_var], TYPE_kwargs],
T.Tuple[ModuleObject, ModuleState, T.List[TYPE_var], TYPE_kwargs],
T.Tuple[OptionInterpreter, str, str, T.List[TYPE_var], TYPE_kwargs],
T.Tuple[OptionInterpreter, T.List[TYPE_var], TYPE_kwargs],
]) -> CalleeArgs:
if is_module(wrapped_args[0]):
s = wrapped_args[1]
Expand Down
52 changes: 30 additions & 22 deletions mesonbuild/optinterpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,21 @@
if T.TYPE_CHECKING:
from .interpreterbase import TYPE_var, TYPE_kwargs
from .mesonlib import SubProject
from typing_extensions import TypedDict, Literal
from typing_extensions import TypeAlias, TypedDict, Literal, NotRequired
from .options import OptionStore

_DEPRECATED_ARGS = T.Union[bool, str, T.Dict[str, str], T.List[str]]

ParserFuncT: TypeAlias = T.Callable[[tuple[str, str, bool, _DEPRECATED_ARGS], TYPE_kwargs], options.AnyOptionType]

FuncOptionArgs = TypedDict('FuncOptionArgs', {
'type': str,
'description': str,
'yield': bool,
'choices': T.Optional[T.List[str]],
'choices': NotRequired[list[str] | None],
'value': object,
'min': T.Optional[int],
'max': T.Optional[int],
'min': NotRequired[int | None],
'max': NotRequired[int | None],
'deprecated': _DEPRECATED_ARGS,
})

Expand Down Expand Up @@ -68,7 +70,7 @@ class OptionInterpreter:
def __init__(self, optionstore: 'OptionStore', subproject: 'SubProject') -> None:
self.options: options.MutableKeyedOptionDictType = {}
self.subproject = subproject
self.option_types: T.Dict[str, T.Callable[..., options.AnyOptionType]] = {
self.option_types: dict[str, ParserFuncT] = {
'string': self.string_parser,
'boolean': self.boolean_parser,
'combo': self.combo_parser,
Expand Down Expand Up @@ -199,10 +201,11 @@ def func_option(self, args: T.Tuple[str], kwargs: 'FuncOptionArgs') -> None:
description = kwargs['description'] or opt_name

# Drop the arguments we've already consumed
n_kwargs = {k: v for k, v in kwargs.items()
if k not in {'type', 'description', 'deprecated', 'yield'}}
n_kwargs = T.cast(
'TYPE_kwargs',
{k: v for k, v in kwargs.items() if k not in {'type', 'description', 'deprecated', 'yield'}})

opt = parser(opt_name, description, (kwargs['yield'], kwargs['deprecated']), n_kwargs)
opt = parser((opt_name, description, kwargs['yield'], kwargs['deprecated']), n_kwargs)
if key in self.options:
mlog.deprecation(f'Option {opt_name} already exists.')
self.options[key] = opt
Expand All @@ -211,8 +214,9 @@ def func_option(self, args: T.Tuple[str], kwargs: 'FuncOptionArgs') -> None:
'string option',
KwargInfo('value', str, default=''),
)
def string_parser(self, name: str, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: StringArgs) -> options.UserOption:
return options.UserStringOption(name, description, kwargs['value'], *args)
def string_parser(self, args: T.Tuple[str, str, bool, _DEPRECATED_ARGS], kwargs: StringArgs) -> options.UserOption:
name, description, yielding, deprecated = args
return options.UserStringOption(name, description, kwargs['value'], yielding, deprecated)

@typed_kwargs(
'boolean option',
Expand All @@ -224,21 +228,22 @@ def string_parser(self, name: str, description: str, args: T.Tuple[bool, _DEPREC
deprecated_values={str: ('1.1.0', 'use a boolean, not a string')},
),
)
def boolean_parser(self, name: str, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: BooleanArgs) -> options.UserOption:
yielding, deprecated = args
def boolean_parser(self, args: T.Tuple[str, str, bool, _DEPRECATED_ARGS], kwargs: BooleanArgs) -> options.UserOption:
name, description, yielding, deprecated = args
return options.UserBooleanOption(name, description, kwargs['value'], yielding=yielding, deprecated=deprecated)

@typed_kwargs(
'combo option',
KwargInfo('value', (str, NoneType)),
KwargInfo('choices', ContainerTypeInfo(list, str, allow_empty=False), required=True),
)
def combo_parser(self, name: str, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: ComboArgs) -> options.UserOption:
def combo_parser(self, args: T.Tuple[str, str, bool, _DEPRECATED_ARGS], kwargs: ComboArgs) -> options.UserOption:
choices = kwargs['choices']
value = kwargs['value']
if value is None:
value = kwargs['choices'][0]
return options.UserComboOption(name, description, value, *args, choices=choices)
value = choices[0]
name, description, yielding, deprecated = args
return options.UserComboOption(name, description, value, yielding, deprecated, choices=choices)

@typed_kwargs(
'integer option',
Expand All @@ -252,32 +257,35 @@ def combo_parser(self, name: str, description: str, args: T.Tuple[bool, _DEPRECA
KwargInfo('min', (int, NoneType)),
KwargInfo('max', (int, NoneType)),
)
def integer_parser(self, name: str, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: IntegerArgs) -> options.UserOption:
def integer_parser(self, args: T.Tuple[str, str, bool, _DEPRECATED_ARGS], kwargs: IntegerArgs) -> options.UserOption:
name, description, yielding, deprecated = args
return options.UserIntegerOption(
name, description, kwargs['value'], *args, min_value=kwargs['min'], max_value=kwargs['max'])
name, description, kwargs['value'], yielding, deprecated, min_value=kwargs['min'], max_value=kwargs['max'])

@typed_kwargs(
'string array option',
KwargInfo('value', (ContainerTypeInfo(list, str), str, NoneType)),
KwargInfo('choices', ContainerTypeInfo(list, str), default=[]),
)
def string_array_parser(self, name: str, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: StringArrayArgs) -> options.UserOption:
def string_array_parser(self, args: T.Tuple[str, str, bool, _DEPRECATED_ARGS], kwargs: StringArrayArgs) -> options.UserOption:
choices = kwargs['choices']
value = kwargs['value'] if kwargs['value'] is not None else choices
if isinstance(value, str):
if value.startswith('['):
FeatureDeprecated('String value for array option', '1.3.0').use(self.subproject)
else:
raise mesonlib.MesonException('Value does not define an array: ' + value)
name, description, yielding, deprecated = args
return options.UserStringArrayOption(
name, description, value,
choices=choices,
yielding=args[0],
deprecated=args[1])
yielding=yielding,
deprecated=deprecated)

@typed_kwargs(
'feature option',
KwargInfo('value', str, default='auto', validator=in_set_validator({'auto', 'enabled', 'disabled'})),
)
def feature_parser(self, name: str, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: FeatureArgs) -> options.UserOption:
return options.UserFeatureOption(name, description, kwargs['value'], *args)
def feature_parser(self, args: T.Tuple[str, str, bool, _DEPRECATED_ARGS], kwargs: FeatureArgs) -> options.UserOption:
name, description, yielding, deprecated = args
return options.UserFeatureOption(name, description, kwargs['value'], yielding, deprecated)
Loading