From c42262131706143e1a213d0bac659085822a0759 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 1 Jun 2021 21:39:42 -0700 Subject: [PATCH] interpreterobjects|build: use typed_kwargs for generator.process --- mesonbuild/build.py | 13 +++---- mesonbuild/interpreter/interpreterobjects.py | 41 ++++++++++++-------- mesonbuild/interpreter/kwargs.py | 8 ++++ mesonbuild/modules/qt.py | 6 +-- 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 9d1c0f9e2..e3a7bb5b2 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -43,6 +43,7 @@ if T.TYPE_CHECKING: from ._typing import ImmutableListProtocol, ImmutableSetProtocol from .interpreter.interpreter import Test, SourceOutputs, Interpreter from .mesonlib import FileMode, FileOrString + from .modules import ModuleState from .backend.backends import Backend from .interpreter.interpreterobjects import GeneratorHolder @@ -1543,9 +1544,10 @@ class Generator: relpath = pathlib.PurePath(trial).relative_to(parent) return relpath.parts[0] != '..' # For subdirs we can only go "down". - def process_files(self, files: T.List[T.Union[str, File, 'CustomTarget', 'CustomTargetIndex', 'GeneratedList']], - state, preserve_path_from=None, extra_args=None): - new = False + def process_files(self, files: T.Iterable[T.Union[str, File, 'CustomTarget', 'CustomTargetIndex', 'GeneratedList']], + state: T.Union['Interpreter', 'ModuleState'], + preserve_path_from: T.Optional[str] = None, + extra_args: T.Optional[T.List[str]] = None) -> 'GeneratedList': output = GeneratedList(self, state.subdir, preserve_path_from, extra_args=extra_args if extra_args is not None else []) #XXX for e in files: @@ -1559,7 +1561,6 @@ class Generator: fs = [] for f in e.get_outputs(): fs.append(File.from_built_file(state.subdir, f)) - new = True elif isinstance(e, str): fs = [File.from_source_file(state.environment.source_dir, state.subdir, e)] @@ -1569,10 +1570,6 @@ class Generator: if not self.is_parent_path(preserve_path_from, abs_f): raise InvalidArguments('generator.process: When using preserve_path_from, all input files must be in a subdirectory of the given dir.') output.add_file(f, state) - if new: - FeatureNew.single_use( - f'Calling "{self.name}" with CustomTaget or Index of CustomTarget.', - '0.57.0', state.subproject) return output diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index a080c05dd..42d983f7a 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -13,11 +13,14 @@ from .. import mlog from ..modules import ModuleReturnValue, ModuleObject, ModuleState, ExtensionModule from ..backend.backends import TestProtocol -from ..interpreterbase import (InterpreterObject, ObjectHolder, MutableInterpreterObject, - FeatureNewKwargs, FeatureNew, FeatureDeprecated, typed_kwargs, - typed_pos_args, stringArgs, permittedKwargs, - noArgsFlattening, noPosargs, TYPE_var, TYPE_nkwargs, - flatten, InterpreterException, InvalidArguments, InvalidCode) +from ..interpreterbase import (ContainerTypeInfo, InterpreterObject, KwargInfo, + ObjectHolder, MutableInterpreterObject, + FeatureNewKwargs, FeatureNew, FeatureDeprecated, + typed_kwargs, typed_pos_args, stringArgs, + permittedKwargs, noArgsFlattening, noPosargs, + TYPE_var, TYPE_nkwargs, flatten, + InterpreterException, InvalidArguments, + InvalidCode) from ..interpreterbase.decorators import FeatureCheckBase from ..dependencies import Dependency, ExternalLibrary, InternalDependency from ..programs import ExternalProgram @@ -1029,21 +1032,27 @@ class GeneratorHolder(InterpreterObject, ObjectHolder[build.Generator]): self.interpreter = interpreter self.methods.update({'process': self.process_method}) - @FeatureNewKwargs('generator.process', '0.45.0', ['preserve_path_from']) - @permittedKwargs({'extra_args', 'preserve_path_from'}) @typed_pos_args('generator.process', min_varargs=1, varargs=(str, mesonlib.File, CustomTargetHolder, CustomTargetIndexHolder, GeneratedListHolder)) - def process_method(self, args: T.Tuple[T.List[T.Union[str, mesonlib.File, CustomTargetHolder, CustomTargetIndexHolder, GeneratedListHolder]]], kwargs): - extras = mesonlib.stringlistify(kwargs.get('extra_args', [])) - if 'preserve_path_from' in kwargs: - preserve_path_from = kwargs['preserve_path_from'] - if not isinstance(preserve_path_from, str): - raise InvalidArguments('Preserve_path_from must be a string.') + @typed_kwargs( + 'generator.process', + KwargInfo('preserve_path_from', str, since='0.45.0'), + KwargInfo('extra_args', ContainerTypeInfo(list, str), listify=True, default=[]), + ) + def process_method(self, args: T.Tuple[T.List[T.Union[str, mesonlib.File, CustomTargetHolder, CustomTargetIndexHolder, GeneratedListHolder]]], + kwargs: 'kwargs.GeneratorProcess') -> GeneratedListHolder: + preserve_path_from = kwargs['preserve_path_from'] + if preserve_path_from is not None: preserve_path_from = os.path.normpath(preserve_path_from) if not os.path.isabs(preserve_path_from): # This is a bit of a hack. Fix properly before merging. raise InvalidArguments('Preserve_path_from must be an absolute path for now. Sorry.') - else: - preserve_path_from = None + + if any(isinstance(a, (CustomTargetHolder, CustomTargetIndexHolder, GeneratedListHolder)) for a in args[0]): + FeatureNew.single_use( + f'Calling generator.process with CustomTaget or Index of CustomTarget.', + '0.57.0', self.interpreter.subproject) + gl = self.held_object.process_files(mesonlib.unholder(args[0]), self.interpreter, - preserve_path_from, extra_args=extras) + preserve_path_from, extra_args=kwargs['extra_args']) + return GeneratedListHolder(gl) diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py index b856e680c..9734caab2 100644 --- a/mesonbuild/interpreter/kwargs.py +++ b/mesonbuild/interpreter/kwargs.py @@ -82,3 +82,11 @@ class FuncGenerator(TypedDict): depfile: bool capture: bool depends: T.List[T.Union['BuildTargetHolder', 'CustomTargetHolder']] + + +class GeneratorProcess(TypedDict): + + """Keyword Arguments for generator.process.""" + + preserve_path_from: T.Optional[str] + extra_args: T.List[str] diff --git a/mesonbuild/modules/qt.py b/mesonbuild/modules/qt.py index adfc8e291..1d38cbe72 100644 --- a/mesonbuild/modules/qt.py +++ b/mesonbuild/modules/qt.py @@ -350,7 +350,7 @@ class QtBaseModule(ExtensionModule): kwargs['extra_args'] + ['-o', '@OUTPUT@', '@INPUT@'], ['ui_@BASENAME@.h'], name=f'Qt{self.qt_version} ui') - out = gen.process_files(kwargs['sources'], state) # type: ignore + out = gen.process_files(kwargs['sources'], state) return ModuleReturnValue(out, [out]) @FeatureNew('qt.compile_moc', '0.59.0') @@ -386,12 +386,12 @@ class QtBaseModule(ExtensionModule): moc_gen = build.Generator( self.moc, arguments, ['moc_@BASENAME@.cpp'], name=f'Qt{self.qt_version} moc header') - output.append(moc_gen.process_files(kwargs['headers'], state)) # type: ignore + output.append(moc_gen.process_files(kwargs['headers'], state)) if kwargs['sources']: moc_gen = build.Generator( self.moc, arguments, ['@BASENAME@.moc'], name=f'Qt{self.qt_version} moc source') - output.append(moc_gen.process_files(kwargs['sources'], state)) # type: ignore + output.append(moc_gen.process_files(kwargs['sources'], state)) return ModuleReturnValue(output, [output])