From 18d07c064c7a05ad51147454696bb17ff8384726 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 17 Aug 2021 17:02:26 -0400 Subject: [PATCH] python module: make external program wrapper have access to useful metadata Basically just reorganize code. Try to make it a little neater, while we're at it. (cherry picked from commit d9a9c3b5dadd7a132bd221b7d2b4f84c0f0edb13) --- mesonbuild/modules/python.py | 59 +++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py index a77429f7e..25ce81271 100644 --- a/mesonbuild/modules/python.py +++ b/mesonbuild/modules/python.py @@ -309,12 +309,43 @@ class PythonExternalProgram(ExternalProgram): 'version': '0.0', } + def _check_version(self, version: str) -> bool: + if self.name == 'python2': + return mesonlib.version_compare(version, '< 3.0') + elif self.name == 'python3': + return mesonlib.version_compare(version, '>= 3.0') + return True + + def sanity(self) -> bool: + # Sanity check, we expect to have something that at least quacks in tune + cmd = self.get_command() + ['-c', INTROSPECT_COMMAND] + p, stdout, stderr = mesonlib.Popen_safe(cmd) + try: + info = json.loads(stdout) + except json.JSONDecodeError: + info = None + mlog.debug('Could not introspect Python (%s): exit code %d' % (str(p.args), p.returncode)) + mlog.debug('Program stdout:\n') + mlog.debug(stdout) + mlog.debug('Program stderr:\n') + mlog.debug(stderr) + + if info is not None and self._check_version(info['version']): + variables = info['variables'] + info['suffix'] = variables.get('EXT_SUFFIX') or variables.get('SO') or variables.get('.so') + self.info = T.cast('PythonIntrospectionDict', info) + return True + else: + return False + + class PythonInstallation(ExternalProgramHolder): def __init__(self, python, interpreter): ExternalProgramHolder.__init__(self, python, interpreter) info = python.info prefix = self.interpreter.environment.coredata.get_option(mesonlib.OptionKey('prefix')) self.variables = info['variables'] + self.suffix = info['suffix'] self.paths = info['paths'] install_paths = info['install_paths'] self.platlib_install_path = os.path.join(prefix, install_paths['platlib'][1:]) @@ -360,11 +391,9 @@ class PythonInstallation(ExternalProgramHolder): new_deps.append(dep) kwargs['dependencies'] = new_deps - suffix = self.variables.get('EXT_SUFFIX') or self.variables.get('SO') or self.variables.get('.so') - # msys2's python3 has "-cpython-36m.dll", we have to be clever # FIXME: explain what the specific cleverness is here - split, suffix = suffix.rsplit('.', 1) + split, suffix = self.suffix.rsplit('.', 1) args[0] += split kwargs['name_prefix'] = '' @@ -518,12 +547,6 @@ class PythonModule(ExtensionModule): else: return None - def _check_version(self, name_or_path, version): - if name_or_path == 'python2': - return mesonlib.version_compare(version, '< 3.0') - elif name_or_path == 'python3': - return mesonlib.version_compare(version, '>= 3.0') - return True @FeatureNewKwargs('python.find_installation', '0.49.0', ['disabler']) @FeatureNewKwargs('python.find_installation', '0.51.0', ['modules']) @@ -603,21 +626,9 @@ class PythonModule(ExtensionModule): raise mesonlib.MesonException('{} is missing modules: {}'.format(name_or_path or 'python', ', '.join(missing_modules))) return NonExistingExternalProgram() else: - # Sanity check, we expect to have something that at least quacks in tune - try: - cmd = python.get_command() + ['-c', INTROSPECT_COMMAND] - p, stdout, stderr = mesonlib.Popen_safe(cmd) - info = json.loads(stdout) - except json.JSONDecodeError: - info = None - mlog.debug('Could not introspect Python (%s): exit code %d' % (str(p.args), p.returncode)) - mlog.debug('Program stdout:\n') - mlog.debug(stdout) - mlog.debug('Program stderr:\n') - mlog.debug(stderr) - - if isinstance(info, dict) and 'version' in info and self._check_version(name_or_path, info['version']): - python.info = info + sane = python.sanity() + + if sane: return python else: if required: