diff options
author | Dylan Baker <dylan@pnwbakers.com> | 2021-11-03 09:50:44 -0700 |
---|---|---|
committer | Dylan Baker <dylan@pnwbakers.com> | 2021-11-22 11:28:43 -0800 |
commit | f34013fb08b8d24d570c96084c5d58c5eaf4f5da (patch) | |
tree | 3ce788bf439e46f44e40e49d9af7a87a833de811 | |
parent | 75d163f56d8264a4e68343367f0b9580d746e21b (diff) | |
download | meson-f34013fb08b8d24d570c96084c5d58c5eaf4f5da.zip meson-f34013fb08b8d24d570c96084c5d58c5eaf4f5da.tar.gz meson-f34013fb08b8d24d570c96084c5d58c5eaf4f5da.tar.bz2 |
interpreter: use typed_kwargs for project
-rw-r--r-- | mesonbuild/interpreter/interpreter.py | 72 | ||||
-rw-r--r-- | mesonbuild/interpreter/kwargs.py | 9 | ||||
-rw-r--r-- | mesonbuild/interpreter/type_checking.py | 9 |
3 files changed, 62 insertions, 28 deletions
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 7518c6f..76096e9 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -56,6 +56,7 @@ from .type_checking import ( CT_INPUT_KW, CT_INSTALL_DIR_KW, CT_OUTPUT_KW, + DEFAULT_OPTIONS, DEPENDS_KW, DEPEND_FILES_KW, DEPFILE_KW, @@ -97,6 +98,15 @@ if T.TYPE_CHECKING: build.GeneratedList] +def _project_version_validator(value: T.Union[T.List, str, mesonlib.File, None]) -> T.Optional[str]: + if isinstance(value, list): + if len(value) != 1: + return 'when passed as array must have a length of 1' + elif not isinstance(value[0], (str, mesonlib.File)): + return 'when passed as array must contain a string or File' + return None + + def stringifyUserArguments(args, quote=False): if isinstance(args, list): return '[%s]' % ', '.join([stringifyUserArguments(x, True) for x in args]) @@ -1019,16 +1029,29 @@ external dependencies (including libraries) must go to "dependencies".''') options = {k: v for k, v in self.environment.options.items() if k.is_backend()} self.coredata.set_options(options) - @permittedKwargs({'version', 'meson_version', 'default_options', 'license', 'subproject_dir'}) @typed_pos_args('project', str, varargs=str) - def func_project(self, node: mparser.FunctionNode, args: T.Tuple[str, T.List[str]], kwargs: 'TYPE_kwargs') -> None: + @typed_kwargs( + 'project', + DEFAULT_OPTIONS, + KwargInfo('meson_version', (str, NoneType)), + KwargInfo( + 'version', + (str, mesonlib.File, NoneType, list), + default='undefined', + validator=_project_version_validator, + convertor=lambda x: x[0] if isinstance(x, list) else x, + ), + KwargInfo('license', ContainerTypeInfo(list, str), default=['unknown'], listify=True), + KwargInfo('subproject_dir', str, default='subprojects'), + ) + def func_project(self, node: mparser.FunctionNode, args: T.Tuple[str, T.List[str]], kwargs: 'kwargs.Project') -> None: proj_name, proj_langs = args if ':' in proj_name: raise InvalidArguments(f"Project name {proj_name!r} must not contain ':'") # This needs to be evaluated as early as possible, as meson uses this # for things like deprecation testing. - if 'meson_version' in kwargs: + if kwargs['meson_version']: cv = coredata.version pv = kwargs['meson_version'] if not mesonlib.version_compare(cv, pv): @@ -1045,8 +1068,8 @@ external dependencies (including libraries) must go to "dependencies".''') # values previously set from command line. That means that changing # default_options in a project will trigger a reconfigure but won't # have any effect. - self.project_default_options = mesonlib.stringlistify(kwargs.get('default_options', [])) - self.project_default_options = coredata.create_options_dict(self.project_default_options, self.subproject) + self.project_default_options = coredata.create_options_dict( + kwargs['default_options'], self.subproject) # If this is the first invocation we always need to initialize # builtins, if this is a subproject that is new in a re-invocation we @@ -1062,11 +1085,8 @@ external dependencies (including libraries) must go to "dependencies".''') if not self.is_subproject(): self.build.project_name = proj_name self.active_projectname = proj_name - version = kwargs.get('version', 'undefined') - if isinstance(version, list): - if len(version) != 1: - raise InvalidCode('Version argument is an array with more than one entry.') - version = version[0] + + version = kwargs['version'] if isinstance(version, mesonlib.File): FeatureNew.single_use('version from file', '0.57.0', self.subproject) self.add_build_def_file(version) @@ -1081,33 +1101,29 @@ external dependencies (including libraries) must go to "dependencies".''') if len(ver_data) != 1: raise InterpreterException('Version file must contain exactly one line of text.') self.project_version = ver_data[0] - elif isinstance(version, str): - self.project_version = version else: - raise InvalidCode('The version keyword argument must be a string or a file.') + self.project_version = version + if self.build.project_version is None: self.build.project_version = self.project_version - proj_license = mesonlib.stringlistify(kwargs.get('license', 'unknown')) + proj_license = kwargs['license'] self.build.dep_manifest[proj_name] = build.DepManifest(self.project_version, proj_license) if self.subproject in self.build.projects: raise InvalidCode('Second call to project().') # spdirname is the subproject_dir for this project, relative to self.subdir. # self.subproject_dir is the subproject_dir for the main project, relative to top source dir. - spdirname = kwargs.get('subproject_dir') - if spdirname: - if not isinstance(spdirname, str): - raise InterpreterException('Subproject_dir must be a string') - if os.path.isabs(spdirname): - raise InterpreterException('Subproject_dir must not be an absolute path.') - if spdirname.startswith('.'): - raise InterpreterException('Subproject_dir must not begin with a period.') - if '..' in spdirname: - raise InterpreterException('Subproject_dir must not contain a ".." segment.') - if not self.is_subproject(): - self.subproject_dir = spdirname - else: - spdirname = 'subprojects' + spdirname = kwargs['subproject_dir'] + if not isinstance(spdirname, str): + raise InterpreterException('Subproject_dir must be a string') + if os.path.isabs(spdirname): + raise InterpreterException('Subproject_dir must not be an absolute path.') + if spdirname.startswith('.'): + raise InterpreterException('Subproject_dir must not begin with a period.') + if '..' in spdirname: + raise InterpreterException('Subproject_dir must not contain a ".." segment.') + if not self.is_subproject(): + self.subproject_dir = spdirname self.build.subproject_dir = self.subproject_dir # Load wrap files from this (sub)project. diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py index 3eca65c..00dfdfd 100644 --- a/mesonbuild/interpreter/kwargs.py +++ b/mesonbuild/interpreter/kwargs.py @@ -195,3 +195,12 @@ class AddTestSetup(TypedDict): is_default: bool exclude_suites: T.List[str] env: build.EnvironmentVariables + + +class Project(TypedDict): + + version: T.Optional[FileOrString] + meson_version: T.Optional[str] + default_options: T.List[str] + license: T.List[str] + subproject_dir: str diff --git a/mesonbuild/interpreter/type_checking.py b/mesonbuild/interpreter/type_checking.py index 9e443ae..50164ee 100644 --- a/mesonbuild/interpreter/type_checking.py +++ b/mesonbuild/interpreter/type_checking.py @@ -285,3 +285,12 @@ INCLUDE_DIRECTORIES: KwargInfo[T.List[T.Union[str, IncludeDirs]]] = KwargInfo( listify=True, default=[], ) + +# for cases like default_options and override_options +DEFAULT_OPTIONS: KwargInfo[T.List[str]] = KwargInfo( + 'default_options', + ContainerTypeInfo(list, (str, IncludeDirs)), + listify=True, + default=[], + validator=_env_validator, +) |