aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/modules
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2022-02-23 14:38:05 -0500
committerXavier Claessens <xclaesse@gmail.com>2022-02-28 09:03:27 -0500
commitc5c02b72e132a03ae0284bdd5e15d1675301a37d (patch)
tree48b66a69567caf0564843a5091679e02d56052ac /mesonbuild/modules
parent7a926d8dff2c161877f26b0ccce21800908893c1 (diff)
downloadmeson-c5c02b72e132a03ae0284bdd5e15d1675301a37d.zip
meson-c5c02b72e132a03ae0284bdd5e15d1675301a37d.tar.gz
meson-c5c02b72e132a03ae0284bdd5e15d1675301a37d.tar.bz2
Cache the result of python.find_installation()
This avoids running sanity checks everytime find_installation() is called.
Diffstat (limited to 'mesonbuild/modules')
-rw-r--r--mesonbuild/modules/python.py63
1 files changed, 34 insertions, 29 deletions
diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py
index a91ec58..5b91efc 100644
--- a/mesonbuild/modules/python.py
+++ b/mesonbuild/modules/python.py
@@ -637,6 +637,7 @@ class PythonModule(ExtensionModule):
@FeatureNew('Python Module', '0.46.0')
def __init__(self, interpreter: 'Interpreter') -> None:
super().__init__(interpreter)
+ self.installations: T.Dict[str, ExternalProgram] = {}
self.methods.update({
'find_installation': self.find_installation,
})
@@ -658,6 +659,31 @@ class PythonModule(ExtensionModule):
else:
return None
+ def _find_installation_impl(self, state: 'ModuleState', display_name: str, name_or_path: str) -> ExternalProgram:
+ if not name_or_path:
+ python = PythonExternalProgram('python3', mesonlib.python_command)
+ else:
+ tmp_python = ExternalProgram.from_entry(display_name, name_or_path)
+ python = PythonExternalProgram(display_name, ext_prog=tmp_python)
+
+ if not python.found() and mesonlib.is_windows():
+ pythonpath = self._get_win_pythonpath(name_or_path)
+ if pythonpath is not None:
+ name_or_path = pythonpath
+ python = PythonExternalProgram(name_or_path)
+
+ # Last ditch effort, python2 or python3 can be named python
+ # on various platforms, let's not give up just yet, if an executable
+ # named python is available and has a compatible version, let's use
+ # it
+ if not python.found() and name_or_path in ['python2', 'python3']:
+ python = PythonExternalProgram('python')
+
+ if python.found() and not python.sanity(state):
+ python = NonExistingExternalProgram()
+
+ return python
+
@disablerIfNotFound
@typed_pos_args('python.find_installation', optargs=[str])
@typed_kwargs(
@@ -670,9 +696,6 @@ class PythonModule(ExtensionModule):
kwargs: 'FindInstallationKw') -> ExternalProgram:
feature_check = FeatureNew('Passing "feature" option to find_installation', '0.48.0')
disabled, required, feature = extract_required_kwarg(kwargs, state.subproject, feature_check)
- want_modules = kwargs['modules']
- found_modules: T.List[str] = []
- missing_modules: T.List[str] = []
# FIXME: this code is *full* of sharp corners. It assumes that it's
# going to get a string value (or now a list of length 1), of `python2`
@@ -691,25 +714,14 @@ class PythonModule(ExtensionModule):
mlog.log('Program', name_or_path or 'python', 'found:', mlog.red('NO'), '(disabled by:', mlog.bold(feature), ')')
return NonExistingExternalProgram()
- if not name_or_path:
- python = PythonExternalProgram('python3', mesonlib.python_command)
- else:
- tmp_python = ExternalProgram.from_entry(display_name, name_or_path)
- python = PythonExternalProgram(display_name, ext_prog=tmp_python)
-
- if not python.found() and mesonlib.is_windows():
- pythonpath = self._get_win_pythonpath(name_or_path)
- if pythonpath is not None:
- name_or_path = pythonpath
- python = PythonExternalProgram(name_or_path)
-
- # Last ditch effort, python2 or python3 can be named python
- # on various platforms, let's not give up just yet, if an executable
- # named python is available and has a compatible version, let's use
- # it
- if not python.found() and name_or_path in ['python2', 'python3']:
- python = PythonExternalProgram('python')
+ python = self.installations.get(name_or_path)
+ if not python:
+ python = self._find_installation_impl(state, display_name, name_or_path)
+ self.installations[name_or_path] = python
+ want_modules = kwargs['modules']
+ found_modules: T.List[str] = []
+ missing_modules: T.List[str] = []
if python.found() and want_modules:
for mod in want_modules:
p, *_ = mesonlib.Popen_safe(
@@ -743,14 +755,7 @@ class PythonModule(ExtensionModule):
raise mesonlib.MesonException('{} is missing modules: {}'.format(name_or_path or 'python', ', '.join(missing_modules)))
return NonExistingExternalProgram()
else:
- sane = python.sanity(state)
-
- if sane:
- return python
- else:
- if required:
- raise mesonlib.MesonException(f'{python} is not a valid python or it is missing distutils')
- return NonExistingExternalProgram()
+ return python
raise mesonlib.MesonBugException('Unreachable code was reached (PythonModule.find_installation).')