diff options
Diffstat (limited to 'mesonbuild/dependencies')
-rw-r--r-- | mesonbuild/dependencies/coarrays.py | 5 | ||||
-rw-r--r-- | mesonbuild/dependencies/detect.py | 43 | ||||
-rw-r--r-- | mesonbuild/dependencies/factory.py | 51 | ||||
-rw-r--r-- | mesonbuild/dependencies/hdf5.py | 7 | ||||
-rw-r--r-- | mesonbuild/dependencies/misc.py | 9 | ||||
-rw-r--r-- | mesonbuild/dependencies/mpi.py | 5 | ||||
-rw-r--r-- | mesonbuild/dependencies/scalapack.py | 4 |
7 files changed, 81 insertions, 43 deletions
diff --git a/mesonbuild/dependencies/coarrays.py b/mesonbuild/dependencies/coarrays.py index e86249f..35001e4 100644 --- a/mesonbuild/dependencies/coarrays.py +++ b/mesonbuild/dependencies/coarrays.py @@ -22,14 +22,15 @@ from .factory import factory_methods if T.TYPE_CHECKING: from . base import Dependency + from . factory import TV_DepGenerators from ..environment import Environment, MachineChoice @factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE, DependencyMethods.SYSTEM}) def coarray_factory(env: 'Environment', for_machine: 'MachineChoice', - kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List[T.Callable[[], 'Dependency']]: + kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> 'TV_DepGenerators': fcid = detect_compiler('coarray', env, for_machine, 'fortran').get_id() - candidates: T.List[T.Callable[[], 'Dependency']] = [] + candidates: 'TV_DepGenerators' = [] if fcid == 'gcc': # OpenCoarrays is the most commonly used method for Fortran Coarray with GCC diff --git a/mesonbuild/dependencies/detect.py b/mesonbuild/dependencies/detect.py index 38bd2ad..199e211 100644 --- a/mesonbuild/dependencies/detect.py +++ b/mesonbuild/dependencies/detect.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from .base import Dependency, DependencyException, DependencyMethods, NotFoundDependency +from .base import Dependency, ExternalDependency, DependencyException, DependencyMethods, NotFoundDependency from .cmake import CMakeDependency from .dub import DubDependency from .framework import ExtraFrameworkDependency @@ -25,15 +25,19 @@ import typing as T if T.TYPE_CHECKING: from ..environment import Environment - from .base import ExternalDependency - from .factory import DependencyType + from .factory import DependencyFactory, TV_FactoryFunc, TV_DepGenerators # These must be defined in this file to avoid cyclical references. -packages = {} -_packages_accept_language = set() +packages: T.Dict[str, T.Union[T.Type[ExternalDependency], 'DependencyFactory', 'TV_FactoryFunc']] = {} +_packages_accept_language: T.Set[str] = set() -def get_dep_identifier(name, kwargs) -> T.Tuple: - identifier = (name, ) +if T.TYPE_CHECKING: + TV_DepIDEntry = T.Union[str, bool, int, T.Tuple[str, ...]] + TV_DepID = T.Tuple[T.Tuple[str, TV_DepIDEntry], ...] + + +def get_dep_identifier(name: str, kwargs: T.Dict[str, T.Any]) -> 'TV_DepID': + identifier: 'TV_DepID' = (('name', name), ) from ..interpreter import permitted_dependency_kwargs assert len(permitted_dependency_kwargs) == 19, \ 'Extra kwargs have been added to dependency(), please review if it makes sense to handle it here' @@ -53,6 +57,10 @@ def get_dep_identifier(name, kwargs) -> T.Tuple: # All keyword arguments are strings, ints, or lists (or lists of lists) if isinstance(value, list): value = frozenset(listify(value)) + for i in value: + assert isinstance(i, str) + else: + assert isinstance(value, (str, bool, int)) identifier += (key, value) return identifier @@ -70,7 +78,7 @@ display_name_map = { 'wxwidgets': 'WxWidgets', } -def find_external_dependency(name: str, env: 'Environment', kwargs: T.Dict[str, object]) -> 'ExternalDependency': +def find_external_dependency(name: str, env: 'Environment', kwargs: T.Dict[str, object]) -> T.Union['ExternalDependency', NotFoundDependency]: assert(name) required = kwargs.get('required', True) if not isinstance(required, bool): @@ -94,7 +102,7 @@ def find_external_dependency(name: str, env: 'Environment', kwargs: T.Dict[str, candidates = _build_external_dependency_list(name, env, for_machine, kwargs) pkg_exc: T.List[DependencyException] = [] - pkgdep: T.List['ExternalDependency'] = [] + pkgdep: T.List[ExternalDependency] = [] details = '' for c in candidates: @@ -117,7 +125,7 @@ def find_external_dependency(name: str, env: 'Environment', kwargs: T.Dict[str, # if the dependency was found if d.found(): - info = [] + info: mlog.TV_LoggableList = [] if d.version: info.append(mlog.normal_cyan(d.version)) @@ -155,7 +163,7 @@ 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[T.Callable[[], 'ExternalDependency']]: + kwargs: T.Dict[str, T.Any]) -> 'TV_DepGenerators': # 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'])) @@ -166,13 +174,18 @@ def _build_external_dependency_list(name: str, env: 'Environment', for_machine: # Create the list of dependency object constructors using a factory # class method, if one exists, otherwise the list just consists of the # constructor - if isinstance(packages[lname], type) and issubclass(packages[lname], Dependency): - dep = [functools.partial(packages[lname], env, kwargs)] + if isinstance(packages[lname], type): + entry1 = T.cast(T.Type[ExternalDependency], packages[lname]) # mypy doesn't understand isinstance(..., type) + if issubclass(entry1, ExternalDependency): + # TODO: somehow make mypy understand that entry1(env, kwargs) is OK... + func: T.Callable[[], 'ExternalDependency'] = lambda: entry1(env, kwargs) # type: ignore + dep = [func] else: - dep = packages[lname](env, for_machine, kwargs) + entry2 = T.cast(T.Union['DependencyFactory', 'TV_FactoryFunc'], packages[lname]) + dep = entry2(env, for_machine, kwargs) return dep - candidates = [] + candidates: 'TV_DepGenerators' = [] # If it's explicitly requested, use the dub detection method (only) if 'dub' == kwargs.get('method', ''): diff --git a/mesonbuild/dependencies/factory.py b/mesonbuild/dependencies/factory.py index 760dba2..0e7175b 100644 --- a/mesonbuild/dependencies/factory.py +++ b/mesonbuild/dependencies/factory.py @@ -24,9 +24,27 @@ import typing as T if T.TYPE_CHECKING: from ..environment import Environment - from .base import DependencyType from .configtool import ConfigToolDependency - FactoryType = T.TypeVar('FactoryType', bound=T.Callable[..., T.List[T.Callable[[], 'Dependency']]]) + + TV_DepGenerators = T.List[T.Callable[[], ExternalDependency]] + TV_WrappedFactoryFunc = T.Callable[ + [ + 'Environment', + MachineChoice, + T.Dict[str, T.Any], + T.List[DependencyMethods] + ], + TV_DepGenerators + ] + + TV_FactoryFunc = T.Callable[ + [ + 'Environment', + MachineChoice, + T.Dict[str, T.Any] + ], + TV_DepGenerators + ] class DependencyFactory: @@ -67,17 +85,20 @@ class DependencyFactory: self.extra_kwargs = extra_kwargs or {} self.methods = methods - self.classes = { + self.classes: T.Dict[ + DependencyMethods, + T.Callable[['Environment', T.Dict[str, T.Any]], ExternalDependency] + ] = { # Just attach the correct name right now, either the generic name # or the method specific name. - DependencyMethods.EXTRAFRAMEWORK: functools.partial(framework_class, framework_name or name), - DependencyMethods.PKGCONFIG: functools.partial(pkgconfig_class, pkgconfig_name or name), - DependencyMethods.CMAKE: functools.partial(cmake_class, cmake_name or name), - DependencyMethods.SYSTEM: functools.partial(system_class, name), - DependencyMethods.CONFIG_TOOL: None, + DependencyMethods.EXTRAFRAMEWORK: lambda env, kwargs: framework_class(framework_name or name, env, kwargs), + DependencyMethods.PKGCONFIG: lambda env, kwargs: pkgconfig_class(pkgconfig_name or name, env, kwargs), + DependencyMethods.CMAKE: lambda env, kwargs: cmake_class(cmake_name or name, env, kwargs), + DependencyMethods.SYSTEM: lambda env, kwargs: system_class(name, env, kwargs), + DependencyMethods.CONFIG_TOOL: None, } if configtool_class is not None: - self.classes[DependencyMethods.CONFIG_TOOL] = functools.partial(configtool_class, name) + self.classes[DependencyMethods.CONFIG_TOOL] = lambda env, kwargs: configtool_class(name, env, kwargs) @staticmethod def _process_method(method: DependencyMethods, env: 'Environment', for_machine: MachineChoice) -> bool: @@ -95,7 +116,7 @@ class DependencyFactory: return True def __call__(self, env: 'Environment', for_machine: MachineChoice, - kwargs: T.Dict[str, T.Any]) -> T.List['DependencyType']: + kwargs: T.Dict[str, T.Any]) -> 'TV_DepGenerators': """Return a list of Dependencies with the arguments already attached.""" methods = process_method_kw(self.methods, kwargs) nwargs = self.extra_kwargs.copy() @@ -105,21 +126,21 @@ class DependencyFactory: if self._process_method(m, env, for_machine)] -def factory_methods(methods: T.Set[DependencyMethods]) -> T.Callable[['FactoryType'], 'FactoryType']: +def factory_methods(methods: T.Set[DependencyMethods]) -> T.Callable[['TV_WrappedFactoryFunc'], 'TV_FactoryFunc']: """Decorator for handling methods for dependency factory functions. 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[T.Callable[[], 'Dependency']]: + >>> def factory(env: Environment, for_machine: MachineChoice, kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> 'TV_DepGenerators': >>> pass """ - def inner(func: 'FactoryType') -> 'FactoryType': + def inner(func: 'TV_WrappedFactoryFunc') -> 'TV_FactoryFunc': @functools.wraps(func) - def wrapped(env: 'Environment', for_machine: MachineChoice, kwargs: T.Dict[str, T.Any]) -> T.List[T.Callable[[], 'Dependency']]: + def wrapped(env: 'Environment', for_machine: MachineChoice, kwargs: T.Dict[str, T.Any]) -> 'TV_DepGenerators': return func(env, for_machine, kwargs, process_method_kw(methods, kwargs)) - return T.cast('FactoryType', wrapped) + return wrapped return inner diff --git a/mesonbuild/dependencies/hdf5.py b/mesonbuild/dependencies/hdf5.py index 87cd8f4..db83766 100644 --- a/mesonbuild/dependencies/hdf5.py +++ b/mesonbuild/dependencies/hdf5.py @@ -30,6 +30,7 @@ import typing as T if T.TYPE_CHECKING: from .base import Dependency + from .factory import TV_DepGenerators from ..environment import Environment from ..mesonlib import MachineChoice @@ -143,7 +144,7 @@ class HDF5ConfigToolDependency(ConfigToolDependency): nkwargs = kwargs.copy() nkwargs['language'] = 'c' # I'm being too clever for mypy and pylint - self.is_found = self._add_sub_dependency(hdf5_factory(environment, for_machine, nkwargs)) # type: ignore # pylint: disable=no-value-for-parameter + self.is_found = self._add_sub_dependency(hdf5_factory(environment, for_machine, nkwargs)) # pylint: disable=no-value-for-parameter def _sanitize_version(self, ver: str) -> str: v = re.search(r'\s*HDF5 Version: (\d+\.\d+\.\d+)', ver) @@ -152,9 +153,9 @@ 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[T.Callable[[], 'Dependency']]: + kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> 'TV_DepGenerators': language = kwargs.get('language') - candidates = [] # type: T.List[T.Callable[[], Dependency]] + candidates: 'TV_DepGenerators' = [] if DependencyMethods.PKGCONFIG in methods: # Use an ordered set so that these remain the first tried pkg-config files diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 84cf04e..52380f3 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -32,12 +32,13 @@ from .factory import DependencyFactory, factory_methods if T.TYPE_CHECKING: from ..environment import Environment, MachineChoice + from .factory import TV_DepGenerators from .base import DependencyType, Dependency # noqa: F401 @factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE}) def netcdf_factory(env: 'Environment', for_machine: 'MachineChoice', - kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List['DependencyType']: + kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> 'TV_DepGenerators': language = kwargs.get('language', 'c') if language not in ('c', 'cpp', 'fortran'): raise DependencyException(f'Language {language} is not supported with NetCDF.') @@ -487,8 +488,8 @@ class CursesSystemDependency(ExternalDependency): @factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.SYSTEM}) def curses_factory(env: 'Environment', for_machine: 'MachineChoice', - kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List[T.Callable[[], 'Dependency']]: - candidates = [] # type: T.List[T.Callable[[], Dependency]] + kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> 'TV_DepGenerators': + candidates: 'TV_DepGenerators' = [] if DependencyMethods.PKGCONFIG in methods: pkgconfig_files = ['pdcurses', 'ncursesw', 'ncurses', 'curses'] @@ -510,7 +511,7 @@ def curses_factory(env: 'Environment', for_machine: 'MachineChoice', @factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM}) def shaderc_factory(env: 'Environment', for_machine: 'MachineChoice', - kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List['DependencyType']: + kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> 'TV_DepGenerators': """Custom DependencyFactory for ShaderC. ShaderC's odd you get three different libraries from the same build diff --git a/mesonbuild/dependencies/mpi.py b/mesonbuild/dependencies/mpi.py index 242dc34..b4dd859 100644 --- a/mesonbuild/dependencies/mpi.py +++ b/mesonbuild/dependencies/mpi.py @@ -25,6 +25,7 @@ from ..environment import detect_cpu_family if T.TYPE_CHECKING: from .base import Dependency + from .factory import TV_DepGenerators from ..compilers import Compiler from ..compilers.compiler import CompilerType from ..environment import Environment, MachineChoice @@ -32,13 +33,13 @@ if T.TYPE_CHECKING: @factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.SYSTEM}) def mpi_factory(env: 'Environment', for_machine: 'MachineChoice', - kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List[T.Callable[[], 'Dependency']]: + kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> 'TV_DepGenerators': language = kwargs.get('language', 'c') if language not in {'c', 'cpp', 'fortran'}: # OpenMPI doesn't work without any other languages return [] - candidates = [] # type: T.List[T.Callable[[], Dependency]] + candidates: 'TV_DepGenerators' = [] compiler = detect_compiler('mpi', env, for_machine, language) # type: T.Optional['CompilerType'] if compiler is None: return [] diff --git a/mesonbuild/dependencies/scalapack.py b/mesonbuild/dependencies/scalapack.py index f81f819..b19e98b 100644 --- a/mesonbuild/dependencies/scalapack.py +++ b/mesonbuild/dependencies/scalapack.py @@ -25,13 +25,13 @@ from .factory import factory_methods if T.TYPE_CHECKING: from ..environment import Environment, MachineChoice - from .base import DependencyType + from .factory import TV_DepGenerators @factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE}) def scalapack_factory(env: 'Environment', for_machine: 'MachineChoice', kwargs: T.Dict[str, T.Any], - methods: T.List[DependencyMethods]) -> T.List['DependencyType']: + methods: T.List[DependencyMethods]) -> 'TV_DepGenerators': candidates = [] if DependencyMethods.PKGCONFIG in methods: |