Skip to content

Commit f4fbb17

Browse files
committed
interpreter/dependencyfallbacks: use DependencyObjectKWs
This allows for a lot of type safety to be introduced, and almost all casting to be removed.
1 parent 229ed1c commit f4fbb17

File tree

2 files changed

+28
-29
lines changed

2 files changed

+28
-29
lines changed

mesonbuild/interpreter/dependencyfallbacks.py

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from .. import dependencies
99
from .. import build
1010
from ..wrap import WrapMode
11-
from ..mesonlib import stringlistify, version_compare_many
11+
from ..mesonlib import stringlistify, version_compare_many, MachineChoice
1212
from ..options import OptionKey
1313
from ..dependencies import Dependency, DependencyException, NotFoundDependency
1414
from ..interpreterbase import (MesonInterpreterObject, FeatureNew,
@@ -19,12 +19,11 @@
1919
from typing_extensions import TypeAlias
2020
from .interpreter import Interpreter
2121
from .kwargs import DoSubproject
22-
from ..interpreterbase import TYPE_nkwargs, TYPE_nvar
23-
from ..mesonlib import MachineChoice
24-
from ..options import ElementaryOptionValues
22+
from ..dependencies.base import DependencyObjectKWs
23+
from ..options import ElementaryOptionValues, OptionDict
2524
from .interpreterobjects import SubprojectHolder
2625

27-
CandidateType: TypeAlias = T.Tuple[T.Callable[[TYPE_nkwargs, TYPE_nvar, DoSubproject], T.Optional[Dependency]], TYPE_nvar]
26+
CandidateType: TypeAlias = T.Tuple[T.Callable[[DependencyObjectKWs, str, DoSubproject], T.Optional[Dependency]], str]
2827

2928

3029
class DependencyFallbacksHolder(MesonInterpreterObject):
@@ -83,36 +82,33 @@ def _subproject_impl(self, subp_name: str, varname: str) -> None:
8382
self.subproject_name = subp_name
8483
self.subproject_varname = varname
8584

86-
def _do_dependency_cache(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: DoSubproject) -> T.Optional[Dependency]:
87-
name = func_args[0]
85+
def _do_dependency_cache(self, kwargs: DependencyObjectKWs, name: str, func_kwargs: DoSubproject) -> T.Optional[Dependency]:
8886
cached_dep = self._get_cached_dep(name, kwargs)
8987
if cached_dep:
9088
self._verify_fallback_consistency(cached_dep)
9189
return cached_dep
9290

93-
def _do_dependency(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: DoSubproject) -> T.Optional[Dependency]:
91+
def _do_dependency(self, kwargs: DependencyObjectKWs, name: str, func_kwargs: DoSubproject) -> T.Optional[Dependency]:
9492
# Note that there is no df.dependency() method, this is called for names
9593
# given as positional arguments to dependency_fallbacks(name1, ...).
9694
# We use kwargs from the dependency() function, for things like version,
9795
# module, etc.
98-
name = func_args[0]
9996
self._handle_featurenew_dependencies(name)
10097
dep = dependencies.find_external_dependency(name, self.environment, kwargs)
10198
if dep.found():
102-
for_machine = T.cast('MachineChoice', kwargs['native'])
99+
for_machine = kwargs.get('native', MachineChoice.HOST)
103100
identifier = dependencies.get_dep_identifier(name, kwargs)
104101
self.coredata.deps[for_machine].put(identifier, dep)
105102
return dep
106103
return None
107104

108-
def _do_existing_subproject(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: DoSubproject) -> T.Optional[Dependency]:
109-
subp_name = func_args[0]
105+
def _do_existing_subproject(self, kwargs: DependencyObjectKWs, subp_name: str, func_kwargs: DoSubproject) -> T.Optional[Dependency]:
110106
varname = self.subproject_varname
111107
if subp_name and self._get_subproject(subp_name):
112108
return self._get_subproject_dep(subp_name, varname, kwargs)
113109
return None
114110

115-
def _do_subproject(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs: DoSubproject) -> T.Optional[Dependency]:
111+
def _do_subproject(self, kwargs: DependencyObjectKWs, name: str, func_kwargs: DoSubproject) -> T.Optional[Dependency]:
116112
if self.forcefallback:
117113
mlog.log('Looking for a fallback subproject for the dependency',
118114
mlog.bold(self._display_name), 'because:\nUse of fallback dependencies is forced.')
@@ -127,7 +123,7 @@ def _do_subproject(self, kwargs: TYPE_nkwargs, func_args: TYPE_nvar, func_kwargs
127123
# dependency('foo', static: true) should implicitly add
128124
# default_options: ['default_library=static']
129125
static = kwargs.get('static')
130-
forced_options = {}
126+
forced_options: OptionDict = {}
131127
if static is not None:
132128
default_library = 'static' if static else 'shared'
133129
mlog.log(f'Building fallback subproject with default_library={default_library}')
@@ -145,7 +141,7 @@ def _get_subproject(self, subp_name: str) -> T.Optional[SubprojectHolder]:
145141
return sub
146142
return None
147143

148-
def _get_subproject_dep(self, subp_name: str, varname: str, kwargs: TYPE_nkwargs) -> T.Optional[Dependency]:
144+
def _get_subproject_dep(self, subp_name: str, varname: str, kwargs: DependencyObjectKWs) -> T.Optional[Dependency]:
149145
# Verify the subproject is found
150146
subproject = self._get_subproject(subp_name)
151147
if not subproject:
@@ -208,12 +204,12 @@ def _get_subproject_dep(self, subp_name: str, varname: str, kwargs: TYPE_nkwargs
208204
mlog.normal_cyan(found) if found else None)
209205
return var_dep
210206

211-
def _get_cached_dep(self, name: str, kwargs: TYPE_nkwargs) -> T.Optional[Dependency]:
207+
def _get_cached_dep(self, name: str, kwargs: DependencyObjectKWs) -> T.Optional[Dependency]:
212208
# Unlike other methods, this one returns not-found dependency instead
213209
# of None in the case the dependency is cached as not-found, or if cached
214210
# version does not match. In that case we don't want to continue with
215211
# other candidates.
216-
for_machine = T.cast('MachineChoice', kwargs['native'])
212+
for_machine = kwargs.get('native', MachineChoice.HOST)
217213
identifier = dependencies.get_dep_identifier(name, kwargs)
218214
wanted_vers = stringlistify(kwargs.get('version', []))
219215

@@ -300,28 +296,30 @@ def _get_candidates(self) -> T.List[CandidateType]:
300296
candidates: T.List[CandidateType] = []
301297
# 1. check if any of the names is cached already.
302298
for name in self.names:
303-
candidates.append((self._do_dependency_cache, [name]))
299+
candidates.append((self._do_dependency_cache, name))
304300
# 2. check if the subproject fallback has already been configured.
305301
if self.subproject_name:
306-
candidates.append((self._do_existing_subproject, [self.subproject_name]))
302+
candidates.append((self._do_existing_subproject, self.subproject_name))
307303
# 3. check external dependency if we are not forced to use subproject
308304
if not self.forcefallback or not self.subproject_name:
309305
for name in self.names:
310-
candidates.append((self._do_dependency, [name]))
306+
candidates.append((self._do_dependency, name))
311307
# 4. configure the subproject
312308
if self.subproject_name:
313-
candidates.append((self._do_subproject, [self.subproject_name]))
309+
candidates.append((self._do_subproject, self.subproject_name))
314310
return candidates
315311

316-
def lookup(self, kwargs: TYPE_nkwargs, force_fallback: bool = False) -> Dependency:
312+
def lookup(self, kwargs: DependencyObjectKWs, force_fallback: bool = False) -> Dependency:
317313
mods = kwargs.get('modules', [])
318314
if mods:
319315
self._display_name += ' (modules: {})'.format(', '.join(str(i) for i in mods))
320316

321-
required = T.cast('bool', kwargs.get('required', True))
317+
required = kwargs.get('required', True)
322318

323319
# Check if usage of the subproject fallback is forced
324-
wrap_mode = WrapMode.from_string(self.coredata.optstore.get_value_for(OptionKey('wrap_mode')))
320+
_wm = self.coredata.optstore.get_value_for(OptionKey('wrap_mode'))
321+
assert isinstance(_wm, str), 'for mypy'
322+
wrap_mode = WrapMode.from_string(_wm)
325323
force_fallback_for = self.coredata.optstore.get_value_for(OptionKey('force_fallback_for'))
326324
assert isinstance(force_fallback_for, list), 'for mypy'
327325
self.nofallback = wrap_mode == WrapMode.nofallback
@@ -354,21 +352,21 @@ def lookup(self, kwargs: TYPE_nkwargs, force_fallback: bool = False) -> Dependen
354352
# Try all candidates, only the last one is really required.
355353
last = len(candidates) - 1
356354
for i, item in enumerate(candidates):
357-
func, func_args = item
355+
func, name = item
356+
kwargs['required'] = required and (i == last)
358357
func_kwargs: DoSubproject = {
359-
'required': required and (i == last),
358+
'required': kwargs['required'],
360359
'cmake_options': [],
361360
'default_options': self.default_options,
362361
'options': None,
363362
'version': [],
364363
}
365-
kwargs['required'] = required and (i == last)
366-
dep = func(kwargs, func_args, func_kwargs)
364+
dep = func(kwargs, name, func_kwargs)
367365
if dep and dep.found():
368366
# Override this dependency to have consistent results in subsequent
369367
# dependency lookups.
370368
for name in self.names:
371-
for_machine = T.cast('MachineChoice', kwargs['native'])
369+
for_machine = kwargs.get('native', MachineChoice.HOST)
372370
identifier = dependencies.get_dep_identifier(name, kwargs)
373371
if identifier not in self.build.dependency_overrides[for_machine]:
374372
self.build.dependency_overrides[for_machine][identifier] = \

run_mypy.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
'mesonbuild/envconfig.py',
3636
'mesonbuild/environment.py',
3737
'mesonbuild/interpreter/compiler.py',
38+
'mesonbuild/interpreter/dependencyfallbacks.py',
3839
'mesonbuild/interpreter/mesonmain.py',
3940
'mesonbuild/interpreter/interpreterobjects.py',
4041
'mesonbuild/interpreter/type_checking.py',

0 commit comments

Comments
 (0)