diff options
| -rw-r--r-- | mesonbuild/dependencies/base.py | 32 | ||||
| -rw-r--r-- | mesonbuild/dependencies/detect.py | 25 | ||||
| -rw-r--r-- | mesonbuild/dependencies/misc.py | 2 | ||||
| -rw-r--r-- | mesonbuild/dependencies/qt.py | 2 | ||||
| -rw-r--r-- | mesonbuild/interpreter/interpreter.py | 1 | ||||
| -rw-r--r-- | mesonbuild/interpreter/kwargs.py | 3 | ||||
| -rw-r--r-- | mesonbuild/interpreter/type_checking.py | 32 | ||||
| -rw-r--r-- | mesonbuild/modules/_qt.py | 42 | ||||
| -rw-r--r-- | unittests/failuretests.py | 4 |
9 files changed, 72 insertions, 71 deletions
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index ead1eece6..d3678c619 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -49,6 +49,7 @@ if T.TYPE_CHECKING: include_type: IncludeType language: T.Optional[str] main: bool + method: DependencyMethods _MissingCompilerBase = Compiler else: @@ -102,12 +103,6 @@ class DependencyMethods(Enum): SYSCONFIG = 'sysconfig' # Specify using a "program"-config style tool CONFIG_TOOL = 'config-tool' - # For backwards compatibility - SDLCONFIG = 'sdlconfig' - CUPSCONFIG = 'cups-config' - PCAPCONFIG = 'pcap-config' - LIBWMFCONFIG = 'libwmf-config' - QMAKE = 'qmake' # Misc DUB = 'dub' @@ -614,30 +609,7 @@ def strip_system_includedirs(environment: 'Environment', for_machine: MachineCho return [i for i in include_args if i not in exclude] def process_method_kw(possible: T.Iterable[DependencyMethods], kwargs: DependencyObjectKWs) -> T.List[DependencyMethods]: - method = T.cast('T.Union[DependencyMethods, str]', kwargs.get('method', 'auto')) - if isinstance(method, DependencyMethods): - return [method] - # TODO: try/except? - if method not in [e.value for e in DependencyMethods]: - raise DependencyException(f'method {method!r} is invalid') - method = DependencyMethods(method) - - # Raise FeatureNew where appropriate - if method is DependencyMethods.CONFIG_TOOL: - # FIXME: needs to get a handle on the subproject - # FeatureNew.single_use('Configuration method "config-tool"', '0.44.0') - pass - # This sets per-tool config methods which are deprecated to to the new - # generic CONFIG_TOOL value. - if method in [DependencyMethods.SDLCONFIG, DependencyMethods.CUPSCONFIG, - DependencyMethods.PCAPCONFIG, DependencyMethods.LIBWMFCONFIG]: - # FIXME: needs to get a handle on the subproject - #FeatureDeprecated.single_use(f'Configuration method {method.value}', '0.44', 'Use "config-tool" instead.') - method = DependencyMethods.CONFIG_TOOL - if method is DependencyMethods.QMAKE: - # FIXME: needs to get a handle on the subproject - # FeatureDeprecated.single_use('Configuration method "qmake"', '0.58', 'Use "config-tool" instead.') - method = DependencyMethods.CONFIG_TOOL + method = kwargs.get('method', DependencyMethods.AUTO) # Set the detection method. If the method is set to auto, use any available method. # If method is set to a specific string, allow only that detection method. diff --git a/mesonbuild/dependencies/detect.py b/mesonbuild/dependencies/detect.py index 92ee0c137..db5afeb82 100644 --- a/mesonbuild/dependencies/detect.py +++ b/mesonbuild/dependencies/detect.py @@ -4,6 +4,7 @@ from __future__ import annotations import collections, functools, importlib +import enum import typing as T from .base import ExternalDependency, DependencyException, DependencyMethods, NotFoundDependency @@ -66,6 +67,9 @@ def get_dep_identifier(name: str, kwargs: DependencyObjectKWs) -> 'TV_DepID': for i in value: assert isinstance(i, str), i value = tuple(frozenset(listify(value))) + elif isinstance(value, enum.Enum): + value = value.value + assert isinstance(value, str), 'for mypy' else: assert value is None or isinstance(value, (str, bool, int)), value identifier = (*identifier, (key, value),) @@ -90,8 +94,6 @@ def find_external_dependency(name: str, env: 'Environment', kwargs: DependencyOb required = kwargs.get('required', True) if not isinstance(required, bool): raise DependencyException('Keyword "required" must be a boolean.') - if not isinstance(kwargs.get('method', ''), str): - raise DependencyException('Keyword "method" must be a string.') lname = name.lower() if lname not in _packages_accept_language and kwargs.get('language') is not None: raise DependencyException(f'{name} dependency does not accept "language" keyword argument') @@ -175,10 +177,6 @@ def find_external_dependency(name: str, env: 'Environment', kwargs: DependencyOb def _build_external_dependency_list(name: str, env: 'Environment', for_machine: MachineChoice, kwargs: DependencyObjectKWs) -> T.List['DependencyGenerator']: - # First check if the method is valid - if 'method' in kwargs and kwargs['method'] not in [e.value for e in DependencyMethods]: # type: ignore[typeddict-item] - raise DependencyException('method {!r} is invalid'.format(kwargs['method'])) # type: ignore[typeddict-item] - # Is there a specific dependency detector for this dependency? lname = name.lower() if lname in packages: @@ -197,25 +195,26 @@ def _build_external_dependency_list(name: str, env: 'Environment', for_machine: candidates: T.List['DependencyGenerator'] = [] - if kwargs.get('method', 'auto') == 'auto': + method = kwargs.get('method', DependencyMethods.AUTO) + if method is DependencyMethods.AUTO: # Just use the standard detection methods. - methods = ['pkg-config', 'extraframework', 'cmake'] + methods = [DependencyMethods.PKGCONFIG, DependencyMethods.EXTRAFRAMEWORK, DependencyMethods.CMAKE] else: # If it's explicitly requested, use that detection method (only). - methods = [kwargs['method']] # type: ignore[typeddict-item] + methods = [method] # Exclusive to when it is explicitly requested - if 'dub' in methods: + if DependencyMethods.DUB in methods: from .dub import DubDependency candidates.append(functools.partial(DubDependency, name, env, kwargs)) # Preferred first candidate for auto. - if 'pkg-config' in methods: + if DependencyMethods.PKGCONFIG in methods: from .pkgconfig import PkgConfigDependency candidates.append(functools.partial(PkgConfigDependency, name, env, kwargs)) # On OSX only, try framework dependency detector. - if 'extraframework' in methods: + if DependencyMethods.EXTRAFRAMEWORK in methods: if env.machines[for_machine].is_darwin(): from .framework import ExtraFrameworkDependency candidates.append(functools.partial(ExtraFrameworkDependency, name, env, kwargs)) @@ -223,7 +222,7 @@ def _build_external_dependency_list(name: str, env: 'Environment', for_machine: # Only use CMake: # - if it's explicitly requested # - as a last resort, since it might not work 100% (see #6113) - if 'cmake' in methods: + if DependencyMethods.CMAKE in methods: from .cmake import CMakeDependency candidates.append(functools.partial(CMakeDependency, name, env, kwargs)) diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 2b1871311..68d04326d 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -458,7 +458,7 @@ class OpensslSystemDependency(SystemDependency): super().__init__(name, env, kwargs) dependency_kwargs: DependencyObjectKWs = { - 'method': 'system', + 'method': DependencyMethods.SYSTEM, 'static': self.static, } # type: ignore[typeddict-unknown-key] if not self.clib_compiler.has_header('openssl/ssl.h', '', env)[0]: diff --git a/mesonbuild/dependencies/qt.py b/mesonbuild/dependencies/qt.py index 86f6faff3..9187b2d6c 100644 --- a/mesonbuild/dependencies/qt.py +++ b/mesonbuild/dependencies/qt.py @@ -355,7 +355,7 @@ class QmakeQtDependency(_QtBase, ConfigToolDependency, metaclass=abc.ABCMeta): # ExtraFrameworkDependency doesn't support any methods fw_kwargs = kwargs.copy() - fw_kwargs.pop('method', None) # type: ignore[typeddict-item] + fw_kwargs.pop('method') fw_kwargs['paths'] = [libdir] # type: ignore[typeddict-unknown-key] for m in modules: diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index c58824206..8d349a4ac 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -1790,7 +1790,6 @@ class Interpreter(InterpreterBase, HoldableObject): # When adding kwargs, please check if they make sense in dependencies.get_dep_identifier() @FeatureNewKwargs('dependency', '0.50.0', ['not_found_message']) @FeatureNewKwargs('dependency', '0.49.0', ['disabler']) - @FeatureNewKwargs('dependency', '0.40.0', ['method']) @disablerIfNotFound @permittedKwargs(permitted_dependency_kwargs) @typed_pos_args('dependency', varargs=str, min_varargs=1) diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py index 5cd26a393..8db7d1a89 100644 --- a/mesonbuild/interpreter/kwargs.py +++ b/mesonbuild/interpreter/kwargs.py @@ -12,7 +12,7 @@ from typing_extensions import TypedDict, Literal, Protocol, NotRequired from .. import build from .. import options from ..compilers import Compiler -from ..dependencies.base import Dependency, IncludeType +from ..dependencies.base import Dependency, DependencyMethods, IncludeType from ..mesonlib import EnvironmentVariables, MachineChoice, File, FileMode, FileOrString from ..options import OptionKey from ..modules.cmake import CMakeSubprojectOptions @@ -503,3 +503,4 @@ class FuncDependency(TypedDict): include_type: IncludeType language: T.Optional[str] main: bool + method: DependencyMethods diff --git a/mesonbuild/interpreter/type_checking.py b/mesonbuild/interpreter/type_checking.py index 0f10a14a8..b50911369 100644 --- a/mesonbuild/interpreter/type_checking.py +++ b/mesonbuild/interpreter/type_checking.py @@ -12,7 +12,7 @@ from ..build import (CustomTarget, BuildTarget, CustomTargetIndex, ExtractedObjects, GeneratedList, IncludeDirs, BothLibraries, SharedLibrary, StaticLibrary, Jar, Executable, StructuredSources) from ..options import OptionKey, UserFeatureOption -from ..dependencies import Dependency, InternalDependency +from ..dependencies import Dependency, DependencyMethods, InternalDependency from ..interpreterbase.decorators import KwargInfo, ContainerTypeInfo, FeatureBroken from ..mesonlib import (File, FileMode, MachineChoice, has_path_sep, listify, stringlistify, EnvironmentVariables) @@ -903,8 +903,38 @@ INCLUDE_TYPE = KwargInfo( validator=in_set_validator({'system', 'non-system', 'preserve'}) ) + +_DEPRECATED_DEPENDENCY_METHODS = frozenset( + {'sdlconfig', 'cups-config', 'pcap-config', 'libwmf-config', 'qmake'}) + + +def _dependency_method_convertor(value: str) -> DependencyMethods: + if value in _DEPRECATED_DEPENDENCY_METHODS: + return DependencyMethods.CONFIG_TOOL + return DependencyMethods(value) + + +DEPENDENCY_METHOD_KW = KwargInfo( + 'method', + str, + default='auto', + since='0.40.0', + validator=in_set_validator( + {m.value for m in DependencyMethods} | _DEPRECATED_DEPENDENCY_METHODS), + convertor=_dependency_method_convertor, + deprecated_values={ + 'sdlconfig': ('0.44.0', 'use config-tool instead'), + 'cups-config': ('0.44.0', 'use config-tool instead'), + 'pcap-config': ('0.44.0', 'use config-tool instead'), + 'libwmf-config': ('0.44.0', 'use config-tool instead'), + 'qmake': ('0.58.0', 'use config-tool instead'), + }, +) + + DEPENDENCY_KWS: T.List[KwargInfo] = [ DEFAULT_OPTIONS.evolve(since='0.38.0'), + DEPENDENCY_METHOD_KW, INCLUDE_TYPE, KwargInfo('allow_fallback', (bool, NoneType), since='0.56.0'), KwargInfo('cmake_args', ContainerTypeInfo(list, str), listify=True, default=[], since='0.50.0'), diff --git a/mesonbuild/modules/_qt.py b/mesonbuild/modules/_qt.py index e28033281..143fbfcdf 100644 --- a/mesonbuild/modules/_qt.py +++ b/mesonbuild/modules/_qt.py @@ -14,10 +14,10 @@ from . import ModuleReturnValue, ExtensionModule from .. import build from .. import options from .. import mlog -from ..dependencies import find_external_dependency, Dependency, ExternalLibrary, InternalDependency +from ..dependencies import DependencyMethods, find_external_dependency, Dependency, ExternalLibrary, InternalDependency from ..mesonlib import MesonException, File, FileMode, version_compare, Popen_safe from ..interpreter import extract_required_kwarg -from ..interpreter.type_checking import INSTALL_DIR_KW, INSTALL_KW, NoneType +from ..interpreter.type_checking import DEPENDENCY_METHOD_KW, INSTALL_DIR_KW, INSTALL_KW, NoneType from ..interpreterbase import ContainerTypeInfo, FeatureDeprecated, KwargInfo, noPosargs, FeatureNew, typed_kwargs, typed_pos_args from ..programs import NonExistingExternalProgram @@ -42,7 +42,7 @@ if T.TYPE_CHECKING: name: T.Optional[str] sources: T.Sequence[T.Union[FileOrString, build.GeneratedTypes]] extra_args: T.List[str] - method: str + method: DependencyMethods class UICompilerKwArgs(TypedDict): @@ -50,7 +50,7 @@ if T.TYPE_CHECKING: sources: T.Sequence[T.Union[FileOrString, build.GeneratedTypes]] extra_args: T.List[str] - method: str + method: DependencyMethods preserve_paths: bool class MocCompilerKwArgs(TypedDict): @@ -60,7 +60,7 @@ if T.TYPE_CHECKING: sources: T.Sequence[T.Union[FileOrString, build.GeneratedTypes]] headers: T.Sequence[T.Union[FileOrString, build.GeneratedTypes]] extra_args: T.List[str] - method: str + method: DependencyMethods include_directories: T.List[T.Union[str, build.IncludeDirs]] dependencies: T.List[T.Union[Dependency, ExternalLibrary]] preserve_paths: bool @@ -79,12 +79,12 @@ if T.TYPE_CHECKING: moc_output_json: bool include_directories: T.List[T.Union[str, build.IncludeDirs]] dependencies: T.List[T.Union[Dependency, ExternalLibrary]] - method: str + method: DependencyMethods preserve_paths: bool class HasToolKwArgs(kwargs.ExtractRequired): - method: str + method: DependencyMethods tools: T.List[Literal['moc', 'uic', 'rcc', 'lrelease', 'qmlcachegen', 'qmltyperegistrar']] class CompileTranslationsKwArgs(TypedDict): @@ -92,7 +92,7 @@ if T.TYPE_CHECKING: build_by_default: bool install: bool install_dir: T.Optional[str] - method: str + method: DependencyMethods qresource: T.Optional[str] rcc_extra_arguments: T.List[str] ts_files: T.List[T.Union[str, File, build.GeneratedTypes]] @@ -127,7 +127,7 @@ if T.TYPE_CHECKING: qml_qrc: T.Union[FileOrString, build.GeneratedTypes] extra_args: T.List[str] module_prefix: str - method: str + method: DependencyMethods class GenQmlTypeRegistrarKwArgs(TypedDict): @@ -140,7 +140,7 @@ if T.TYPE_CHECKING: generate_qmltype: bool collected_json: T.Optional[T.Union[FileOrString, build.CustomTarget]] extra_args: T.List[str] - method: str + method: DependencyMethods install: bool install_dir: T.Optional[str] @@ -148,7 +148,7 @@ if T.TYPE_CHECKING: target_name: str moc_json: T.Sequence[build.GeneratedList] - method: str + method: DependencyMethods class QmlModuleKwArgs(TypedDict): @@ -174,7 +174,7 @@ if T.TYPE_CHECKING: generate_qmltype: bool cachegen: bool dependencies: T.List[T.Union[Dependency, ExternalLibrary]] - method: str + method: DependencyMethods preserve_paths: bool install_dir: str install: bool @@ -265,7 +265,7 @@ class QtBaseModule(ExtensionModule): if p.found(): self.tools[name] = p - def _detect_tools(self, state: ModuleState, method: str, required: bool = True) -> None: + def _detect_tools(self, state: ModuleState, method: DependencyMethods, required: bool = True) -> None: if self._tools_detected: return self._tools_detected = True @@ -366,15 +366,15 @@ class QtBaseModule(ExtensionModule): @noPosargs @typed_kwargs( 'qt.has_tools', + DEPENDENCY_METHOD_KW, KwargInfo('required', (bool, options.UserFeatureOption), default=False), - KwargInfo('method', str, default='auto'), KwargInfo('tools', ContainerTypeInfo(list, str), listify=True, default=['moc', 'uic', 'rcc', 'lrelease'], validator=_list_in_set_validator(_set_of_qt_tools), since='1.6.0'), ) def has_tools(self, state: ModuleState, args: T.Tuple, kwargs: HasToolKwArgs) -> bool: - method = kwargs.get('method', 'auto') + method = kwargs['method'] # We have to cast here because TypedDicts are invariant, even though # ExtractRequiredKwArgs is a subset of HasToolKwArgs, type checkers # will insist this is wrong @@ -395,6 +395,7 @@ class QtBaseModule(ExtensionModule): @noPosargs @typed_kwargs( 'qt.compile_resources', + DEPENDENCY_METHOD_KW, KwargInfo('name', (str, NoneType)), KwargInfo( 'sources', @@ -403,7 +404,6 @@ class QtBaseModule(ExtensionModule): required=True, ), KwargInfo('extra_args', ContainerTypeInfo(list, str), listify=True, default=[]), - KwargInfo('method', str, default='auto') ) def compile_resources(self, state: 'ModuleState', args: T.Tuple, kwargs: 'ResourceCompilerKwArgs') -> ModuleReturnValue: """Compile Qt resources files. @@ -487,6 +487,7 @@ class QtBaseModule(ExtensionModule): @noPosargs @typed_kwargs( 'qt.compile_ui', + DEPENDENCY_METHOD_KW, KwargInfo( 'sources', ContainerTypeInfo(list, (File, str, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList), allow_empty=False), @@ -494,7 +495,6 @@ class QtBaseModule(ExtensionModule): required=True, ), KwargInfo('extra_args', ContainerTypeInfo(list, str), listify=True, default=[]), - KwargInfo('method', str, default='auto'), KwargInfo('preserve_paths', bool, default=False, since='1.4.0'), ) def compile_ui(self, state: ModuleState, args: T.Tuple, kwargs: UICompilerKwArgs) -> ModuleReturnValue: @@ -526,6 +526,7 @@ class QtBaseModule(ExtensionModule): @noPosargs @typed_kwargs( 'qt.compile_moc', + DEPENDENCY_METHOD_KW, KwargInfo( 'sources', ContainerTypeInfo(list, (File, str, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList)), @@ -539,7 +540,6 @@ class QtBaseModule(ExtensionModule): default=[] ), KwargInfo('extra_args', ContainerTypeInfo(list, str), listify=True, default=[]), - KwargInfo('method', str, default='auto'), KwargInfo('include_directories', ContainerTypeInfo(list, (build.IncludeDirs, str)), listify=True, default=[]), KwargInfo('dependencies', ContainerTypeInfo(list, (Dependency, ExternalLibrary)), listify=True, default=[]), KwargInfo('preserve_paths', bool, default=False, since='1.4.0'), @@ -612,6 +612,7 @@ class QtBaseModule(ExtensionModule): # We can't use typed_pos_args here, the signature is ambiguous @typed_kwargs( 'qt.preprocess', + DEPENDENCY_METHOD_KW, KwargInfo('sources', ContainerTypeInfo(list, (File, str)), listify=True, default=[], deprecated='0.59.0'), KwargInfo('qresources', ContainerTypeInfo(list, (File, str)), listify=True, default=[]), KwargInfo('ui_files', ContainerTypeInfo(list, (File, str, build.CustomTarget)), listify=True, default=[]), @@ -620,7 +621,6 @@ class QtBaseModule(ExtensionModule): KwargInfo('moc_extra_arguments', ContainerTypeInfo(list, str), listify=True, default=[], since='0.44.0'), KwargInfo('rcc_extra_arguments', ContainerTypeInfo(list, str), listify=True, default=[], since='0.49.0'), KwargInfo('uic_extra_arguments', ContainerTypeInfo(list, str), listify=True, default=[], since='0.49.0'), - KwargInfo('method', str, default='auto'), KwargInfo('include_directories', ContainerTypeInfo(list, (build.IncludeDirs, str)), listify=True, default=[]), KwargInfo('dependencies', ContainerTypeInfo(list, (Dependency, ExternalLibrary)), listify=True, default=[]), KwargInfo('preserve_paths', bool, default=False, since='1.4.0'), @@ -677,9 +677,9 @@ class QtBaseModule(ExtensionModule): @typed_kwargs( 'qt.compile_translations', KwargInfo('build_by_default', bool, default=False), + DEPENDENCY_METHOD_KW, INSTALL_KW, INSTALL_DIR_KW, - KwargInfo('method', str, default='auto'), KwargInfo('qresource', (str, NoneType), since='0.56.0'), KwargInfo('rcc_extra_arguments', ContainerTypeInfo(list, str), listify=True, default=[], since='0.56.0'), KwargInfo('ts_files', ContainerTypeInfo(list, (str, File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList)), listify=True, default=[]), @@ -1019,7 +1019,7 @@ class QtBaseModule(ExtensionModule): KwargInfo('dependencies', ContainerTypeInfo(list, (Dependency, ExternalLibrary)), listify=True, default=[]), INSTALL_DIR_KW, INSTALL_KW, - KwargInfo('method', str, default='auto'), + DEPENDENCY_METHOD_KW, KwargInfo('preserve_paths', bool, default=False), ) def qml_module(self, state: ModuleState, args: T.Tuple[str], kwargs: QmlModuleKwArgs) -> ModuleReturnValue: diff --git a/unittests/failuretests.py b/unittests/failuretests.py index 26f72e4af..360b0e774 100644 --- a/unittests/failuretests.py +++ b/unittests/failuretests.py @@ -147,11 +147,11 @@ class FailureTests(BasePlatformTests): def test_dependency(self): if subprocess.call(['pkg-config', '--exists', 'zlib']) != 0: raise unittest.SkipTest('zlib not found with pkg-config') - a = (("dependency('zlib', method : 'fail')", "'fail' is invalid"), + a = (("dependency('zlib', method : 'fail')", 'dependency keyword argument "method" must be one of auto, builtin, cmake, config-tool, cups-config, dub, extraframework, libwmf-config, pcap-config, pkg-config, qmake, sdlconfig, sysconfig, system, not fail'), ("dependency('zlib', static : '1')", "[Ss]tatic.*boolean"), ("dependency('zlib', version : 1)", "Item must be a list or one of <class 'str'>"), ("dependency('zlib', required : 1)", "[Rr]equired.*boolean"), - ("dependency('zlib', method : 1)", "[Mm]ethod.*string"), + ("dependency('zlib', method : 1)", "dependency keyword argument 'method' was of type int but should have been str"), ("dependency('zlibfail')", self.dnf),) for contents, match in a: self.assertMesonRaises(contents, match) |
