Skip to content

Commit 43c6031

Browse files
eli-schwartzjpakkane
authored andcommitted
python module: cache dependency() lookup between invocations
Modeled similarly after the installations cache, but using the coredata dependency cache because it has a nice mechanism for handling the cache key.
1 parent ea95296 commit 43c6031

File tree

1 file changed

+26
-14
lines changed

1 file changed

+26
-14
lines changed

mesonbuild/modules/python.py

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
from __future__ import annotations
1415

1516
from pathlib import Path
1617
import functools
@@ -26,6 +27,7 @@
2627
from ..build import known_shmod_kwargs
2728
from ..dependencies import DependencyMethods, PkgConfigDependency, NotFoundDependency, SystemDependency, ExtraFrameworkDependency
2829
from ..dependencies.base import process_method_kw
30+
from ..dependencies.detect import get_dep_identifier
2931
from ..environment import detect_cpu_family
3032
from ..interpreter import ExternalProgramHolder, extract_required_kwarg, permitted_dependency_kwargs
3133
from ..interpreter.type_checking import NoneType
@@ -539,31 +541,41 @@ def extension_module_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs
539541

540542
return self.interpreter.func_shared_module(None, args, kwargs)
541543

544+
def _dependency_method_impl(self, kwargs: TYPE_kwargs) -> Dependency:
545+
for_machine = self.interpreter.machine_from_native_kwarg(kwargs)
546+
identifier = get_dep_identifier(self._full_path(), kwargs)
547+
548+
dep = self.interpreter.coredata.deps[for_machine].get(identifier)
549+
if dep is not None:
550+
return dep
551+
552+
new_kwargs = kwargs.copy()
553+
new_kwargs['required'] = False
554+
methods = process_method_kw({DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM}, kwargs)
555+
# it's theoretically (though not practically) possible to not bind dep, let's ensure it is.
556+
dep: Dependency = NotFoundDependency('python', self.interpreter.environment)
557+
for d in python_factory(self.interpreter.environment, for_machine, new_kwargs, methods, self):
558+
dep = d()
559+
if dep.found():
560+
break
561+
562+
self.interpreter.coredata.deps[for_machine].put(identifier, dep)
563+
return dep
564+
542565
@disablerIfNotFound
543566
@permittedKwargs(permitted_dependency_kwargs | {'embed'})
544567
@FeatureNewKwargs('python_installation.dependency', '0.53.0', ['embed'])
545568
@noPosargs
546569
def dependency_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> 'Dependency':
547570
disabled, required, feature = extract_required_kwarg(kwargs, self.subproject)
548-
# it's theoretically (though not practically) possible for the else clse
549-
# to not bind dep, let's ensure it is.
550-
dep: 'Dependency' = NotFoundDependency('python', self.interpreter.environment)
551571
if disabled:
552572
mlog.log('Dependency', mlog.bold('python'), 'skipped: feature', mlog.bold(feature), 'disabled')
573+
return NotFoundDependency('python', self.interpreter.environment)
553574
else:
554-
new_kwargs = kwargs.copy()
555-
new_kwargs['required'] = False
556-
methods = process_method_kw({DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM}, kwargs)
557-
for d in python_factory(self.interpreter.environment,
558-
MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST,
559-
new_kwargs, methods, self):
560-
dep = d()
561-
if dep.found():
562-
break
575+
dep = self._dependency_method_impl(kwargs)
563576
if required and not dep.found():
564577
raise mesonlib.MesonException('Python dependency not found')
565-
566-
return dep
578+
return dep
567579

568580
@typed_pos_args('install_data', varargs=(str, mesonlib.File))
569581
@typed_kwargs('python_installation.install_sources', _PURE_KW, _SUBDIR_KW,

0 commit comments

Comments
 (0)