summaryrefslogtreecommitdiff
path: root/mesonbuild/dependencies
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2025-08-01 15:40:44 -0700
committerDylan Baker <dylan@pnwbakers.com>2025-10-20 15:15:53 -0700
commit035b8e4c013d686da7ab433b643338f696e15500 (patch)
treebf3fc4dcbf4e7e2f3014dfcdbf95efc7fcb34039 /mesonbuild/dependencies
parentae89ca1015fd1d8306bbb78c31f1bde53375a712 (diff)
downloadmeson-035b8e4c013d686da7ab433b643338f696e15500.tar.gz
dependency: Use a TypedDict to describe the keyword arguments to Dependency
This allows us to check that all of the keyword arguments are of the correct type.
Diffstat (limited to 'mesonbuild/dependencies')
-rw-r--r--mesonbuild/dependencies/base.py46
-rw-r--r--mesonbuild/dependencies/boost.py7
-rw-r--r--mesonbuild/dependencies/cmake.py17
-rw-r--r--mesonbuild/dependencies/coarrays.py11
-rw-r--r--mesonbuild/dependencies/configtool.py8
-rw-r--r--mesonbuild/dependencies/cuda.py7
-rw-r--r--mesonbuild/dependencies/detect.py15
-rw-r--r--mesonbuild/dependencies/dev.py34
-rw-r--r--mesonbuild/dependencies/dub.py7
-rw-r--r--mesonbuild/dependencies/factory.py18
-rw-r--r--mesonbuild/dependencies/framework.py3
-rw-r--r--mesonbuild/dependencies/hdf5.py11
-rw-r--r--mesonbuild/dependencies/misc.py63
-rw-r--r--mesonbuild/dependencies/mpi.py13
-rw-r--r--mesonbuild/dependencies/pkgconfig.py3
-rw-r--r--mesonbuild/dependencies/platform.py5
-rw-r--r--mesonbuild/dependencies/python.py23
-rw-r--r--mesonbuild/dependencies/qt.py23
-rw-r--r--mesonbuild/dependencies/scalapack.py5
-rw-r--r--mesonbuild/dependencies/ui.py17
20 files changed, 183 insertions, 153 deletions
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 01175291e..b8db1c5ed 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -21,6 +21,8 @@ from ..options import OptionKey
#from ..interpreterbase import FeatureDeprecated, FeatureNew
if T.TYPE_CHECKING:
+ from typing_extensions import TypedDict
+
from ..compilers.compilers import Compiler
from ..environment import Environment
from ..interpreterbase import FeatureCheckBase
@@ -30,6 +32,16 @@ if T.TYPE_CHECKING:
)
from ..interpreter.type_checking import PkgConfigDefineType
+ class DependencyObjectKWs(TypedDict, total=False):
+
+ """Keyword arguments that the Dependency IR object accepts.
+
+ This is different than the arguments as taken by the Interpreter, since
+ it is expected to be clean.
+ """
+
+ cmake_args: T.List[str]
+
_MissingCompilerBase = Compiler
else:
_MissingCompilerBase = object
@@ -98,16 +110,16 @@ DependencyTypeName = T.NewType('DependencyTypeName', str)
class Dependency(HoldableObject):
@classmethod
- def _process_include_type_kw(cls, kwargs: T.Dict[str, T.Any]) -> str:
+ def _process_include_type_kw(cls, kwargs: DependencyObjectKWs) -> str:
if 'include_type' not in kwargs:
return 'preserve'
- if not isinstance(kwargs['include_type'], str):
+ if not isinstance(kwargs['include_type'], str): # type: ignore[typeddict-item]
raise DependencyException('The include_type kwarg must be a string type')
- if kwargs['include_type'] not in ['preserve', 'system', 'non-system']:
+ if kwargs['include_type'] not in ['preserve', 'system', 'non-system']: # type: ignore[typeddict-item]
raise DependencyException("include_type may only be one of ['preserve', 'system', 'non-system']")
- return kwargs['include_type']
+ return kwargs['include_type'] # type: ignore[typeddict-item]
- def __init__(self, type_name: DependencyTypeName, kwargs: T.Dict[str, T.Any]) -> None:
+ def __init__(self, type_name: DependencyTypeName, kwargs: DependencyObjectKWs) -> None:
# This allows two Dependencies to be compared even after being copied.
# The purpose is to allow the name to be changed, but still have a proper comparison
self._id = uuid.uuid4().int
@@ -264,7 +276,7 @@ class Dependency(HoldableObject):
def generate_system_dependency(self, include_type: str) -> 'Dependency':
new_dep = copy.deepcopy(self)
- new_dep.include_type = self._process_include_type_kw({'include_type': include_type})
+ new_dep.include_type = self._process_include_type_kw({'include_type': include_type}) # type: ignore[typeddict-unknown-key]
return new_dep
def get_as_static(self, recursive: bool) -> Dependency:
@@ -390,14 +402,14 @@ class InternalDependency(Dependency):
return new_dep
class HasNativeKwarg:
- def __init__(self, kwargs: T.Dict[str, T.Any]):
+ def __init__(self, kwargs: DependencyObjectKWs):
self.for_machine = self.get_for_machine_from_kwargs(kwargs)
- def get_for_machine_from_kwargs(self, kwargs: T.Dict[str, T.Any]) -> MachineChoice:
+ def get_for_machine_from_kwargs(self, kwargs: DependencyObjectKWs) -> MachineChoice:
return MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST
class ExternalDependency(Dependency, HasNativeKwarg):
- def __init__(self, type_name: DependencyTypeName, environment: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None):
+ def __init__(self, type_name: DependencyTypeName, environment: 'Environment', kwargs: DependencyObjectKWs, language: T.Optional[str] = None):
Dependency.__init__(self, type_name, kwargs)
self.env = environment
self.name = type_name # default
@@ -406,10 +418,10 @@ class ExternalDependency(Dependency, HasNativeKwarg):
version_reqs = kwargs.get('version', None)
if isinstance(version_reqs, str):
version_reqs = [version_reqs]
- self.version_reqs: T.Optional[T.List[str]] = version_reqs
- self.required = kwargs.get('required', True)
- self.silent = kwargs.get('silent', False)
- self.static = kwargs.get('static', self.env.coredata.optstore.get_value_for(OptionKey('prefer_static')))
+ self.version_reqs = T.cast('T.Optional[T.List[str]]', version_reqs)
+ self.required = T.cast('bool', kwargs.get('required', True))
+ self.silent = T.cast('bool', kwargs.get('silent', False))
+ self.static = T.cast('bool', kwargs.get('static', self.env.coredata.optstore.get_value_for(OptionKey('prefer_static'))))
self.libtype = LibType.STATIC if self.static else LibType.PREFER_SHARED
if not isinstance(self.static, bool):
raise DependencyException('Static keyword must be boolean')
@@ -603,8 +615,8 @@ def strip_system_includedirs(environment: 'Environment', for_machine: MachineCho
exclude = {f'-I{p}' for p in environment.get_compiler_system_include_dirs(for_machine)}
return [i for i in include_args if i not in exclude]
-def process_method_kw(possible: T.Iterable[DependencyMethods], kwargs: T.Dict[str, T.Any]) -> T.List[DependencyMethods]:
- method: T.Union[DependencyMethods, str] = kwargs.get('method', 'auto')
+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?
@@ -670,7 +682,7 @@ class SystemDependency(ExternalDependency):
"""Dependency base for System type dependencies."""
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any],
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs,
language: T.Optional[str] = None) -> None:
super().__init__(DependencyTypeName('system'), env, kwargs, language=language)
self.name = name
@@ -684,7 +696,7 @@ class BuiltinDependency(ExternalDependency):
"""Dependency base for Builtin type dependencies."""
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any],
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs,
language: T.Optional[str] = None) -> None:
super().__init__(DependencyTypeName('builtin'), env, kwargs, language=language)
self.name = name
diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py
index 82a232f3d..733d28896 100644
--- a/mesonbuild/dependencies/boost.py
+++ b/mesonbuild/dependencies/boost.py
@@ -21,6 +21,7 @@ from .misc import threads_factory
if T.TYPE_CHECKING:
from ..envconfig import Properties
from ..environment import Environment
+ from .base import DependencyObjectKWs
# On windows 3 directory layouts are supported:
# * The default layout (versioned) installed:
@@ -339,7 +340,7 @@ class BoostLibraryFile():
return [self.path.as_posix()]
class BoostDependency(SystemDependency):
- def __init__(self, environment: Environment, kwargs: T.Dict[str, T.Any]) -> None:
+ def __init__(self, environment: Environment, kwargs: DependencyObjectKWs) -> None:
super().__init__('boost', environment, kwargs, language='cpp')
buildtype = environment.coredata.optstore.get_value_for(OptionKey('buildtype'))
assert isinstance(buildtype, str)
@@ -350,7 +351,7 @@ class BoostDependency(SystemDependency):
self.explicit_static = 'static' in kwargs
# Extract and validate modules
- self.modules: T.List[str] = mesonlib.extract_as_list(kwargs, 'modules')
+ self.modules: T.List[str] = mesonlib.extract_as_list(kwargs, 'modules') # type: ignore[arg-type]
for i in self.modules:
if not isinstance(i, str):
raise DependencyException('Boost module argument is not a string.')
@@ -677,7 +678,7 @@ class BoostDependency(SystemDependency):
# Try getting the BOOST_ROOT from a boost.pc if it exists. This primarily
# allows BoostDependency to find boost from Conan. See #5438
try:
- boost_pc = PkgConfigDependency('boost', self.env, {'required': False})
+ boost_pc = PkgConfigDependency('boost', self.env, {'required': False}) # type: ignore[typeddict-unknown-key]
if boost_pc.found():
boost_lib_dir = boost_pc.get_variable(pkgconfig='libdir')
boost_inc_dir = boost_pc.get_variable(pkgconfig='includedir')
diff --git a/mesonbuild/dependencies/cmake.py b/mesonbuild/dependencies/cmake.py
index 4e449816d..c995fc79c 100644
--- a/mesonbuild/dependencies/cmake.py
+++ b/mesonbuild/dependencies/cmake.py
@@ -21,6 +21,7 @@ if T.TYPE_CHECKING:
from ..environment import Environment
from ..envconfig import MachineInfo
from ..interpreter.type_checking import PkgConfigDefineType
+ from .base import DependencyObjectKWs
class CMakeInfo(T.NamedTuple):
module_paths: T.List[str]
@@ -69,7 +70,7 @@ class CMakeDependency(ExternalDependency):
# one module
return module
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None, force_use_global_compilers: bool = False) -> None:
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs, language: T.Optional[str] = None, force_use_global_compilers: bool = False) -> None:
# Gather a list of all languages to support
self.language_list: T.List[str] = []
if language is None or force_use_global_compilers:
@@ -116,7 +117,7 @@ class CMakeDependency(ExternalDependency):
# Setup the trace parser
self.traceparser = CMakeTraceParser(self.cmakebin.version(), self._get_build_dir(), self.env)
- cm_args = stringlistify(extract_as_list(kwargs, 'cmake_args'))
+ cm_args = stringlistify(extract_as_list(kwargs, 'cmake_args')) # type: ignore[arg-type]
cm_args = check_cmake_args(cm_args)
if CMakeDependency.class_cmakeinfo[self.for_machine] is None:
CMakeDependency.class_cmakeinfo[self.for_machine] = self._get_cmake_info(cm_args)
@@ -128,10 +129,10 @@ class CMakeDependency(ExternalDependency):
package_version = kwargs.get('cmake_package_version', '')
if not isinstance(package_version, str):
raise DependencyException('Keyword "cmake_package_version" must be a string.')
- components = [(x, True) for x in stringlistify(extract_as_list(kwargs, 'components'))]
- modules = [(x, True) for x in stringlistify(extract_as_list(kwargs, 'modules'))]
- modules += [(x, False) for x in stringlistify(extract_as_list(kwargs, 'optional_modules'))]
- cm_path = stringlistify(extract_as_list(kwargs, 'cmake_module_path'))
+ components = [(x, True) for x in stringlistify(extract_as_list(kwargs, 'components'))] # type: ignore[arg-type]
+ modules = [(x, True) for x in stringlistify(extract_as_list(kwargs, 'modules'))] # type: ignore[arg-type]
+ modules += [(x, False) for x in stringlistify(extract_as_list(kwargs, 'optional_modules'))] # type: ignore[arg-type]
+ cm_path = stringlistify(extract_as_list(kwargs, 'cmake_module_path')) # type: ignore[arg-type]
cm_path = [x if os.path.isabs(x) else os.path.join(environment.get_source_dir(), x) for x in cm_path]
if cm_path:
cm_args.append('-DCMAKE_MODULE_PATH=' + ';'.join(cm_path))
@@ -655,9 +656,9 @@ class CMakeDependencyFactory:
self.name = name
self.modules = modules
- def __call__(self, name: str, env: Environment, kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None, force_use_global_compilers: bool = False) -> CMakeDependency:
+ def __call__(self, name: str, env: Environment, kwargs: DependencyObjectKWs, language: T.Optional[str] = None, force_use_global_compilers: bool = False) -> CMakeDependency:
if self.modules:
- kwargs['modules'] = self.modules
+ kwargs['modules'] = self.modules # type: ignore[typeddict-unknown-key]
return CMakeDependency(self.name or name, env, kwargs, language, force_use_global_compilers)
@staticmethod
diff --git a/mesonbuild/dependencies/coarrays.py b/mesonbuild/dependencies/coarrays.py
index 7701c06ec..07da33cc6 100644
--- a/mesonbuild/dependencies/coarrays.py
+++ b/mesonbuild/dependencies/coarrays.py
@@ -16,12 +16,13 @@ if T.TYPE_CHECKING:
from . factory import DependencyGenerator
from ..environment import Environment
from ..mesonlib import MachineChoice
+ from .base import DependencyObjectKWs
@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE, DependencyMethods.SYSTEM})
def coarray_factory(env: 'Environment',
for_machine: 'MachineChoice',
- kwargs: T.Dict[str, T.Any],
+ kwargs: DependencyObjectKWs,
methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
fcid = detect_compiler('coarray', env, for_machine, 'fortran').get_id()
candidates: T.List['DependencyGenerator'] = []
@@ -35,7 +36,7 @@ def coarray_factory(env: 'Environment',
if DependencyMethods.CMAKE in methods:
if 'modules' not in kwargs:
- kwargs['modules'] = 'OpenCoarrays::caf_mpi'
+ kwargs['modules'] = 'OpenCoarrays::caf_mpi' # type: ignore[typeddict-unknown-key]
candidates.append(functools.partial(
CMakeDependency, 'OpenCoarrays', env, kwargs, language='fortran'))
@@ -55,10 +56,10 @@ class CoarrayDependency(SystemDependency):
Coarrays may be thought of as a high-level language abstraction of
low-level MPI calls.
"""
- def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
+ def __init__(self, environment: 'Environment', kwargs: DependencyObjectKWs) -> None:
super().__init__('coarray', environment, kwargs, language='fortran')
- kwargs['required'] = False
- kwargs['silent'] = True
+ kwargs['required'] = False # type: ignore[typeddict-unknown-key]
+ kwargs['silent'] = True # type: ignore[typeddict-unknown-key]
cid = self.get_compiler().get_id()
if cid == 'gcc':
diff --git a/mesonbuild/dependencies/configtool.py b/mesonbuild/dependencies/configtool.py
index 476f7ad42..dca9e8c04 100644
--- a/mesonbuild/dependencies/configtool.py
+++ b/mesonbuild/dependencies/configtool.py
@@ -15,6 +15,8 @@ from mesonbuild import mesonlib
if T.TYPE_CHECKING:
from ..environment import Environment
from ..interpreter.type_checking import PkgConfigDefineType
+ from .base import DependencyObjectKWs
+
class ConfigToolDependency(ExternalDependency):
@@ -37,7 +39,7 @@ class ConfigToolDependency(ExternalDependency):
allow_default_for_cross = False
__strip_version = re.compile(r'^[0-9][0-9.]+')
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None, exclude_paths: T.Optional[T.List[str]] = None):
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs, language: T.Optional[str] = None, exclude_paths: T.Optional[T.List[str]] = None):
super().__init__(DependencyTypeName('config-tool'), environment, kwargs, language=language)
self.name = name
# You may want to overwrite the class version in some cases
@@ -45,14 +47,14 @@ class ConfigToolDependency(ExternalDependency):
if not self.tool_name:
self.tool_name = self.tools[0]
if 'version_arg' in kwargs:
- self.version_arg = kwargs['version_arg']
+ self.version_arg = kwargs['version_arg'] # type: ignore[typeddict-item]
req_version_raw = kwargs.get('version', None)
if req_version_raw is not None:
req_version = mesonlib.stringlistify(req_version_raw)
else:
req_version = []
- tool, version = self.find_config(req_version, kwargs.get('returncode_value', 0), exclude_paths=exclude_paths)
+ tool, version = self.find_config(req_version, kwargs.get('returncode_value', 0), exclude_paths=exclude_paths) # type: ignore[arg-type]
self.config = tool
self.is_found = self.report_config(version, req_version)
if not self.is_found:
diff --git a/mesonbuild/dependencies/cuda.py b/mesonbuild/dependencies/cuda.py
index 6fe2f1d03..0bb8ffa6f 100644
--- a/mesonbuild/dependencies/cuda.py
+++ b/mesonbuild/dependencies/cuda.py
@@ -19,6 +19,7 @@ if T.TYPE_CHECKING:
from ..environment import Environment
from ..compilers import Compiler
from ..envconfig import MachineInfo
+ from .base import DependencyObjectKWs
TV_ResultTuple = T.Tuple[T.Optional[str], T.Optional[str], bool]
@@ -27,7 +28,7 @@ class CudaDependency(SystemDependency):
supported_languages = ['cpp', 'c', 'cuda'] # see also _default_language
targets_dir = 'targets' # Directory containing CUDA targets.
- def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
+ def __init__(self, environment: 'Environment', kwargs: DependencyObjectKWs) -> None:
for_machine = self.get_for_machine_from_kwargs(kwargs)
compilers = environment.coredata.compilers[for_machine]
machine = environment.machines[for_machine]
@@ -310,8 +311,8 @@ class CudaDependency(SystemDependency):
def log_info(self) -> str:
return self.cuda_path if self.cuda_path else ''
- def get_requested(self, kwargs: T.Dict[str, T.Any]) -> T.List[str]:
- candidates = mesonlib.extract_as_list(kwargs, 'modules')
+ def get_requested(self, kwargs: DependencyObjectKWs) -> T.List[str]:
+ candidates = mesonlib.extract_as_list(kwargs, 'modules') # type: ignore[arg-type,var-annotated]
for c in candidates:
if not isinstance(c, str):
raise DependencyException('CUDA module argument is not a string.')
diff --git a/mesonbuild/dependencies/detect.py b/mesonbuild/dependencies/detect.py
index 4cdf16de5..6dc0299ca 100644
--- a/mesonbuild/dependencies/detect.py
+++ b/mesonbuild/dependencies/detect.py
@@ -14,6 +14,7 @@ from .. import mlog
if T.TYPE_CHECKING:
from ..environment import Environment
from .factory import DependencyFactory, WrappedFactoryFunc, DependencyGenerator
+ from .base import DependencyObjectKWs
TV_DepIDEntry = T.Union[str, bool, int, None, T.Tuple[str, ...]]
TV_DepID = T.Tuple[T.Tuple[str, TV_DepIDEntry], ...]
@@ -38,10 +39,10 @@ class DependencyPackages(collections.UserDict):
packages = DependencyPackages()
_packages_accept_language: T.Set[str] = set()
-def get_dep_identifier(name: str, kwargs: T.Dict[str, T.Any]) -> 'TV_DepID':
+def get_dep_identifier(name: str, kwargs: DependencyObjectKWs) -> 'TV_DepID':
identifier: 'TV_DepID' = (('name', name), )
from ..interpreter.type_checking import DEPENDENCY_KWS
- nkwargs = {k.name: k.default for k in DEPENDENCY_KWS}
+ nkwargs = T.cast('DependencyObjectKWs', {k.name: k.default for k in DEPENDENCY_KWS})
nkwargs.update(kwargs)
from ..interpreter import permitted_dependency_kwargs
@@ -84,7 +85,7 @@ display_name_map = {
'wxwidgets': 'WxWidgets',
}
-def find_external_dependency(name: str, env: 'Environment', kwargs: T.Dict[str, object], candidates: T.Optional[T.List['DependencyGenerator']] = None) -> T.Union['ExternalDependency', NotFoundDependency]:
+def find_external_dependency(name: str, env: 'Environment', kwargs: DependencyObjectKWs, candidates: T.Optional[T.List['DependencyGenerator']] = None) -> T.Union['ExternalDependency', NotFoundDependency]:
assert name
required = kwargs.get('required', True)
if not isinstance(required, bool):
@@ -173,10 +174,10 @@ def find_external_dependency(name: str, env: 'Environment', kwargs: T.Dict[str,
def _build_external_dependency_list(name: str, env: 'Environment', for_machine: MachineChoice,
- kwargs: T.Dict[str, T.Any]) -> T.List['DependencyGenerator']:
+ 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]:
- raise DependencyException('method {!r} is invalid'.format(kwargs['method']))
+ 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()
@@ -201,7 +202,7 @@ def _build_external_dependency_list(name: str, env: 'Environment', for_machine:
methods = ['pkg-config', 'extraframework', 'cmake']
else:
# If it's explicitly requested, use that detection method (only).
- methods = [kwargs['method']]
+ methods = [kwargs['method']] # type: ignore[typeddict-item]
# Exclusive to when it is explicitly requested
if 'dub' in methods:
diff --git a/mesonbuild/dependencies/dev.py b/mesonbuild/dependencies/dev.py
index 8f0f1baae..2b3931774 100644
--- a/mesonbuild/dependencies/dev.py
+++ b/mesonbuild/dependencies/dev.py
@@ -30,10 +30,10 @@ if T.TYPE_CHECKING:
from ..environment import Environment
from ..compilers import Compiler
from ..mesonlib import MachineChoice
- from typing_extensions import TypedDict
from ..interpreter.type_checking import PkgConfigDefineType
+ from .base import DependencyObjectKWs
- class JNISystemDependencyKW(TypedDict):
+ class JNISystemDependencyKW(DependencyObjectKWs):
modules: T.List[str]
# FIXME: When dependency() moves to typed Kwargs, this should inherit
# from its TypedDict type.
@@ -53,7 +53,7 @@ def get_shared_library_suffix(environment: 'Environment', for_machine: MachineCh
class GTestDependencySystem(SystemDependency):
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs) -> None:
super().__init__(name, environment, kwargs, language='cpp')
self.main = kwargs.get('main', False)
@@ -110,7 +110,7 @@ class GTestDependencySystem(SystemDependency):
class GTestDependencyPC(PkgConfigDependency):
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs):
assert name == 'gtest'
if kwargs.get('main'):
name = 'gtest_main'
@@ -118,7 +118,7 @@ class GTestDependencyPC(PkgConfigDependency):
class GMockDependencySystem(SystemDependency):
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs) -> None:
super().__init__(name, environment, kwargs, language='cpp')
self.main = kwargs.get('main', False)
if not self._add_sub_dependency(threads_factory(environment, self.for_machine, {})):
@@ -129,7 +129,7 @@ class GMockDependencySystem(SystemDependency):
# want to avoid linking in main() from GTest
gtest_kwargs = kwargs.copy()
if self.main:
- gtest_kwargs['main'] = False
+ gtest_kwargs['main'] = False # type: ignore[typeddict-unknown-key]
# GMock without GTest is pretty much useless
# this also mimics the structure given in WrapDB,
@@ -178,7 +178,7 @@ class GMockDependencySystem(SystemDependency):
class GMockDependencyPC(PkgConfigDependency):
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs):
assert name == 'gmock'
if kwargs.get('main'):
name = 'gmock_main'
@@ -193,7 +193,7 @@ class LLVMDependencyConfigTool(ConfigToolDependency):
tool_name = 'llvm-config'
__cpp_blacklist = {'-DNDEBUG'}
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs):
self.tools = get_llvm_tool_names('llvm-config')
# Fedora starting with Fedora 30 adds a suffix of the number
@@ -215,9 +215,9 @@ class LLVMDependencyConfigTool(ConfigToolDependency):
return
self.provided_modules = self.get_config_value(['--components'], 'modules')
- modules = stringlistify(extract_as_list(kwargs, 'modules'))
+ modules = stringlistify(extract_as_list(kwargs, 'modules')) # type: ignore[arg-type]
self.check_components(modules)
- opt_modules = stringlistify(extract_as_list(kwargs, 'optional_modules'))
+ opt_modules = stringlistify(extract_as_list(kwargs, 'optional_modules')) # type: ignore[arg-type]
self.check_components(opt_modules, required=False)
cargs = mesonlib.OrderedSet(self.get_config_value(['--cppflags'], 'compile_args'))
@@ -388,9 +388,9 @@ class LLVMDependencyConfigTool(ConfigToolDependency):
return ''
class LLVMDependencyCMake(CMakeDependency):
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
- self.llvm_modules = stringlistify(extract_as_list(kwargs, 'modules'))
- self.llvm_opt_modules = stringlistify(extract_as_list(kwargs, 'optional_modules'))
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs) -> None:
+ self.llvm_modules = stringlistify(extract_as_list(kwargs, 'modules')) # type: ignore[arg-type]
+ self.llvm_opt_modules = stringlistify(extract_as_list(kwargs, 'optional_modules')) # type: ignore[arg-type]
compilers = None
if kwargs.get('native', False):
@@ -515,7 +515,7 @@ class ValgrindDependency(PkgConfigDependency):
Consumers of Valgrind usually only need the compile args and do not want to
link to its (static) libraries.
'''
- def __init__(self, env: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, env: 'Environment', kwargs: DependencyObjectKWs):
super().__init__('valgrind', env, kwargs)
def get_link_args(self, language: T.Optional[str] = None, raw: bool = False) -> T.List[str]:
@@ -526,7 +526,7 @@ packages['valgrind'] = ValgrindDependency
class ZlibSystemDependency(SystemDependency):
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, environment, kwargs)
from ..compilers.c import AppleClangCCompiler
from ..compilers.cpp import AppleClangCPPCompiler
@@ -564,7 +564,7 @@ class ZlibSystemDependency(SystemDependency):
class JNISystemDependency(SystemDependency):
def __init__(self, environment: 'Environment', kwargs: JNISystemDependencyKW):
- super().__init__('jni', environment, T.cast('T.Dict[str, T.Any]', kwargs))
+ super().__init__('jni', environment, kwargs)
self.feature_since = ('0.62.0', '')
@@ -757,7 +757,7 @@ class DiaSDKSystemDependency(SystemDependency):
defval, _ = compiler.get_define(dname, '', env, [], [])
return defval is not None
- def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
+ def __init__(self, environment: 'Environment', kwargs: DependencyObjectKWs) -> None:
super().__init__('diasdk', environment, kwargs)
self.is_found = False
diff --git a/mesonbuild/dependencies/dub.py b/mesonbuild/dependencies/dub.py
index ac137e399..5cf588e6f 100644
--- a/mesonbuild/dependencies/dub.py
+++ b/mesonbuild/dependencies/dub.py
@@ -19,6 +19,7 @@ if T.TYPE_CHECKING:
from typing_extensions import TypedDict
from ..environment import Environment
+ from .base import DependencyObjectKWs
# Definition of what `dub describe` returns (only the fields used by Meson)
class DubDescription(TypedDict):
@@ -74,7 +75,7 @@ class DubDependency(ExternalDependency):
'llvm': 'ldc',
}
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(DependencyTypeName('dub'), environment, kwargs, language='d')
self.name = name
from ..compilers.d import DCompiler, d_feature_args
@@ -84,7 +85,7 @@ class DubDependency(ExternalDependency):
self.compiler = _temp_comp
if 'required' in kwargs:
- self.required = kwargs.get('required')
+ self.required = T.cast('bool', kwargs.get('required'))
if DubDependency.class_dubbin is None and not DubDependency.class_dubbin_searched:
DubDependency.class_dubbin = self._check_dub()
@@ -303,7 +304,7 @@ class DubDependency(ExternalDependency):
for lib in bs['libs']:
if os.name != 'nt':
# trying to add system libraries by pkg-config
- pkgdep = PkgConfigDependency(lib, environment, {'required': True, 'silent': True})
+ pkgdep = PkgConfigDependency(lib, environment, {'required': True, 'silent': True}) # type: ignore[typeddict-unknown-key]
if pkgdep.is_found:
for arg in pkgdep.get_compile_args():
self.compile_args.append(arg)
diff --git a/mesonbuild/dependencies/factory.py b/mesonbuild/dependencies/factory.py
index aac09cafa..0c4ca8174 100644
--- a/mesonbuild/dependencies/factory.py
+++ b/mesonbuild/dependencies/factory.py
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2013-2021 The Meson development team
-# Copyright © 2021-2023 Intel Corporation
+# Copyright © 2021-2025 Intel Corporation
from __future__ import annotations
@@ -15,7 +15,7 @@ from .framework import ExtraFrameworkDependency
from .pkgconfig import PkgConfigDependency
if T.TYPE_CHECKING:
- from .base import ExternalDependency
+ from .base import DependencyObjectKWs, ExternalDependency
from .configtool import ConfigToolDependency
from ..environment import Environment
from ..mesonlib import MachineChoice
@@ -25,7 +25,7 @@ if T.TYPE_CHECKING:
[
'Environment',
MachineChoice,
- T.Dict[str, T.Any],
+ DependencyObjectKWs,
T.List[DependencyMethods]
],
T.List[DependencyGenerator]
@@ -35,7 +35,7 @@ if T.TYPE_CHECKING:
[
'Environment',
MachineChoice,
- T.Dict[str, T.Any]
+ DependencyObjectKWs,
],
T.List[DependencyGenerator]
]
@@ -68,7 +68,7 @@ class DependencyFactory:
"""
def __init__(self, name: str, methods: T.List[DependencyMethods], *,
- extra_kwargs: T.Optional[T.Dict[str, T.Any]] = None,
+ extra_kwargs: T.Optional[DependencyObjectKWs] = None,
pkgconfig_name: T.Optional[str] = None,
pkgconfig_class: 'T.Type[PkgConfigDependency]' = PkgConfigDependency,
cmake_name: T.Optional[str] = None,
@@ -86,7 +86,7 @@ class DependencyFactory:
self.methods = methods
self.classes: T.Dict[
DependencyMethods,
- T.Callable[['Environment', T.Dict[str, T.Any]], ExternalDependency]
+ T.Callable[['Environment', DependencyObjectKWs], ExternalDependency]
] = {
# Just attach the correct name right now, either the generic name
# or the method specific name.
@@ -116,7 +116,7 @@ class DependencyFactory:
return True
def __call__(self, env: 'Environment', for_machine: MachineChoice,
- kwargs: T.Dict[str, T.Any]) -> T.List['DependencyGenerator']:
+ kwargs: DependencyObjectKWs) -> T.List['DependencyGenerator']:
"""Return a list of Dependencies with the arguments already attached."""
methods = process_method_kw(self.methods, kwargs)
nwargs = self.extra_kwargs.copy()
@@ -131,14 +131,14 @@ def factory_methods(methods: T.Set[DependencyMethods]) -> T.Callable[['FactoryFu
This helps to make factory functions self documenting
>>> @factory_methods([DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE])
- >>> def factory(env: Environment, for_machine: MachineChoice, kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
+ >>> def factory(env: Environment, for_machine: MachineChoice, kwargs: DependencyObjectKWs, methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
>>> pass
"""
def inner(func: 'FactoryFunc') -> 'WrappedFactoryFunc':
@functools.wraps(func)
- def wrapped(env: 'Environment', for_machine: MachineChoice, kwargs: T.Dict[str, T.Any]) -> T.List['DependencyGenerator']:
+ def wrapped(env: 'Environment', for_machine: MachineChoice, kwargs: DependencyObjectKWs) -> T.List['DependencyGenerator']:
return func(env, for_machine, kwargs, process_method_kw(methods, kwargs))
return wrapped
diff --git a/mesonbuild/dependencies/framework.py b/mesonbuild/dependencies/framework.py
index 1fbd62823..6f87964ec 100644
--- a/mesonbuild/dependencies/framework.py
+++ b/mesonbuild/dependencies/framework.py
@@ -11,11 +11,12 @@ import typing as T
if T.TYPE_CHECKING:
from ..environment import Environment
+ from .base import DependencyObjectKWs
class ExtraFrameworkDependency(ExternalDependency):
system_framework_paths: T.Optional[T.List[str]] = None
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None) -> None:
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs, language: T.Optional[str] = None) -> None:
paths = stringlistify(kwargs.get('paths', []))
super().__init__(DependencyTypeName('extraframeworks'), env, kwargs, language=language)
self.name = name
diff --git a/mesonbuild/dependencies/hdf5.py b/mesonbuild/dependencies/hdf5.py
index 7595c7cc6..2bb31807f 100644
--- a/mesonbuild/dependencies/hdf5.py
+++ b/mesonbuild/dependencies/hdf5.py
@@ -21,13 +21,14 @@ if T.TYPE_CHECKING:
from .factory import DependencyGenerator
from ..environment import Environment
from ..mesonlib import MachineChoice
+ from .base import DependencyObjectKWs
class HDF5PkgConfigDependency(PkgConfigDependency):
"""Handle brokenness in the HDF5 pkg-config files."""
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None) -> None:
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs, language: T.Optional[str] = None) -> None:
language = language or 'c'
if language not in {'c', 'cpp', 'fortran'}:
raise DependencyException(f'Language {language} is not supported with HDF5.')
@@ -78,7 +79,7 @@ class HDF5ConfigToolDependency(ConfigToolDependency):
version_arg = '-showconfig'
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None) -> None:
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs, language: T.Optional[str] = None) -> None:
language = language or 'c'
if language not in {'c', 'cpp', 'fortran'}:
raise DependencyException(f'Language {language} is not supported with HDF5.')
@@ -102,7 +103,7 @@ class HDF5ConfigToolDependency(ConfigToolDependency):
for_machine = self.get_for_machine_from_kwargs(kwargs)
nkwargs = kwargs.copy()
- nkwargs['tools'] = tools
+ nkwargs['tools'] = tools # type: ignore[typeddict-unknown-key]
# Override the compiler that the config tools are going to use by
# setting the environment variables that they use for the compiler and
@@ -144,8 +145,8 @@ class HDF5ConfigToolDependency(ConfigToolDependency):
@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL})
def hdf5_factory(env: 'Environment', for_machine: 'MachineChoice',
- kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
- language = kwargs.get('language')
+ kwargs: DependencyObjectKWs, methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
+ language = T.cast('T.Optional[str]', kwargs.get('language'))
candidates: T.List['DependencyGenerator'] = []
if DependencyMethods.PKGCONFIG in methods:
diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py
index 3ab2194e3..9f6746328 100644
--- a/mesonbuild/dependencies/misc.py
+++ b/mesonbuild/dependencies/misc.py
@@ -21,15 +21,16 @@ from ..options import OptionKey
if T.TYPE_CHECKING:
from ..environment import Environment
+ from .base import DependencyObjectKWs
from .factory import DependencyGenerator
@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE})
def netcdf_factory(env: 'Environment',
for_machine: 'mesonlib.MachineChoice',
- kwargs: T.Dict[str, T.Any],
+ kwargs: DependencyObjectKWs,
methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
- language = kwargs.get('language')
+ language = T.cast('T.Optional[str]', kwargs.get('language'))
if language is None:
language = 'c'
if language not in ('c', 'cpp', 'fortran'):
@@ -54,7 +55,7 @@ packages['netcdf'] = netcdf_factory
class AtomicBuiltinDependency(BuiltinDependency):
- def __init__(self, name: str, env: Environment, kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: Environment, kwargs: DependencyObjectKWs):
super().__init__(name, env, kwargs)
self.feature_since = ('1.7.0', "consider checking for `atomic_flag_clear` with and without `find_library('atomic')`")
@@ -63,7 +64,7 @@ class AtomicBuiltinDependency(BuiltinDependency):
class AtomicSystemDependency(SystemDependency):
- def __init__(self, name: str, env: Environment, kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: Environment, kwargs: DependencyObjectKWs):
super().__init__(name, env, kwargs)
self.feature_since = ('1.7.0', "consider checking for `atomic_flag_clear` with and without `find_library('atomic')`")
@@ -75,7 +76,7 @@ class AtomicSystemDependency(SystemDependency):
class DlBuiltinDependency(BuiltinDependency):
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, env, kwargs)
self.feature_since = ('0.62.0', "consider checking for `dlopen` with and without `find_library('dl')`")
@@ -84,7 +85,7 @@ class DlBuiltinDependency(BuiltinDependency):
class DlSystemDependency(SystemDependency):
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, env, kwargs)
self.feature_since = ('0.62.0', "consider checking for `dlopen` with and without `find_library('dl')`")
@@ -111,8 +112,8 @@ class OpenMPDependency(SystemDependency):
'199810': '1.0',
}
- def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
- language = kwargs.get('language')
+ def __init__(self, environment: 'Environment', kwargs: DependencyObjectKWs) -> None:
+ language = T.cast('T.Optional[str]', kwargs.get('language'))
super().__init__('openmp', environment, kwargs, language=language)
self.is_found = False
if self.clib_compiler.get_id() == 'nagfor':
@@ -165,7 +166,7 @@ packages['openmp'] = OpenMPDependency
class ThreadDependency(SystemDependency):
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs) -> None:
super().__init__(name, environment, kwargs)
self.is_found = True
# Happens if you are using a language with threads
@@ -179,7 +180,7 @@ class ThreadDependency(SystemDependency):
class BlocksDependency(SystemDependency):
- def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
+ def __init__(self, environment: 'Environment', kwargs: DependencyObjectKWs) -> None:
super().__init__('blocks', environment, kwargs)
self.name = 'blocks'
self.is_found = False
@@ -222,7 +223,7 @@ class PcapDependencyConfigTool(ConfigToolDependency):
# version 1.10.3 will hopefully add actual support for --version
skip_version = '--help'
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, environment, kwargs)
if not self.is_found:
return
@@ -251,7 +252,7 @@ class CupsDependencyConfigTool(ConfigToolDependency):
tools = ['cups-config']
tool_name = 'cups-config'
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, environment, kwargs)
if not self.is_found:
return
@@ -264,7 +265,7 @@ class LibWmfDependencyConfigTool(ConfigToolDependency):
tools = ['libwmf-config']
tool_name = 'libwmf-config'
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, environment, kwargs)
if not self.is_found:
return
@@ -277,7 +278,7 @@ class LibGCryptDependencyConfigTool(ConfigToolDependency):
tools = ['libgcrypt-config']
tool_name = 'libgcrypt-config'
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, environment, kwargs)
if not self.is_found:
return
@@ -291,7 +292,7 @@ class GpgmeDependencyConfigTool(ConfigToolDependency):
tools = ['gpgme-config']
tool_name = 'gpg-config'
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, environment, kwargs)
if not self.is_found:
return
@@ -302,7 +303,7 @@ class GpgmeDependencyConfigTool(ConfigToolDependency):
class ShadercDependency(SystemDependency):
- def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, environment: 'Environment', kwargs: DependencyObjectKWs):
super().__init__('shaderc', environment, kwargs)
static_lib = 'shaderc_combined'
@@ -334,7 +335,7 @@ class CursesConfigToolDependency(ConfigToolDependency):
# ncurses5.4-config is for macOS Catalina
tools = ['ncursesw6-config', 'ncursesw5-config', 'ncurses6-config', 'ncurses5-config', 'ncurses5.4-config']
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs, language: T.Optional[str] = None):
exclude_paths = None
# macOS mistakenly ships /usr/bin/ncurses5.4-config and a man page for
# it, but none of the headers or libraries. Ignore /usr/bin because it
@@ -358,7 +359,7 @@ class CursesSystemDependency(SystemDependency):
implementations, and the differences between them can be very annoying.
"""
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, env, kwargs)
candidates = [
@@ -389,7 +390,7 @@ class CursesSystemDependency(SystemDependency):
self.version = f'{v_major}.{v_minor}'
# Check the version if possible, emit a warning if we can't
- req = kwargs.get('version')
+ req = T.cast('T.Iterable[str]', kwargs.get('version'))
if req:
if self.version:
self.is_found, *_ = mesonlib.version_compare_many(self.version, req)
@@ -405,7 +406,7 @@ class CursesSystemDependency(SystemDependency):
class IconvBuiltinDependency(BuiltinDependency):
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, env, kwargs)
self.feature_since = ('0.60.0', "consider checking for `iconv_open` with and without `find_library('iconv')`")
code = '''#include <iconv.h>\n\nint main() {\n iconv_open("","");\n}''' # [ignore encoding] this is C, not python, Mr. Lint
@@ -415,7 +416,7 @@ class IconvBuiltinDependency(BuiltinDependency):
class IconvSystemDependency(SystemDependency):
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, env, kwargs)
self.feature_since = ('0.60.0', "consider checking for `iconv_open` with and without find_library('iconv')")
@@ -427,7 +428,7 @@ class IconvSystemDependency(SystemDependency):
class IntlBuiltinDependency(BuiltinDependency):
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, env, kwargs)
self.feature_since = ('0.59.0', "consider checking for `ngettext` with and without `find_library('intl')`")
code = '''#include <libintl.h>\n\nint main() {\n gettext("Hello world");\n}'''
@@ -437,7 +438,7 @@ class IntlBuiltinDependency(BuiltinDependency):
class IntlSystemDependency(SystemDependency):
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, env, kwargs)
self.feature_since = ('0.59.0', "consider checking for `ngettext` with and without `find_library('intl')`")
@@ -448,18 +449,18 @@ class IntlSystemDependency(SystemDependency):
self.is_found = True
if self.static:
- if not self._add_sub_dependency(iconv_factory(env, self.for_machine, {'static': True})):
+ if not self._add_sub_dependency(iconv_factory(env, self.for_machine, {'static': True})): # type: ignore[typeddict-unknown-key]
self.is_found = False
class OpensslSystemDependency(SystemDependency):
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, env, kwargs)
- dependency_kwargs = {
+ dependency_kwargs: DependencyObjectKWs = {
'method': 'system',
'static': self.static,
- }
+ } # type: ignore[typeddict-unknown-key]
if not self.clib_compiler.has_header('openssl/ssl.h', '', env)[0]:
return
@@ -506,7 +507,7 @@ class ObjFWDependency(ConfigToolDependency):
tools = ['objfw-config']
tool_name = 'objfw-config'
- def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, environment: 'Environment', kwargs: DependencyObjectKWs):
super().__init__('objfw', environment, kwargs)
self.feature_since = ('1.5.0', '')
if not self.is_found:
@@ -516,7 +517,7 @@ class ObjFWDependency(ConfigToolDependency):
# TODO: Expose --framework-libs
extra_flags = []
- for module in mesonlib.stringlistify(mesonlib.extract_as_list(kwargs, 'modules')):
+ for module in mesonlib.stringlistify(mesonlib.extract_as_list(kwargs, 'modules')): # type: ignore[arg-type]
extra_flags.append('--package')
extra_flags.append(module)
@@ -528,7 +529,7 @@ class ObjFWDependency(ConfigToolDependency):
@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.SYSTEM})
def curses_factory(env: 'Environment',
for_machine: 'mesonlib.MachineChoice',
- kwargs: T.Dict[str, T.Any],
+ kwargs: DependencyObjectKWs,
methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
candidates: T.List['DependencyGenerator'] = []
@@ -554,7 +555,7 @@ packages['curses'] = curses_factory
@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM})
def shaderc_factory(env: 'Environment',
for_machine: 'mesonlib.MachineChoice',
- kwargs: T.Dict[str, T.Any],
+ kwargs: DependencyObjectKWs,
methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
"""Custom DependencyFactory for ShaderC.
diff --git a/mesonbuild/dependencies/mpi.py b/mesonbuild/dependencies/mpi.py
index a259972b0..8d8ead86d 100644
--- a/mesonbuild/dependencies/mpi.py
+++ b/mesonbuild/dependencies/mpi.py
@@ -20,14 +20,15 @@ if T.TYPE_CHECKING:
from .factory import DependencyGenerator
from ..environment import Environment
from ..mesonlib import MachineChoice
+ from .base import DependencyObjectKWs
@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.SYSTEM})
def mpi_factory(env: 'Environment',
for_machine: 'MachineChoice',
- kwargs: T.Dict[str, T.Any],
+ kwargs: DependencyObjectKWs,
methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
- language = kwargs.get('language')
+ language = T.cast('T.Optional[str]', kwargs.get('language'))
if language is None:
language = 'c'
if language not in {'c', 'cpp', 'fortran'}:
@@ -58,7 +59,7 @@ def mpi_factory(env: 'Environment',
if compiler_is_intel:
if env.machines[for_machine].is_windows():
- nwargs['returncode_value'] = 3
+ nwargs['returncode_value'] = 3 # type: ignore[typeddict-unknown-key]
if language == 'c':
tool_names.append('mpiicc')
@@ -75,7 +76,7 @@ def mpi_factory(env: 'Environment',
elif language == 'fortran':
tool_names.extend(['mpifort', 'mpif90', 'mpif77'])
- nwargs['tools'] = tool_names
+ nwargs['tools'] = tool_names # type: ignore[typeddict-unknown-key]
candidates.append(functools.partial(
MPIConfigToolDependency, tool_names[0], env, nwargs, language=language))
@@ -104,7 +105,7 @@ packages['mpi'] = mpi_factory
class MPIConfigToolDependency(ConfigToolDependency):
"""Wrapper around mpicc, Intel's mpiicc and friends."""
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any],
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs,
language: T.Optional[str] = None):
super().__init__(name, env, kwargs, language=language)
if not self.is_found:
@@ -214,7 +215,7 @@ class MSMPIDependency(SystemDependency):
"""The Microsoft MPI."""
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any],
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs,
language: T.Optional[str] = None):
super().__init__(name, env, kwargs, language=language)
# MSMPI only supports the C API
diff --git a/mesonbuild/dependencies/pkgconfig.py b/mesonbuild/dependencies/pkgconfig.py
index a1390fb59..326ecb1b4 100644
--- a/mesonbuild/dependencies/pkgconfig.py
+++ b/mesonbuild/dependencies/pkgconfig.py
@@ -25,6 +25,7 @@ if T.TYPE_CHECKING:
from ..environment import Environment
from ..utils.core import EnvironOrDict
from ..interpreter.type_checking import PkgConfigDefineType
+ from .base import DependencyObjectKWs
class PkgConfigInterface:
'''Base class wrapping a pkg-config implementation'''
@@ -305,7 +306,7 @@ class PkgConfigCLI(PkgConfigInterface):
class PkgConfigDependency(ExternalDependency):
- def __init__(self, name: str, environment: Environment, kwargs: T.Dict[str, T.Any],
+ def __init__(self, name: str, environment: Environment, kwargs: DependencyObjectKWs,
language: T.Optional[str] = None,
extra_paths: T.Optional[T.List[str]] = None) -> None:
super().__init__(DependencyTypeName('pkgconfig'), environment, kwargs, language=language)
diff --git a/mesonbuild/dependencies/platform.py b/mesonbuild/dependencies/platform.py
index 335faed2c..14eca3821 100644
--- a/mesonbuild/dependencies/platform.py
+++ b/mesonbuild/dependencies/platform.py
@@ -12,11 +12,12 @@ import typing as T
if T.TYPE_CHECKING:
from ..environment import Environment
+ from .base import DependencyObjectKWs
class AppleFrameworks(ExternalDependency):
- def __init__(self, env: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
+ def __init__(self, env: 'Environment', kwargs: DependencyObjectKWs) -> None:
super().__init__(DependencyTypeName('appleframeworks'), env, kwargs)
- modules = kwargs.get('modules', [])
+ modules = T.cast('T.Union[None, str, T.List[str]]', kwargs.get('modules', []))
if isinstance(modules, str):
modules = [modules]
if not modules:
diff --git a/mesonbuild/dependencies/python.py b/mesonbuild/dependencies/python.py
index 5c5ed384f..0f9a618b6 100644
--- a/mesonbuild/dependencies/python.py
+++ b/mesonbuild/dependencies/python.py
@@ -24,6 +24,7 @@ if T.TYPE_CHECKING:
from .factory import DependencyGenerator
from ..environment import Environment
from ..mesonlib import MachineChoice
+ from .base import DependencyObjectKWs
class PythonIntrospectionDict(TypedDict):
@@ -56,7 +57,7 @@ class Pybind11ConfigToolDependency(ConfigToolDependency):
# in the meantime
skip_version = '--pkgconfigdir'
- def __init__(self, name: str, environment: Environment, kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: Environment, kwargs: DependencyObjectKWs):
super().__init__(name, environment, kwargs)
if not self.is_found:
return
@@ -67,7 +68,7 @@ class NumPyConfigToolDependency(ConfigToolDependency):
tools = ['numpy-config']
- def __init__(self, name: str, environment: Environment, kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: Environment, kwargs: DependencyObjectKWs):
super().__init__(name, environment, kwargs)
if not self.is_found:
return
@@ -456,7 +457,7 @@ class _PythonDependencyBase(_Base):
class PythonPkgConfigDependency(PkgConfigDependency, _PythonDependencyBase):
- def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any],
+ def __init__(self, environment: 'Environment', kwargs: DependencyObjectKWs,
installation: 'BasicPythonExternalProgram', embed: bool,
for_machine: 'MachineChoice'):
pkg_embed = '-embed' if embed and mesonlib.version_compare(installation.info['version'], '>=3.8') else ''
@@ -483,7 +484,7 @@ class PythonPkgConfigDependency(PkgConfigDependency, _PythonDependencyBase):
pkgconfig_paths = [pkg_libdir] if pkg_libdir else []
PkgConfigDependency.__init__(self, pkg_name, environment, kwargs, extra_paths=pkgconfig_paths)
- _PythonDependencyBase.__init__(self, installation, kwargs.get('embed', False), for_machine)
+ _PythonDependencyBase.__init__(self, installation, T.cast('bool', kwargs.get('embed', False)), for_machine)
if pkg_libdir and not self.is_found:
mlog.debug(f'{pkg_name!r} could not be found in {pkg_libdir_origin}, '
@@ -508,19 +509,19 @@ class PythonPkgConfigDependency(PkgConfigDependency, _PythonDependencyBase):
class PythonFrameworkDependency(ExtraFrameworkDependency, _PythonDependencyBase):
def __init__(self, name: str, environment: 'Environment',
- kwargs: T.Dict[str, T.Any], installation: 'BasicPythonExternalProgram',
+ kwargs: DependencyObjectKWs, installation: 'BasicPythonExternalProgram',
for_machine: 'MachineChoice'):
ExtraFrameworkDependency.__init__(self, name, environment, kwargs)
- _PythonDependencyBase.__init__(self, installation, kwargs.get('embed', False), for_machine)
+ _PythonDependencyBase.__init__(self, installation, T.cast('bool', kwargs.get('embed', False)), for_machine)
class PythonSystemDependency(SystemDependency, _PythonDependencyBase):
def __init__(self, name: str, environment: 'Environment',
- kwargs: T.Dict[str, T.Any], installation: 'BasicPythonExternalProgram',
+ kwargs: DependencyObjectKWs, installation: 'BasicPythonExternalProgram',
for_machine: 'MachineChoice'):
SystemDependency.__init__(self, name, environment, kwargs)
- _PythonDependencyBase.__init__(self, installation, kwargs.get('embed', False), for_machine)
+ _PythonDependencyBase.__init__(self, installation, T.cast('bool', kwargs.get('embed', False)), for_machine)
# For most platforms, match pkg-config behavior. iOS is a special case;
# check for that first, so that check takes priority over
@@ -563,12 +564,12 @@ class PythonSystemDependency(SystemDependency, _PythonDependencyBase):
return 'sysconfig'
def python_factory(env: 'Environment', for_machine: 'MachineChoice',
- kwargs: T.Dict[str, T.Any],
+ kwargs: DependencyObjectKWs,
installation: T.Optional['BasicPythonExternalProgram'] = None) -> T.List['DependencyGenerator']:
# We can't use the factory_methods decorator here, as we need to pass the
# extra installation argument
methods = process_method_kw({DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM}, kwargs)
- embed = kwargs.get('embed', False)
+ embed = T.cast('bool', kwargs.get('embed', False))
candidates: T.List['DependencyGenerator'] = []
from_installation = installation is not None
# When not invoked through the python module, default installation.
@@ -590,7 +591,7 @@ def python_factory(env: 'Environment', for_machine: 'MachineChoice',
if mesonlib.version_compare(installation.version, '>= 3'):
# There is a python in /System/Library/Frameworks, but that's python 2.x,
# Python 3 will always be in /Library
- nkwargs['paths'] = ['/Library/Frameworks']
+ nkwargs['paths'] = ['/Library/Frameworks'] # type: ignore[typeddict-unknown-key]
candidates.append(functools.partial(PythonFrameworkDependency, 'Python', env, nkwargs, installation, for_machine))
return candidates
diff --git a/mesonbuild/dependencies/qt.py b/mesonbuild/dependencies/qt.py
index 8bb269e83..a277de5ae 100644
--- a/mesonbuild/dependencies/qt.py
+++ b/mesonbuild/dependencies/qt.py
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2013-2017 The Meson development team
-# Copyright © 2021-2023 Intel Corporation
+# Copyright © 2021-2025 Intel Corporation
from __future__ import annotations
@@ -26,6 +26,7 @@ if T.TYPE_CHECKING:
from ..envconfig import MachineInfo
from ..environment import Environment
from ..dependencies import MissingCompiler
+ from .base import DependencyObjectKWs
def _qt_get_private_includes(mod_inc_dir: str, module: str, mod_version: str) -> T.List[str]:
@@ -96,7 +97,7 @@ def _get_modules_lib_suffix(version: str, info: 'MachineInfo', is_debug: bool) -
class QtExtraFrameworkDependency(ExtraFrameworkDependency):
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any], qvars: T.Dict[str, str], language: T.Optional[str] = None):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs, qvars: T.Dict[str, str], language: T.Optional[str] = None):
super().__init__(name, env, kwargs, language=language)
self.mod_name = name[2:]
self.qt_extra_include_directory = qvars['QT_INSTALL_HEADERS']
@@ -123,7 +124,7 @@ class _QtBase:
libexecdir: T.Optional[str] = None
version: str
- def __init__(self, name: str, kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, kwargs: DependencyObjectKWs):
self.name = name
self.qtname = name.capitalize()
self.qtver = name[-1]
@@ -134,7 +135,7 @@ class _QtBase:
self.private_headers = T.cast('bool', kwargs.get('private_headers', False))
- self.requested_modules = mesonlib.stringlistify(mesonlib.extract_as_list(kwargs, 'modules'))
+ self.requested_modules = mesonlib.stringlistify(mesonlib.extract_as_list(kwargs, 'modules')) # type: ignore[arg-type]
if not self.requested_modules:
raise DependencyException('No ' + self.qtname + ' modules specified.')
@@ -171,7 +172,7 @@ class QtPkgConfigDependency(_QtBase, PkgConfigDependency, metaclass=abc.ABCMeta)
"""Specialization of the PkgConfigDependency for Qt."""
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs):
_QtBase.__init__(self, name, kwargs)
# Always use QtCore as the "main" dependency, since it has the extra
@@ -250,7 +251,7 @@ class QmakeQtDependency(_QtBase, ConfigToolDependency, metaclass=abc.ABCMeta):
version: str
version_arg = '-v'
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs):
_QtBase.__init__(self, name, kwargs)
self.tool_name = f'qmake{self.qtver}'
self.tools = [f'qmake{self.qtver}', f'qmake-{self.name}', 'qmake']
@@ -262,7 +263,7 @@ class QmakeQtDependency(_QtBase, ConfigToolDependency, metaclass=abc.ABCMeta):
kwargs = kwargs.copy()
_vers = mesonlib.listify(kwargs.get('version', []))
_vers.extend([f'>= {self.qtver}', f'< {int(self.qtver) + 1}'])
- kwargs['version'] = _vers
+ kwargs['version'] = _vers # type: ignore[typeddict-unknown-key]
ConfigToolDependency.__init__(self, name, env, kwargs)
if not self.found():
@@ -349,13 +350,13 @@ class QmakeQtDependency(_QtBase, ConfigToolDependency, metaclass=abc.ABCMeta):
def get_private_includes(self, mod_inc_dir: str, module: str) -> T.List[str]:
pass
- def _framework_detect(self, qvars: T.Dict[str, str], modules: T.List[str], kwargs: T.Dict[str, T.Any]) -> None:
+ def _framework_detect(self, qvars: T.Dict[str, str], modules: T.List[str], kwargs: DependencyObjectKWs) -> None:
libdir = qvars['QT_INSTALL_LIBS']
# ExtraFrameworkDependency doesn't support any methods
fw_kwargs = kwargs.copy()
- fw_kwargs.pop('method', None)
- fw_kwargs['paths'] = [libdir]
+ fw_kwargs.pop('method', None) # type: ignore[typeddict-item]
+ fw_kwargs['paths'] = [libdir] # type: ignore[typeddict-unknown-key]
for m in modules:
fname = 'Qt' + m
@@ -443,7 +444,7 @@ class Qt5PkgConfigDependency(QtPkgConfigDependency):
class Qt6PkgConfigDependency(Qt6WinMainMixin, QtPkgConfigDependency):
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, env, kwargs)
if not self.libexecdir:
mlog.debug(f'detected Qt6 {self.version} pkg-config dependency does not '
diff --git a/mesonbuild/dependencies/scalapack.py b/mesonbuild/dependencies/scalapack.py
index f34692c25..1107aa8ac 100644
--- a/mesonbuild/dependencies/scalapack.py
+++ b/mesonbuild/dependencies/scalapack.py
@@ -19,11 +19,12 @@ if T.TYPE_CHECKING:
from ..environment import Environment
from ..mesonlib import MachineChoice
from .factory import DependencyGenerator
+ from .base import DependencyObjectKWs
@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE})
def scalapack_factory(env: 'Environment', for_machine: 'MachineChoice',
- kwargs: T.Dict[str, T.Any],
+ kwargs: DependencyObjectKWs,
methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
candidates: T.List['DependencyGenerator'] = []
@@ -54,7 +55,7 @@ class MKLPkgConfigDependency(PkgConfigDependency):
bunch of fixups to make it work correctly.
"""
- def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any],
+ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs,
language: T.Optional[str] = None):
_m = os.environ.get('MKLROOT')
self.__mklroot = Path(_m).resolve() if _m else None
diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py
index edf3c310a..4d9215644 100644
--- a/mesonbuild/dependencies/ui.py
+++ b/mesonbuild/dependencies/ui.py
@@ -24,10 +24,11 @@ from .factory import DependencyFactory
if T.TYPE_CHECKING:
from ..environment import Environment
+ from .base import DependencyObjectKWs
class GLDependencySystem(SystemDependency):
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs) -> None:
super().__init__(name, environment, kwargs)
if self.env.machines[self.for_machine].is_darwin():
@@ -56,11 +57,11 @@ class GnuStepDependency(ConfigToolDependency):
tools = ['gnustep-config']
tool_name = 'gnustep-config'
- def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None:
+ def __init__(self, environment: 'Environment', kwargs: DependencyObjectKWs) -> None:
super().__init__('gnustep', environment, kwargs, language='objc')
if not self.is_found:
return
- self.modules = kwargs.get('modules', [])
+ self.modules = T.cast('T.List[str]', kwargs.get('modules', []))
self.compile_args = self.filter_args(
self.get_config_value(['--objc-flags'], 'compile_args'))
self.link_args = self.weird_filter(self.get_config_value(
@@ -135,7 +136,7 @@ class SDL2DependencyConfigTool(ConfigToolDependency):
tools = ['sdl2-config']
tool_name = 'sdl2-config'
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs):
super().__init__(name, environment, kwargs)
if not self.is_found:
return
@@ -148,7 +149,7 @@ class WxDependency(ConfigToolDependency):
tools = ['wx-config-3.0', 'wx-config-3.1', 'wx-config', 'wx-config-gtk3']
tool_name = 'wx-config'
- def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
+ def __init__(self, environment: 'Environment', kwargs: DependencyObjectKWs):
super().__init__('WxWidgets', environment, kwargs, language='cpp')
if not self.is_found:
return
@@ -171,10 +172,10 @@ class WxDependency(ConfigToolDependency):
self.link_args = self.get_config_value(['--libs'] + extra_args + self.requested_modules, 'link_args')
@staticmethod
- def get_requested(kwargs: T.Dict[str, T.Any]) -> T.List[str]:
+ def get_requested(kwargs: DependencyObjectKWs) -> T.List[str]:
if 'modules' not in kwargs:
return []
- candidates = extract_as_list(kwargs, 'modules')
+ candidates = T.cast('T.List[str]', extract_as_list(kwargs, 'modules')) # type: ignore[arg-type]
for c in candidates:
if not isinstance(c, str):
raise DependencyException('wxwidgets module argument is not a string')
@@ -184,7 +185,7 @@ packages['wxwidgets'] = WxDependency
class VulkanDependencySystem(SystemDependency):
- def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None) -> None:
+ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs, language: T.Optional[str] = None) -> None:
super().__init__(name, environment, kwargs, language=language)
self.vulkan_sdk = os.environ.get('VULKAN_SDK', os.environ.get('VK_SDK_PATH'))