diff options
author | Dylan Baker <dylan@pnwbakers.com> | 2022-02-28 15:12:35 -0800 |
---|---|---|
committer | Dylan Baker <dylan@pnwbakers.com> | 2022-03-03 10:29:14 -0800 |
commit | f4ae32c2ad4f4912867e1be6333371955bdaf83b (patch) | |
tree | 346af978dcb84fea339e658bbeef1cb06e641122 | |
parent | 5e4ea9f0f444120e566e364aba0b12f2520bd9ac (diff) | |
download | meson-f4ae32c2ad4f4912867e1be6333371955bdaf83b.zip meson-f4ae32c2ad4f4912867e1be6333371955bdaf83b.tar.gz meson-f4ae32c2ad4f4912867e1be6333371955bdaf83b.tar.bz2 |
modules/cmake: add type annotations for subproject method
This will be used to handle the interpreter subproject as well
-rw-r--r-- | mesonbuild/interpreter/dependencyfallbacks.py | 30 | ||||
-rw-r--r-- | mesonbuild/modules/cmake.py | 43 |
2 files changed, 46 insertions, 27 deletions
diff --git a/mesonbuild/interpreter/dependencyfallbacks.py b/mesonbuild/interpreter/dependencyfallbacks.py index 417c8cd..9194978 100644 --- a/mesonbuild/interpreter/dependencyfallbacks.py +++ b/mesonbuild/interpreter/dependencyfallbacks.py @@ -105,14 +105,14 @@ class DependencyFallbacksHolder(MesonInterpreterObject): def _do_subproject(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: TYPE_nkwargs) -> T.Optional[Dependency]: if self.forcefallback: mlog.log('Looking for a fallback subproject for the dependency', - mlog.bold(self.display_name), 'because:\nUse of fallback dependencies is forced.') + mlog.bold(self._display_name), 'because:\nUse of fallback dependencies is forced.') elif self.nofallback: mlog.log('Not looking for a fallback subproject for the dependency', - mlog.bold(self.display_name), 'because:\nUse of fallback dependencies is disabled.') + mlog.bold(self._display_name), 'because:\nUse of fallback dependencies is disabled.') return None else: mlog.log('Looking for a fallback subproject for the dependency', - mlog.bold(self.display_name)) + mlog.bold(self._display_name)) # dependency('foo', static: true) should implicitly add # default_options: ['default_library=static'] @@ -141,7 +141,7 @@ class DependencyFallbacksHolder(MesonInterpreterObject): # Verify the subproject is found subproject = self._get_subproject(subp_name) if not subproject: - mlog.log('Dependency', mlog.bold(self.display_name), 'from subproject', + mlog.log('Dependency', mlog.bold(self._display_name), 'from subproject', mlog.bold(subp_name), 'found:', mlog.red('NO'), mlog.blue('(subproject failed to configure)')) return None @@ -167,27 +167,27 @@ class DependencyFallbacksHolder(MesonInterpreterObject): # Legacy: Use the variable name if provided instead of relying on the # subproject to override one of our dependency names if not varname: - mlog.warning(f'Subproject {subp_name!r} did not override {self.display_name!r} dependency and no variable name specified') - mlog.log('Dependency', mlog.bold(self.display_name), 'from subproject', + mlog.warning(f'Subproject {subp_name!r} did not override {self._display_name!r} dependency and no variable name specified') + mlog.log('Dependency', mlog.bold(self._display_name), 'from subproject', mlog.bold(subproject.subdir), 'found:', mlog.red('NO')) return self._notfound_dependency() var_dep = self._get_subproject_variable(subproject, varname) or self._notfound_dependency() if not var_dep.found(): - mlog.log('Dependency', mlog.bold(self.display_name), 'from subproject', + mlog.log('Dependency', mlog.bold(self._display_name), 'from subproject', mlog.bold(subproject.subdir), 'found:', mlog.red('NO')) return var_dep wanted = stringlistify(kwargs.get('version', [])) found = var_dep.get_version() if not self._check_version(wanted, found): - mlog.log('Dependency', mlog.bold(self.display_name), 'from subproject', + mlog.log('Dependency', mlog.bold(self._display_name), 'from subproject', mlog.bold(subproject.subdir), 'found:', mlog.red('NO'), 'found', mlog.normal_cyan(found), 'but need:', mlog.bold(', '.join([f"'{e}'" for e in wanted]))) return self._notfound_dependency() - mlog.log('Dependency', mlog.bold(self.display_name), 'from subproject', + mlog.log('Dependency', mlog.bold(self._display_name), 'from subproject', mlog.bold(subproject.subdir), 'found:', mlog.green('YES'), mlog.normal_cyan(found) if found else None) return var_dep @@ -209,7 +209,7 @@ class DependencyFallbacksHolder(MesonInterpreterObject): # have explicitly called meson.override_dependency() with a not-found # dep. if not cached_dep.found(): - mlog.log('Dependency', mlog.bold(self.display_name), + mlog.log('Dependency', mlog.bold(self._display_name), 'found:', mlog.red('NO'), *info) return cached_dep else: @@ -231,7 +231,7 @@ class DependencyFallbacksHolder(MesonInterpreterObject): return self._notfound_dependency() if found_vers: info = [mlog.normal_cyan(found_vers), *info] - mlog.log('Dependency', mlog.bold(self.display_name), + mlog.log('Dependency', mlog.bold(self._display_name), 'found:', mlog.green('YES'), *info) return cached_dep return None @@ -298,14 +298,14 @@ class DependencyFallbacksHolder(MesonInterpreterObject): return candidates def lookup(self, kwargs: TYPE_nkwargs, force_fallback: bool = False) -> Dependency: - self.display_name = self.names[0] if self.names else '(anonymous)' + self._display_name = self.names[0] if self.names else '(anonymous)' mods = extract_as_list(kwargs, 'modules') if mods: - self.display_name += ' (modules: {})'.format(', '.join(str(i) for i in mods)) + self._display_name += ' (modules: {})'.format(', '.join(str(i) for i in mods)) disabled, required, feature = extract_required_kwarg(kwargs, self.subproject) if disabled: - mlog.log('Dependency', mlog.bold(self.display_name), 'skipped: feature', mlog.bold(feature), 'disabled') + mlog.log('Dependency', mlog.bold(self._display_name), 'skipped: feature', mlog.bold(feature), 'disabled') return self._notfound_dependency() # Check if usage of the subproject fallback is forced @@ -359,7 +359,7 @@ class DependencyFallbacksHolder(MesonInterpreterObject): # This was the last candidate or the dependency has been cached # as not-found, or cached dependency version does not match, # otherwise func() would have returned None instead. - raise DependencyException(f'Dependency {self.display_name!r} is required but not found.') + raise DependencyException(f'Dependency {self._display_name!r} is required but not found.') elif dep: # Same as above, but the dependency is not required. return dep diff --git a/mesonbuild/modules/cmake.py b/mesonbuild/modules/cmake.py index b046371..f996087 100644 --- a/mesonbuild/modules/cmake.py +++ b/mesonbuild/modules/cmake.py @@ -11,6 +11,8 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + +from __future__ import annotations import re import os, os.path, pathlib import shutil @@ -21,11 +23,10 @@ from . import ExtensionModule, ModuleReturnValue, ModuleObject from .. import build, mesonlib, mlog, dependencies from ..cmake import SingleTargetOptions, TargetOptions, cmake_defines_to_args from ..interpreter import SubprojectHolder -from ..interpreter.type_checking import NoneType, in_set_validator +from ..interpreter.type_checking import REQUIRED_KW, NoneType, in_set_validator from ..interpreterbase import ( FeatureNew, FeatureNewKwargs, - FeatureDeprecatedKwargs, stringArgs, permittedKwargs, @@ -35,6 +36,7 @@ from ..interpreterbase import ( InvalidArguments, InterpreterException, + typed_pos_args, typed_kwargs, KwargInfo, ContainerTypeInfo, @@ -43,6 +45,9 @@ from ..interpreterbase import ( if T.TYPE_CHECKING: from typing_extensions import TypedDict + from . import ModuleState + from ..interpreter import kwargs + class WriteBasicPackageVersionFile(TypedDict): arch_independent: bool @@ -58,6 +63,12 @@ if T.TYPE_CHECKING: install_dir: T.Optional[str] name: str + class Subproject(kwargs.ExtractRequired): + + options: T.Optional[CMakeSubprojectOptions] + cmake_options: T.List[str] + + COMPATIBILITIES = ['AnyNewerVersion', 'SameMajorVersion', 'SameMinorVersion', 'ExactVersion'] # Taken from https://github.com/Kitware/CMake/blob/master/Modules/CMakePackageConfigHelpers.cmake @@ -91,7 +102,7 @@ endmacro() ''' class CMakeSubproject(ModuleObject): - def __init__(self, subp, pv): + def __init__(self, subp: SubprojectHolder): assert isinstance(subp, SubprojectHolder) assert hasattr(subp, 'cm_interpreter') super().__init__() @@ -400,20 +411,28 @@ class CmakeModule(ExtensionModule): return res @FeatureNew('subproject', '0.51.0') - @FeatureNewKwargs('subproject', '0.55.0', ['options']) - @FeatureDeprecatedKwargs('subproject', '0.55.0', ['cmake_options']) - @permittedKwargs({'cmake_options', 'required', 'options'}) - @stringArgs - def subproject(self, state, args, kwargs): - if len(args) != 1: - raise InterpreterException('Subproject takes exactly one argument') - if 'cmake_options' in kwargs and 'options' in kwargs: + @typed_pos_args('cmake.subproject', str) + @typed_kwargs( + 'cmake.subproject', + REQUIRED_KW, + KwargInfo('options', (CMakeSubprojectOptions, NoneType), since='0.55.0'), + KwargInfo( + 'cmake_options', + ContainerTypeInfo(list, str), + default=[], + listify=True, + deprecated='0.55.0', + deprecated_message='Use options instead', + ), + ) + def subproject(self, state: ModuleState, args: T.Tuple[str], kwargs: Subproject) -> T.Union[SubprojectHolder, CMakeSubproject]: + if kwargs['cmake_options'] and kwargs['options'] is not None: raise InterpreterException('"options" cannot be used together with "cmake_options"') dirname = args[0] subp = self.interpreter.do_subproject(dirname, 'cmake', kwargs) if not subp.found(): return subp - return CMakeSubproject(subp, dirname) + return CMakeSubproject(subp) @FeatureNew('subproject_options', '0.55.0') @noKwargs |