aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/dependencies/base.py
diff options
context:
space:
mode:
authorDaniel Mensinger <daniel@mensinger-ka.de>2021-06-01 11:23:12 +0200
committerDylan Baker <dylan@pnwbakers.com>2021-06-03 10:23:27 -0700
commitdf4d2bd24729a06c604a52aad4b44c5ddbd608fa (patch)
tree4b4cfc17a116482581c7e80e7fe9ca72711a88e0 /mesonbuild/dependencies/base.py
parentf502a38d1c98361301b601238d39a478871d17dc (diff)
downloadmeson-df4d2bd24729a06c604a52aad4b44c5ddbd608fa.zip
meson-df4d2bd24729a06c604a52aad4b44c5ddbd608fa.tar.gz
meson-df4d2bd24729a06c604a52aad4b44c5ddbd608fa.tar.bz2
typing: Fully annotate dependencies.base
Diffstat (limited to 'mesonbuild/dependencies/base.py')
-rw-r--r--mesonbuild/dependencies/base.py128
1 files changed, 64 insertions, 64 deletions
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index f18a7cc..9b835d0 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -15,30 +15,21 @@
# This file contains the detection logic for external dependencies.
# Custom logic for several other packages are in separate files.
import copy
-import functools
import os
-import re
import itertools
-import json
-import shlex
-import shutil
-import textwrap
import typing as T
from enum import Enum
-from pathlib import Path, PurePath
from .. import mlog
-from .. import mesonlib
from ..compilers import clib_langs
-from ..environment import Environment, MachineInfo
-from ..mesonlib import MachineChoice, MesonException, OrderedSet, PerMachine
-from ..mesonlib import Popen_safe, version_compare_many, version_compare, listify, stringlistify, extract_as_list, split_args
-from ..mesonlib import Version, LibType, OptionKey
-from ..programs import ExternalProgram, find_external_program
+from ..mesonlib import MachineChoice, MesonException
+from ..mesonlib import version_compare_many
from ..interpreterbase import FeatureDeprecated
if T.TYPE_CHECKING:
from ..compilers.compilers import Compiler
+ from ..environment import Environment
+ from ..build import BuildTarget
DependencyType = T.TypeVar('DependencyType', bound='Dependency')
@@ -72,7 +63,7 @@ class DependencyMethods(Enum):
class Dependency:
@classmethod
- def _process_include_type_kw(cls, kwargs) -> str:
+ def _process_include_type_kw(cls, kwargs: T.Dict[str, T.Any]) -> str:
if 'include_type' not in kwargs:
return 'preserve'
if not isinstance(kwargs['include_type'], str):
@@ -81,25 +72,24 @@ class Dependency:
raise DependencyException("include_type may only be one of ['preserve', 'system', 'non-system']")
return kwargs['include_type']
- def __init__(self, type_name, kwargs):
+ def __init__(self, type_name: str, kwargs: T.Dict[str, T.Any]) -> None:
self.name = "null"
- self.version = None # type: T.Optional[str]
- self.language = None # None means C-like
+ self.version: T.Optional[str] = None
+ self.language: T.Optional[str] = None # None means C-like
self.is_found = False
self.type_name = type_name
- self.compile_args = [] # type: T.List[str]
- self.link_args = []
+ self.compile_args: T.List[str] = []
+ self.link_args: T.List[str] = []
# Raw -L and -l arguments without manual library searching
# If None, self.link_args will be used
- self.raw_link_args = None
- self.sources = []
+ self.raw_link_args: T.Optional[T.List[str]] = None
+ self.sources: T.List[str] = []
self.methods = process_method_kw(self.get_methods(), kwargs)
self.include_type = self._process_include_type_kw(kwargs)
- self.ext_deps = [] # type: T.List[Dependency]
+ self.ext_deps: T.List[Dependency] = []
- def __repr__(self):
- s = '<{0} {1}: {2}>'
- return s.format(self.__class__.__name__, self.name, self.is_found)
+ def __repr__(self) -> str:
+ return f'<{self.__class__.__name__} {self.name}: {self.is_found}>'
def is_built(self) -> bool:
return False
@@ -109,7 +99,7 @@ class Dependency:
return mlog.red('NO')
if not self.version:
return mlog.green('YES')
- return mlog.AnsiText(mlog.green('YES'), ' ', mlog.cyan(self.version))
+ return mlog.AnsiText([mlog.green('YES'), ' ', mlog.cyan(self.version)])
def get_compile_args(self) -> T.List[str]:
if self.include_type == 'system':
@@ -135,7 +125,7 @@ class Dependency:
return list(itertools.chain(self.get_compile_args(),
*[d.get_all_compile_args() for d in self.ext_deps]))
- def get_link_args(self, raw: bool = False) -> T.List[str]:
+ def get_link_args(self, language: T.Optional[str] = None, raw: bool = False) -> T.List[str]:
if raw and self.raw_link_args is not None:
return self.raw_link_args
return self.link_args
@@ -148,16 +138,16 @@ class Dependency:
def found(self) -> bool:
return self.is_found
- def get_sources(self):
+ def get_sources(self) -> T.List[str]:
"""Source files that need to be added to the target.
As an example, gtest-all.cc when using GTest."""
return self.sources
@staticmethod
- def get_methods():
+ def get_methods() -> T.List[DependencyMethods]:
return [DependencyMethods.AUTO]
- def get_name(self):
+ def get_name(self) -> str:
return self.name
def get_version(self) -> str:
@@ -169,18 +159,18 @@ class Dependency:
def get_include_type(self) -> str:
return self.include_type
- def get_exe_args(self, compiler):
+ def get_exe_args(self, compiler: 'Compiler') -> T.List[str]:
return []
def get_pkgconfig_variable(self, variable_name: str, kwargs: T.Dict[str, T.Any]) -> str:
raise DependencyException(f'{self.name!r} is not a pkgconfig dependency')
- def get_configtool_variable(self, variable_name):
+ def get_configtool_variable(self, variable_name: str) -> str:
raise DependencyException(f'{self.name!r} is not a config-tool dependency')
def get_partial_dependency(self, *, compile_args: bool = False,
link_args: bool = False, links: bool = False,
- includes: bool = False, sources: bool = False):
+ includes: bool = False, sources: bool = False) -> 'Dependency':
"""Create a new dependency that contains part of the parent dependency.
The following options can be inherited:
@@ -220,14 +210,16 @@ class Dependency:
return default_value
raise DependencyException(f'No default provided for dependency {self!r}, which is not pkg-config, cmake, or config-tool based.')
- def generate_system_dependency(self, include_type: str) -> T.Type['Dependency']:
+ 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})
return new_dep
class InternalDependency(Dependency):
- def __init__(self, version, incdirs, compile_args, link_args, libraries,
- whole_libraries, sources, ext_deps, variables: T.Dict[str, T.Any]):
+ def __init__(self, version: str, incdirs: T.List[str], compile_args: T.List[str],
+ link_args: T.List[str], libraries: T.List['BuildTarget'],
+ whole_libraries: T.List['BuildTarget'], sources: T.List[str],
+ ext_deps: T.List[Dependency], variables: T.Dict[str, T.Any]):
super().__init__('internal', {})
self.version = version
self.is_found = True
@@ -240,8 +232,9 @@ class InternalDependency(Dependency):
self.ext_deps = ext_deps
self.variables = variables
- def __deepcopy__(self, memo: dict) -> 'InternalDependency':
+ def __deepcopy__(self, memo: T.Dict[int, 'InternalDependency']) -> 'InternalDependency':
result = self.__class__.__new__(self.__class__)
+ assert isinstance(result, InternalDependency)
memo[id(self)] = result
for k, v in self.__dict__.items():
if k in ['libraries', 'whole_libraries']:
@@ -264,13 +257,13 @@ class InternalDependency(Dependency):
raise DependencyException('Method "get_pkgconfig_variable()" is '
'invalid for an internal dependency')
- def get_configtool_variable(self, variable_name):
+ def get_configtool_variable(self, variable_name: str) -> str:
raise DependencyException('Method "get_configtool_variable()" is '
'invalid for an internal dependency')
def get_partial_dependency(self, *, compile_args: bool = False,
link_args: bool = False, links: bool = False,
- includes: bool = False, sources: bool = False):
+ includes: bool = False, sources: bool = False) -> 'InternalDependency':
final_compile_args = self.compile_args.copy() if compile_args else []
final_link_args = self.link_args.copy() if link_args else []
final_libraries = self.libraries.copy() if links else []
@@ -291,10 +284,16 @@ class InternalDependency(Dependency):
pkgconfig_define: T.Optional[T.List[str]] = None) -> T.Union[str, T.List[str]]:
val = self.variables.get(internal, default_value)
if val is not None:
- return val
+ # TODO: Try removing this assert by better typing self.variables
+ if isinstance(val, str):
+ return val
+ if isinstance(val, list):
+ for i in val:
+ assert isinstance(i, str)
+ return val
raise DependencyException(f'Could not get an internal variable and no default provided for {self!r}')
- def generate_link_whole_dependency(self) -> T.Type['Dependency']:
+ def generate_link_whole_dependency(self) -> Dependency:
new_dep = copy.deepcopy(self)
new_dep.whole_libraries += new_dep.libraries
new_dep.libraries = []
@@ -308,7 +307,7 @@ class HasNativeKwarg:
return MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST
class ExternalDependency(Dependency, HasNativeKwarg):
- def __init__(self, type_name, environment: Environment, kwargs, language: T.Optional[str] = None):
+ def __init__(self, type_name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None):
Dependency.__init__(self, type_name, kwargs)
self.env = environment
self.name = type_name # default
@@ -326,12 +325,12 @@ class ExternalDependency(Dependency, HasNativeKwarg):
HasNativeKwarg.__init__(self, kwargs)
self.clib_compiler = detect_compiler(self.name, environment, self.for_machine, self.language)
- def get_compiler(self):
+ def get_compiler(self) -> 'Compiler':
return self.clib_compiler
def get_partial_dependency(self, *, compile_args: bool = False,
link_args: bool = False, links: bool = False,
- includes: bool = False, sources: bool = False):
+ includes: bool = False, sources: bool = False) -> Dependency:
new = copy.copy(self)
if not compile_args:
new.compile_args = []
@@ -340,32 +339,32 @@ class ExternalDependency(Dependency, HasNativeKwarg):
if not sources:
new.sources = []
if not includes:
- new.include_directories = []
+ pass # TODO maybe filter compile_args?
if not sources:
new.sources = []
return new
- def log_details(self):
+ def log_details(self) -> str:
return ''
- def log_info(self):
+ def log_info(self) -> str:
return ''
- def log_tried(self):
+ def log_tried(self) -> str:
return ''
# Check if dependency version meets the requirements
- def _check_version(self):
+ def _check_version(self) -> None:
if not self.is_found:
return
if self.version_reqs:
# an unknown version can never satisfy any requirement
if not self.version:
- found_msg = ['Dependency', mlog.bold(self.name), 'found:']
- found_msg += [mlog.red('NO'), 'unknown version, but need:',
- self.version_reqs]
+ found_msg: mlog.TV_LoggableList = []
+ found_msg += ['Dependency', mlog.bold(self.name), 'found:']
+ found_msg += [mlog.red('NO'), 'unknown version, but need:', self.version_reqs]
mlog.log(*found_msg)
if self.required:
@@ -392,7 +391,7 @@ class ExternalDependency(Dependency, HasNativeKwarg):
class NotFoundDependency(Dependency):
- def __init__(self, environment):
+ def __init__(self, environment: 'Environment') -> None:
super().__init__('not-found', {})
self.env = environment
self.name = 'not-found'
@@ -400,12 +399,13 @@ class NotFoundDependency(Dependency):
def get_partial_dependency(self, *, compile_args: bool = False,
link_args: bool = False, links: bool = False,
- includes: bool = False, sources: bool = False):
+ includes: bool = False, sources: bool = False) -> 'NotFoundDependency':
return copy.copy(self)
class ExternalLibrary(ExternalDependency):
- def __init__(self, name, link_args, environment, language, silent=False):
+ def __init__(self, name: str, link_args: T.List[str], environment: 'Environment',
+ language: str, silent: bool = False) -> None:
super().__init__('library', environment, {}, language=language)
self.name = name
self.language = language
@@ -419,7 +419,7 @@ class ExternalLibrary(ExternalDependency):
else:
mlog.log('Library', mlog.bold(name), 'found:', mlog.red('NO'))
- def get_link_args(self, language=None, **kwargs):
+ def get_link_args(self, language: T.Optional[str] = None, raw: bool = False) -> T.List[str]:
'''
External libraries detected using a compiler must only be used with
compatible code. For instance, Vala libraries (.vapi files) cannot be
@@ -432,11 +432,11 @@ class ExternalLibrary(ExternalDependency):
if (self.language == 'vala' and language != 'vala') or \
(language == 'vala' and self.language != 'vala'):
return []
- return super().get_link_args(**kwargs)
+ return super().get_link_args(language=language, raw=raw)
def get_partial_dependency(self, *, compile_args: bool = False,
link_args: bool = False, links: bool = False,
- includes: bool = False, sources: bool = False):
+ includes: bool = False, sources: bool = False) -> 'ExternalLibrary':
# External library only has link_args, so ignore the rest of the
# interface.
new = copy.copy(self)
@@ -454,11 +454,11 @@ def sort_libpaths(libpaths: T.List[str], refpaths: T.List[str]) -> T.List[str]:
if len(refpaths) == 0:
return list(libpaths)
- def key_func(libpath):
- common_lengths = []
+ def key_func(libpath: str) -> T.Tuple[int, int]:
+ common_lengths: T.List[int] = []
for refpath in refpaths:
try:
- common_path = os.path.commonpath([libpath, refpath])
+ common_path: str = os.path.commonpath([libpath, refpath])
except ValueError:
common_path = ''
common_lengths.append(len(common_path))
@@ -468,7 +468,7 @@ def sort_libpaths(libpaths: T.List[str], refpaths: T.List[str]) -> T.List[str]:
return (max_index, reversed_max_length)
return sorted(libpaths, key=key_func)
-def strip_system_libdirs(environment, for_machine: MachineChoice, link_args):
+def strip_system_libdirs(environment: 'Environment', for_machine: MachineChoice, link_args: T.List[str]) -> T.List[str]:
"""Remove -L<system path> arguments.
leaving these in will break builds where a user has a version of a library
@@ -478,7 +478,7 @@ def strip_system_libdirs(environment, for_machine: MachineChoice, link_args):
exclude = {f'-L{p}' for p in environment.get_compiler_system_dirs(for_machine)}
return [l for l in link_args if l not in exclude]
-def process_method_kw(possible: T.Iterable[DependencyMethods], kwargs) -> T.List[DependencyMethods]:
+def process_method_kw(possible: T.Iterable[DependencyMethods], kwargs: T.Dict[str, T.Any]) -> T.List[DependencyMethods]:
method = kwargs.get('method', 'auto') # type: T.Union[DependencyMethods, str]
if isinstance(method, DependencyMethods):
return [method]
@@ -511,7 +511,7 @@ def process_method_kw(possible: T.Iterable[DependencyMethods], kwargs) -> T.List
return methods
-def detect_compiler(name: str, env: Environment, for_machine: MachineChoice,
+def detect_compiler(name: str, env: 'Environment', for_machine: MachineChoice,
language: T.Optional[str]) -> T.Optional['Compiler']:
"""Given a language and environment find the compiler used."""
compilers = env.coredata.compilers[for_machine]