summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2024-09-06 11:52:56 -0700
committerJussi Pakkanen <jpakkane@gmail.com>2025-02-05 17:45:38 +0200
commit9fd5281befe7881c9d1210c9e6865382bc0f2b08 (patch)
tree45530ef9752f3537f23dd564f2fb6c657417fc0f
parent8eba69cbaaa6498ecb0a43fac64e81b7f764d572 (diff)
downloadmeson-9fd5281befe7881c9d1210c9e6865382bc0f2b08.tar.gz
options: Replace uses of `UserOption[T.Any]` with a Union of UserOption types
The fact that UserOption is generic is really an implementation detail, not something to be used publicly. So by having an `AnyOptionType` alias, we can get better type checking, as can be seen by the patch as a whole. One of the big fixes it replace open-coded equivlalents of `MutableKeydOptionDictType` with that type alias.
-rw-r--r--mesonbuild/compilers/compilers.py3
-rw-r--r--mesonbuild/coredata.py4
-rw-r--r--mesonbuild/mconf.py6
-rw-r--r--mesonbuild/mintro.py4
-rw-r--r--mesonbuild/optinterpreter.py2
-rw-r--r--mesonbuild/options.py30
6 files changed, 24 insertions, 25 deletions
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 5777f19f1..0f7ef172f 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -35,7 +35,6 @@ if T.TYPE_CHECKING:
from ..dependencies import Dependency
CompilerType = T.TypeVar('CompilerType', bound='Compiler')
- UserOptionType = T.TypeVar('UserOptionType', bound=options.UserOption)
_T = T.TypeVar('_T')
@@ -592,7 +591,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
return f'{self.language}_{key.name}'
@staticmethod
- def update_options(options: MutableKeyedOptionDictType, *args: T.Tuple[OptionKey, UserOptionType]) -> MutableKeyedOptionDictType:
+ def update_options(options: MutableKeyedOptionDictType, *args: T.Tuple[OptionKey, options.AnyOptionType]) -> MutableKeyedOptionDictType:
options.update(args)
return options
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index b9a6b6d5d..c2a7c140a 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -60,8 +60,8 @@ if T.TYPE_CHECKING:
cross_file: T.List[str]
native_file: T.List[str]
- OptionDictType = T.Union[T.Dict[str, 'options.UserOption[T.Any]'], 'OptionsView']
- MutableKeyedOptionDictType = T.Dict['OptionKey', 'options.UserOption[T.Any]']
+ OptionDictType = T.Union[T.Dict[str, options.AnyOptionType], 'OptionsView']
+ MutableKeyedOptionDictType = T.Dict['OptionKey', options.AnyOptionType]
KeyedOptionDictType = T.Union['options.OptionStore', 'OptionsView']
CompilerCheckCacheKey = T.Tuple[T.Tuple[str, ...], str, FileOrString, T.Tuple[str, ...], CompileCheckMode]
# code, args
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
index 7c2270edc..9d65cc26f 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -26,8 +26,6 @@ from .optinterpreter import OptionInterpreter
if T.TYPE_CHECKING:
from typing_extensions import Protocol
- from typing import Any
- from .options import UserOption
import argparse
class CMDOptions(coredata.SharedCMDOptions, Protocol):
@@ -189,7 +187,7 @@ class Conf:
items = [l[i] if l[i] else ' ' * four_column[i] for i in range(4)]
mlog.log(*items)
- def split_options_per_subproject(self, options: 'T.Union[dict[OptionKey, UserOption[Any]], coredata.KeyedOptionDictType]') -> T.Dict[str, 'coredata.MutableKeyedOptionDictType']:
+ def split_options_per_subproject(self, options: T.Union[coredata.MutableKeyedOptionDictType, coredata.KeyedOptionDictType]) -> T.Dict[str, 'coredata.MutableKeyedOptionDictType']:
result: T.Dict[str, 'coredata.MutableKeyedOptionDictType'] = {}
for k, o in options.items():
if k.subproject:
@@ -227,7 +225,7 @@ class Conf:
self._add_line(mlog.normal_yellow(section + ':'), '', '', '')
self.print_margin = 2
- def print_options(self, title: str, opts: 'T.Union[dict[OptionKey, UserOption[Any]], coredata.KeyedOptionDictType]') -> None:
+ def print_options(self, title: str, opts: T.Union[coredata.MutableKeyedOptionDictType, coredata.KeyedOptionDictType]) -> None:
if not opts:
return
if title:
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index 4b65c5aca..383f15473 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -30,8 +30,6 @@ from .mparser import FunctionNode, ArrayNode, ArgumentNode, StringNode
if T.TYPE_CHECKING:
import argparse
- from typing import Any
- from .options import UserOption
from .interpreter import Interpreter
from .mparser import BaseNode
@@ -306,7 +304,7 @@ def list_buildoptions(coredata: cdata.CoreData, subprojects: T.Optional[T.List[s
for s in subprojects:
core_options[k.evolve(subproject=s)] = v
- def add_keys(opts: 'T.Union[dict[OptionKey, UserOption[Any]], cdata.KeyedOptionDictType]', section: str) -> None:
+ def add_keys(opts: T.Union[cdata.MutableKeyedOptionDictType, cdata.KeyedOptionDictType], section: str) -> None:
for key, opt in sorted(opts.items()):
optdict = {'name': str(key), 'value': opt.value, 'section': section,
'machine': key.machine.get_lower_case_name() if coredata.is_per_machine_option(key) else 'any'}
diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py
index 8c0d1daec..9f95925fa 100644
--- a/mesonbuild/optinterpreter.py
+++ b/mesonbuild/optinterpreter.py
@@ -69,7 +69,7 @@ class OptionInterpreter:
def __init__(self, optionstore: 'OptionStore', subproject: 'SubProject') -> None:
self.options: 'coredata.MutableKeyedOptionDictType' = {}
self.subproject = subproject
- self.option_types: T.Dict[str, T.Callable[..., options.UserOption]] = {
+ self.option_types: T.Dict[str, T.Callable[..., options.AnyOptionType]] = {
'string': self.string_parser,
'boolean': self.boolean_parser,
'combo': self.combo_parser,
diff --git a/mesonbuild/options.py b/mesonbuild/options.py
index 23dc5fc86..7aa9a5efa 100644
--- a/mesonbuild/options.py
+++ b/mesonbuild/options.py
@@ -32,6 +32,10 @@ if T.TYPE_CHECKING:
from typing_extensions import Literal, TypeAlias, TypedDict
DeprecatedType: TypeAlias = T.Union[bool, str, T.Dict[str, str], T.List[str]]
+ AnyOptionType: TypeAlias = T.Union[
+ 'UserBooleanOption', 'UserComboOption', 'UserFeatureOption',
+ 'UserIntegerOption', 'UserStdOption', 'UserStringArrayOption',
+ 'UserStringOption', 'UserUmaskOption']
class ArgparseKWs(TypedDict, total=False):
@@ -734,7 +738,7 @@ BUILTIN_DIR_NOPREFIX_OPTIONS: T.Dict[OptionKey, T.Dict[str, str]] = {
class OptionStore:
def __init__(self) -> None:
- self.d: T.Dict['OptionKey', 'UserOption[T.Any]'] = {}
+ self.d: T.Dict['OptionKey', AnyOptionType] = {}
self.project_options: T.Set[OptionKey] = set()
self.module_options: T.Set[OptionKey] = set()
from .compilers import all_languages
@@ -748,35 +752,35 @@ class OptionStore:
return OptionKey(key)
return key
- def get_value_object(self, key: T.Union[OptionKey, str]) -> 'UserOption[T.Any]':
+ def get_value_object(self, key: T.Union[OptionKey, str]) -> AnyOptionType:
return self.d[self.ensure_key(key)]
def get_value(self, key: T.Union[OptionKey, str]) -> 'T.Any':
return self.get_value_object(key).value
- def add_system_option(self, key: T.Union[OptionKey, str], valobj: 'UserOption[T.Any]') -> None:
+ def add_system_option(self, key: T.Union[OptionKey, str], valobj: AnyOptionType) -> None:
key = self.ensure_key(key)
if '.' in key.name:
raise MesonException(f'Internal error: non-module option has a period in its name {key.name}.')
self.add_system_option_internal(key, valobj)
- def add_system_option_internal(self, key: T.Union[OptionKey, str], valobj: 'UserOption[T.Any]') -> None:
+ def add_system_option_internal(self, key: T.Union[OptionKey, str], valobj: AnyOptionType) -> None:
key = self.ensure_key(key)
assert isinstance(valobj, UserOption)
self.d[key] = valobj
- def add_compiler_option(self, language: str, key: T.Union[OptionKey, str], valobj: 'UserOption[T.Any]') -> None:
+ def add_compiler_option(self, language: str, key: T.Union[OptionKey, str], valobj: AnyOptionType) -> None:
key = self.ensure_key(key)
if not key.name.startswith(language + '_'):
raise MesonException(f'Internal error: all compiler option names must start with language prefix. ({key.name} vs {language}_)')
self.add_system_option(key, valobj)
- def add_project_option(self, key: T.Union[OptionKey, str], valobj: 'UserOption[T.Any]') -> None:
+ def add_project_option(self, key: T.Union[OptionKey, str], valobj: AnyOptionType) -> None:
key = self.ensure_key(key)
self.d[key] = valobj
self.project_options.add(key)
- def add_module_option(self, modulename: str, key: T.Union[OptionKey, str], valobj: 'UserOption[T.Any]') -> None:
+ def add_module_option(self, modulename: str, key: T.Union[OptionKey, str], valobj: AnyOptionType) -> None:
key = self.ensure_key(key)
if key.name.startswith('build.'):
raise MesonException('FATAL internal error: somebody goofed option handling.')
@@ -790,7 +794,7 @@ class OptionStore:
return self.d[key].set_value(new_value)
# FIXME, this should be removed.or renamed to "change_type_of_existing_object" or something like that
- def set_value_object(self, key: T.Union[OptionKey, str], new_object: 'UserOption[T.Any]') -> None:
+ def set_value_object(self, key: T.Union[OptionKey, str], new_object: AnyOptionType) -> None:
key = self.ensure_key(key)
self.d[key] = new_object
@@ -807,20 +811,20 @@ class OptionStore:
def keys(self) -> T.KeysView[OptionKey]:
return self.d.keys()
- def values(self) -> T.ValuesView[UserOption[T.Any]]:
+ def values(self) -> T.ValuesView[AnyOptionType]:
return self.d.values()
- def items(self) -> T.ItemsView['OptionKey', 'UserOption[T.Any]']:
+ def items(self) -> T.ItemsView['OptionKey', AnyOptionType]:
return self.d.items()
# FIXME: this method must be deleted and users moved to use "add_xxx_option"s instead.
- def update(self, **kwargs: UserOption[T.Any]) -> None:
+ def update(self, **kwargs: AnyOptionType) -> None:
self.d.update(**kwargs)
- def setdefault(self, k: OptionKey, o: UserOption[T.Any]) -> UserOption[T.Any]:
+ def setdefault(self, k: OptionKey, o: AnyOptionType) -> AnyOptionType:
return self.d.setdefault(k, o)
- def get(self, o: OptionKey, default: T.Optional[UserOption[T.Any]] = None) -> T.Optional[UserOption[T.Any]]:
+ def get(self, o: OptionKey, default: T.Optional[AnyOptionType] = None) -> T.Optional[AnyOptionType]:
return self.d.get(o, default)
def is_project_option(self, key: OptionKey) -> bool: