|
|
|
@ -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).') |
|
|
|
|
|
|
|
|
|