modules/qt: fully annotate and check qt.has_tools

pull/8822/head
Dylan Baker 4 years ago
parent 61ddceb3b9
commit 2bc7a1b3da
  1. 13
      mesonbuild/interpreter/interpreterobjects.py
  2. 16
      mesonbuild/interpreter/kwargs.py
  3. 22
      mesonbuild/modules/qt.py
  4. 2
      mesonbuild/modules/unstable_rust.py

@ -18,17 +18,25 @@ from ..interpreterbase import (InterpreterObject, ObjectHolder, MutableInterpret
typed_pos_args, stringArgs, permittedKwargs, typed_pos_args, stringArgs, permittedKwargs,
noArgsFlattening, noPosargs, TYPE_var, TYPE_nkwargs, noArgsFlattening, noPosargs, TYPE_var, TYPE_nkwargs,
flatten, InterpreterException, InvalidArguments, InvalidCode) flatten, InterpreterException, InvalidArguments, InvalidCode)
from ..interpreterbase.decorators import FeatureCheckBase
from ..dependencies import Dependency, ExternalLibrary, InternalDependency from ..dependencies import Dependency, ExternalLibrary, InternalDependency
from ..programs import ExternalProgram from ..programs import ExternalProgram
from ..mesonlib import FileMode, OptionKey, listify, Popen_safe from ..mesonlib import FileMode, OptionKey, listify, Popen_safe
import typing as T import typing as T
def extract_required_kwarg(kwargs, subproject, feature_check=None, default=True): if T.TYPE_CHECKING:
from . import kwargs
from .interpreter import Interpreter
def extract_required_kwarg(kwargs: 'kwargs.ExtractRequired', subproject: str,
feature_check: T.Optional['FeatureCheckBase'] = None,
default: bool = True) -> T.Tuple[bool, bool, T.Optional[str]]:
val = kwargs.get('required', default) val = kwargs.get('required', default)
disabled = False disabled = False
required = False required = False
feature = None feature: T.Optional[str] = None
if isinstance(val, FeatureOptionHolder): if isinstance(val, FeatureOptionHolder):
if not feature_check: if not feature_check:
feature_check = FeatureNew('User option "feature"', '0.47.0') feature_check = FeatureNew('User option "feature"', '0.47.0')
@ -46,6 +54,7 @@ def extract_required_kwarg(kwargs, subproject, feature_check=None, default=True)
# Keep boolean value in kwargs to simplify other places where this kwarg is # Keep boolean value in kwargs to simplify other places where this kwarg is
# checked. # checked.
# TODO: this should be removed, and those callers should learn about FeatureOptions
kwargs['required'] = required kwargs['required'] = required
return disabled, required, feature return disabled, required, feature

@ -9,7 +9,10 @@ import typing as T
from typing_extensions import TypedDict, Literal from typing_extensions import TypedDict, Literal
from ..mesonlib import MachineChoice, File from ..mesonlib import MachineChoice, File
from .interpreterobjects import BuildTargetHolder, CustomTargetHolder, EnvironmentVariablesHolder, TargetHolder from .interpreterobjects import (
BuildTargetHolder, CustomTargetHolder, EnvironmentVariablesHolder,
FeatureOptionHolder, TargetHolder
)
class FuncAddProjectArgs(TypedDict): class FuncAddProjectArgs(TypedDict):
@ -57,3 +60,14 @@ class FuncTest(FuncBenchmark):
""" """
is_parallel: bool is_parallel: bool
class ExtractRequired(TypedDict):
"""Keyword Arguments consumed by the `extract_required_kwargs` function.
Any function that uses the `required` keyword argument which accepts either
a boolean or a feature option should inherit it's arguments from this class.
"""
required: T.Union[bool, 'FeatureOptionHolder']

@ -26,12 +26,13 @@ from . import ModuleReturnValue, ExtensionModule
from ..interpreterbase import ContainerTypeInfo, FeatureDeprecated, FeatureDeprecatedKwargs, KwargInfo, noPosargs, permittedKwargs, FeatureNew, FeatureNewKwargs, typed_kwargs from ..interpreterbase import ContainerTypeInfo, FeatureDeprecated, FeatureDeprecatedKwargs, KwargInfo, noPosargs, permittedKwargs, FeatureNew, FeatureNewKwargs, typed_kwargs
from ..interpreter import extract_required_kwarg from ..interpreter import extract_required_kwarg
from ..programs import NonExistingExternalProgram from ..programs import NonExistingExternalProgram
from ..interpreter.interpreterobjects import DependencyHolder, ExternalLibraryHolder, IncludeDirsHolder from ..interpreter.interpreterobjects import DependencyHolder, ExternalLibraryHolder, IncludeDirsHolder, FeatureOptionHolder
if T.TYPE_CHECKING: if T.TYPE_CHECKING:
from . import ModuleState from . import ModuleState
from ..dependencies.qt import QtPkgConfigDependency, QmakeQtDependency from ..dependencies.qt import QtPkgConfigDependency, QmakeQtDependency
from ..interpreter import Interpreter from ..interpreter import Interpreter
from ..interpreter import kwargs
from ..programs import ExternalProgram from ..programs import ExternalProgram
QtDependencyType = T.Union[QtPkgConfigDependency, QmakeQtDependency] QtDependencyType = T.Union[QtPkgConfigDependency, QmakeQtDependency]
@ -79,6 +80,10 @@ if T.TYPE_CHECKING:
dependencies: T.List[T.Union[DependencyHolder, ExternalLibraryHolder]] dependencies: T.List[T.Union[DependencyHolder, ExternalLibraryHolder]]
method: str method: str
class HasToolKwArgs(kwargs.ExtractRequired):
method: str
class QtBaseModule(ExtensionModule): class QtBaseModule(ExtensionModule):
_tools_detected = False _tools_detected = False
@ -221,11 +226,19 @@ class QtBaseModule(ExtensionModule):
result.append(File(is_built=False, subdir=state.subdir, fname=path_from_rcc)) result.append(File(is_built=False, subdir=state.subdir, fname=path_from_rcc))
return result return result
@FeatureNew('qt.has_tools', '0.54.0')
@noPosargs @noPosargs
@typed_kwargs(
'qt.has_tools',
KwargInfo('required', (bool, FeatureOptionHolder), default=False),
KwargInfo('method', str, default='auto'),
)
@permittedKwargs({'method', 'required'}) @permittedKwargs({'method', 'required'})
@FeatureNew('qt.has_tools', '0.54.0') def has_tools(self, state: 'ModuleState', args: T.Tuple, kwargs: 'HasToolKwArgs') -> bool:
def has_tools(self, state: 'ModuleState', args: T.Tuple, kwargs) -> bool:
method = kwargs.get('method', 'auto') method = kwargs.get('method', 'auto')
# We have to cast here because TypedDicts are invariant, even though
# ExtractRequiredKwArgs is a subset of HasToolKwArgs, type checkers
# will insist this is wrong
disabled, required, feature = extract_required_kwarg(kwargs, state.subproject, default=False) disabled, required, feature = extract_required_kwarg(kwargs, state.subproject, default=False)
if disabled: if disabled:
mlog.log('qt.has_tools skipped: feature', mlog.bold(feature), 'disabled') mlog.log('qt.has_tools skipped: feature', mlog.bold(feature), 'disabled')
@ -429,7 +442,8 @@ class QtBaseModule(ExtensionModule):
@FeatureNewKwargs('qt.compile_translations', '0.56.0', ['qresource']) @FeatureNewKwargs('qt.compile_translations', '0.56.0', ['qresource'])
@FeatureNewKwargs('qt.compile_translations', '0.56.0', ['rcc_extra_arguments']) @FeatureNewKwargs('qt.compile_translations', '0.56.0', ['rcc_extra_arguments'])
@permittedKwargs({'ts_files', 'qresource', 'rcc_extra_arguments', 'install', 'install_dir', 'build_by_default', 'method'}) @permittedKwargs({'ts_files', 'qresource', 'rcc_extra_arguments', 'install', 'install_dir', 'build_by_default', 'method'})
def compile_translations(self, state, args, kwargs): @noPosargs
def compile_translations(self, state: 'ModuleState', args: T.Tuple, kwargs: T.Dict[str, T.Any]) -> ModuleReturnValue:
ts_files, install_dir = [extract_as_list(kwargs, c, pop=True) for c in ['ts_files', 'install_dir']] ts_files, install_dir = [extract_as_list(kwargs, c, pop=True) for c in ['ts_files', 'install_dir']]
qresource = kwargs.get('qresource') qresource = kwargs.get('qresource')
if qresource: if qresource:

@ -199,7 +199,7 @@ class RustModule(ExtensionModule):
if self._bindgen_bin is None: if self._bindgen_bin is None:
# there's some bugs in the interpreter typeing. # there's some bugs in the interpreter typeing.
self._bindgen_bin = T.cast('ExternalProgram', state.find_program('bindgen').held_object) self._bindgen_bin = state.find_program('bindgen').held_object
name: str name: str
if isinstance(header, File): if isinstance(header, File):

Loading…
Cancel
Save