Skip to content

Commit

Permalink
Remove deprecated use of distutils, fix for Python 3.12+
Browse files Browse the repository at this point in the history
This switches to using sysconfig from distutils, which is necessary for
Python 3.12+ since distutils is deprecated and has been removed.

It is necessary to specify the install scheme when a prefix other than
the Python default is used so that changes to the default scheme made by
distributions (e.g. Debian, Fedora) do not produce an incorrect Python
installation directory. For example, Debian patches the default scheme
to prepend the path with '/local', but if a user specifies a prefix of
'/usr/local', then the path using the default scheme would be
'/usr/local/local/...' with a duplicated 'local' directory. Specifying
an unmodified install scheme fixes that.

Signed-off-by: Ryan Volz <ryan.volz@gmail.com>
  • Loading branch information
ryanvolz committed Sep 27, 2023
1 parent bb33b2d commit 1ee5670
Showing 1 changed file with 25 additions and 11 deletions.
36 changes: 25 additions & 11 deletions swig/python/get_python_lib.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
import os
import pathlib
import sys
import site
from distutils.sysconfig import get_python_lib
import sysconfig

if __name__ == '__main__':
prefix = sys.argv[1]
prefix = pathlib.Path(sys.argv[1]).resolve()

#ask distutils where to install the python module
install_dir = get_python_lib(plat_specific=True, prefix=prefix)
# default install dir for the running Python interpreter
default_install_dir = pathlib.Path(sysconfig.get_path('platlib')).resolve()

#use sites when the prefix is already recognized
# if default falls under the desired prefix, we're done
try:
paths = [p for p in site.getsitepackages() if p.startswith(prefix)]
if len(paths) == 1: install_dir = paths[0]
except AttributeError: pass
relative_install_dir = default_install_dir.relative_to(prefix)
except ValueError:
# get install dir for the specified prefix
# can't use the default scheme because distributions modify it
# newer Python versions have 'venv' scheme, use for all OSs.
if 'venv' in sysconfig.get_scheme_names():
scheme = 'venv'
elif os.name == 'nt':
scheme = 'nt'
else:
scheme = 'posix_prefix'
prefix_install_dir = pathlib.Path(sysconfig.get_path(
'platlib',
scheme=scheme,
vars={'base': prefix, 'platbase': prefix},
)).resolve()
relative_install_dir = prefix_install_dir.relative_to(prefix)

#strip the prefix to return a relative path
print(os.path.relpath(install_dir, prefix))
# want a relative path for use in the build system
print(relative_install_dir)

0 comments on commit 1ee5670

Please # to comment.