From 502f3e4dc4df5f81fbfe12b4b06c106dff8ccfda Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 29 Jan 2025 13:40:55 -0800 Subject: [PATCH] Add a fallback parameter to `get_value_safe` This allows us to get rid of some `if key in optstore optstore.get_value` and some wrapper functions around the optstore --- mesonbuild/backend/ninjabackend.py | 8 ++------ mesonbuild/compilers/compilers.py | 25 ++++++------------------- mesonbuild/coredata.py | 16 ++++++++++++---- mesonbuild/dependencies/qt.py | 6 ++---- mesonbuild/options.py | 16 ++++++++++++---- 5 files changed, 34 insertions(+), 37 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index f6ed3941eda2..4d9890ddfc7d 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -3746,9 +3746,7 @@ def generate_clangtool(self, name: str, extra_arg: T.Optional[str] = None) -> No if extra_arg: target_name += f'-{extra_arg}' extra_args.append(f'--{extra_arg}') - # TODO: fallback parameter - colorout = self.environment.coredata.optstore.get_value_safe('b_colorout', str) \ - if OptionKey('b_colorout') in self.environment.coredata.optstore else 'always' + colorout = self.environment.coredata.optstore.get_value_safe('b_colorout', str, 'always') extra_args.extend(['--color', colorout]) if not os.path.exists(os.path.join(self.environment.source_dir, '.clang-' + name)) and \ not os.path.exists(os.path.join(self.environment.source_dir, '_clang-' + name)): @@ -3843,9 +3841,7 @@ def generate_ending(self) -> None: if ctlist: elem.add_dep(self.generate_custom_target_clean(ctlist)) - # TODO: fallback parameter - if OptionKey('b_coverage') in self.environment.coredata.optstore and \ - self.environment.coredata.optstore.get_value_safe('b_coverage', bool): + if self.environment.coredata.optstore.get_value_safe('b_coverage', bool, False): self.generate_gcov_clean() elem.add_dep('clean-gcda') elem.add_dep('clean-gcno') diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 4a6ef414f471..fcde6995a790 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -266,19 +266,6 @@ def option_enabled(boptions: T.Set[OptionKey], options: 'KeyedOptionDictType', return False -# TODO: replace with fallback parameter in get_value_safe -def get_option_value(options: 'KeyedOptionDictType', opt: OptionKey, fallback: '_T') -> '_T': - """Get the value of an option, or the fallback value.""" - try: - v = T.cast('_T', options.get_value(opt)) - except (KeyError, AttributeError): - return fallback - - assert isinstance(v, type(fallback)), f'Should have {type(fallback)!r} but was {type(v)!r}' - # Mypy doesn't understand that the above assert ensures that v is type _T - return v - - def are_asserts_disabled(options: KeyedOptionDictType) -> bool: """Should debug assertions be disabled @@ -295,8 +282,8 @@ def get_base_compile_args(options: 'KeyedOptionDictType', compiler: 'Compiler', try: if options.get_value_safe(OptionKey('b_lto'), bool): args.extend(compiler.get_lto_compile_args( - threads=get_option_value(options, OptionKey('b_lto_threads'), 0), - mode=get_option_value(options, OptionKey('b_lto_mode'), 'default'))) + threads=options.get_value_safe(OptionKey('b_lto_threads'), int, 0), + mode=options.get_value_safe(OptionKey('b_lto_mode'), str, 'default'))) except (KeyError, AttributeError): pass try: @@ -347,13 +334,13 @@ def get_base_link_args(options: 'KeyedOptionDictType', linker: 'Compiler', args.extend(linker.get_werror_args()) thinlto_cache_dir = None - if get_option_value(options, OptionKey('b_thinlto_cache'), False): - thinlto_cache_dir = get_option_value(options, OptionKey('b_thinlto_cache_dir'), '') + if options.get_value_safe(OptionKey('b_thinlto_cache'), bool, False): + thinlto_cache_dir = options.get_value_safe(OptionKey('b_thinlto_cache_dir'), str, '') if thinlto_cache_dir == '': thinlto_cache_dir = os.path.join(build_dir, 'meson-private', 'thinlto-cache') args.extend(linker.get_lto_link_args( - threads=get_option_value(options, OptionKey('b_lto_threads'), 0), - mode=get_option_value(options, OptionKey('b_lto_mode'), 'default'), + threads=options.get_value_safe(OptionKey('b_lto_threads'), int, 0), + mode=options.get_value_safe(OptionKey('b_lto_mode'), str, 'default'), thinlto_cache_dir=thinlto_cache_dir)) except (KeyError, AttributeError): pass diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 738b119a5e32..99fd91f578a5 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -964,10 +964,18 @@ def get_value(self, key: T.Union[str, OptionKey]) -> ElementaryOptionValues: key = OptionKey(key) return self[key].value - def get_value_safe(self, key: T.Union[OptionKey, str], type_: T.Type[ElementaryOptionTypes]) -> ElementaryOptionTypes: - v = self.get_value(key) - assert isinstance(v, type_), 'for mypy' - return v + def get_value_safe(self, key: T.Union[OptionKey, str], + type_: T.Type[ElementaryOptionTypes], + fallback: T.Optional[ElementaryOptionTypes] = None, + ) -> ElementaryOptionTypes: + try: + v = self.get_value(key) + assert isinstance(v, type_), 'for mypy' + return v + except KeyError: + if fallback is not None: + return fallback + raise def set_value(self, key: T.Union[str, OptionKey], value: ElementaryOptionValues) -> None: if isinstance(key, str): diff --git a/mesonbuild/dependencies/qt.py b/mesonbuild/dependencies/qt.py index 717fd97bf103..07f0b4ad97ea 100644 --- a/mesonbuild/dependencies/qt.py +++ b/mesonbuild/dependencies/qt.py @@ -298,10 +298,8 @@ def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]): # Use the buildtype by default, but look at the b_vscrt option if the # compiler supports it. is_debug = self.env.coredata.get_option(OptionKey('buildtype')) == 'debug' - # TODO: fallback - if OptionKey('b_vscrt') in self.env.coredata.optstore: - if self.env.coredata.optstore.get_value_safe('b_vscrt', str) in {'mdd', 'mtd'}: - is_debug = True + if self.env.coredata.optstore.get_value_safe('b_vscrt', str, '') in {'mdd', 'mtd'}: + is_debug = True modules_lib_suffix = _get_modules_lib_suffix(self.version, self.env.machines[self.for_machine], is_debug) for module in self.requested_modules: diff --git a/mesonbuild/options.py b/mesonbuild/options.py index 7e3de59c7870..c538709182de 100644 --- a/mesonbuild/options.py +++ b/mesonbuild/options.py @@ -760,10 +760,18 @@ def get_value_object(self, key: T.Union[OptionKey, str]) -> AnyOptionType: def get_value(self, key: T.Union[OptionKey, str]) -> ElementaryOptionValues: return self.get_value_object(key).value - def get_value_safe(self, key: T.Union[OptionKey, str], type_: T.Type[ElementaryOptionTypes]) -> ElementaryOptionTypes: - v = self.get_value_object(key).value - assert isinstance(v, type_), 'for mypy' - return v + def get_value_safe(self, key: T.Union[OptionKey, str], + type_: T.Type[ElementaryOptionTypes], + fallback: T.Optional[ElementaryOptionTypes] = None, + ) -> ElementaryOptionTypes: + try: + v = self.get_value_object(key).value + assert isinstance(v, type_), 'for mypy' + return v + except KeyError: + if fallback is not None: + return fallback + raise def add_system_option(self, key: T.Union[OptionKey, str], valobj: AnyOptionType) -> None: key = self.ensure_key(key)