From dccf59bcbf244d07cb5b7454e6991eac22980031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Tue, 21 Sep 2021 19:52:55 +0100 Subject: [PATCH] modules: python: better handling of the Python paths for Debian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hardcoding the name is fragile, and enabling it based on the existence of /etc/debian_version (as the is_debianlike helper does) will result in incorrect paths if the Python binary is not provided by Debian. Using the deb_system sysconfig scheme instead makes sure we use the install path from the current interpreter, which Debian could change between releases, and gives us the correct value on Python installations that are not provided by Debian (eg. deadsnakes, Github Action Python, etc.) Do notice, though, that there is still no guarantee that these are the correct paths, as they assume all schemes paths have the install prefix as a base, see #9284. Signed-off-by: Filipe LaĆ­ns --- mesonbuild/modules/python.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py index 57cea91b5e77..0037e2d984dc 100644 --- a/mesonbuild/modules/python.py +++ b/mesonbuild/modules/python.py @@ -280,7 +280,18 @@ def set_env(name, value): import json import sys -install_paths = sysconfig.get_paths(vars={'base': '', 'platbase': '', 'installed_base': ''}) +# On Debian derivatives, the Python interpreter shipped by the distribution uses +# a custom install scheme, deb_system, for the system install, and changes the +# default scheme to a custom one pointing to /usr/local and replacing +# site-packages with dist-packages. +# See https://github.com/mesonbuild/meson/issues/8739. +empty_vars = {'base': '', 'platbase': '', 'installed_base': ''} +if 'deb_system' in sysconfig.get_scheme_names(): + paths = sysconfig.get_paths('deb_system') + install_paths = sysconfig.get_paths('deb_system', vars=empty_vars) +else: + paths = sysconfig.get_paths() + install_paths = sysconfig.get_paths(vars=empty_vars) def links_against_libpython(): from distutils.core import Distribution, Extension @@ -290,7 +301,7 @@ def links_against_libpython(): print(json.dumps({ 'variables': sysconfig.get_config_vars(), - 'paths': sysconfig.get_paths(), + 'paths': paths, 'install_paths': install_paths, 'sys_paths': sys.path, 'version': sysconfig.get_python_version(), @@ -373,14 +384,9 @@ def _get_path(self, key: str) -> None: sys_paths = self.info['sys_paths'] rel_path = self.info['install_paths'][key][1:] if not any(p.endswith(rel_path) for p in sys_paths if not p.startswith(user_dir)): - # On Debian derivatives sysconfig install path is broken and is not - # included in the locations python actually lookup. - # See https://github.com/mesonbuild/meson/issues/8739. mlog.warning('Broken python installation detected. Python files', 'installed by Meson might not be found by python interpreter.', once=True) - if mesonlib.is_debianlike(): - rel_path = 'lib/python3/dist-packages' return rel_path