Subject: [bug#54412] [PATCH] python: use the posix_prefix sysconfig scheme on Debian

From: Karl Berry <[email-masked]>
Date: Wed, 17 Jan 2024 15:48:30 -0700

Gianfranoc, Stefano - thanks much for the patch wrt Automake and Debian
Python posix_local vs. posix_prefix. Below is what I installed -- the
code change is substantively the same as what you wrote; I just took the
extra try..catch that Bogdan added.

I changed the paragraph in the manual about pythondir. If you could look
at it, that would be great. Is it correct that the basic idea is that,
with this change, Automake again follows --prefix (and related) + using
site-packages instead of Debian's defaults of /usr/local and
dist-packages? --thanks, karl.

-------------------------------------------------------------------------------
python: use posix_prefix instead of posix_local on Debian.

>From https://debbugs.gnu.org/cgi/bugreport.cgi?bug=54412#17.
(Patch slightly adapted by Bogdan from original by Gianfranco,
as posted by Stefano Rivera in message#14.)

* m4/python.m4 (AM_PATH_PYTHON): replace Debian's posix_local
scheme with posix_prefix.
* doc/automake.texi (Python) <pythondir>: say a bit more.
* NEWS: mention this.
diff --git a/NEWS b/NEWS
index c53573a0a..2b2da0908 100644
--- a/NEWS
+++ b/NEWS
+  - The installation directory for Python files again defaults to
+    "site-packages" under the usual installation prefix, even on systems
+    (generally Debian-based) that would normally use the "dist-packages"
+    subdirectory under /usr/local. (bug#54412, bug#64837)
+
   - When compiling Emacs Lisp files, emacs is run with --no-site-file to
     disable user config files that might hang or access the terminal;
     and -Q is not used, since its support and behavior varies. (bug#58102)
diff --git a/doc/automake.texi b/doc/automake.texi
index c63279a9e..ecefe2dc6 100644
--- a/doc/automake.texi
+++ b/doc/automake.texi
@@ -7987,8 +7987,18 @@ building Python extensions.

 @item pythondir
 @cindex @file{site-packages} Python directory
-The directory name for the @file{site-packages} subdirectory of the
-standard Python install tree.
+@cindex @file{dist-packages} Python directory
+The subdirectory of the Python install tree in which to install Python
+scripts. By default this is, on all systems,
+@file{$PYTHON_PREFIX/lib/python@var{version}/site-packages}, where
+@code{$PYTHON_PREFIX} is described above, and @var{version} is the
+Python version.  (For those knowledgeable about Python installation
+details: systems generally have their own Python installation scheme,
+such as @code{posix_local} on Debian and related (as of
+Python@tie{}3.10), which ends up using a directory named
+@file{dist-packages}; Automake uses the @code{posix_prefix} scheme and
+@file{site-packages}.)
+@c https://bugs.gnu.org/54412 et al.

 @item pkgpythondir
 This is the directory under @code{pythondir} that is named after the
diff --git a/m4/python.m4 b/m4/python.m4
index 2de57c52a..f90c73d93 100644
--- a/m4/python.m4
+++ b/m4/python.m4
@@ -243,9 +243,9 @@ except ImportError:

   dnl 1. pythondir: where to install python scripts.  This is the
   dnl    site-packages directory, not the python standard library
-  dnl    directory like in previous automake betas.  This behavior
+  dnl    directory as in early automake betas.  This behavior
   dnl    is more consistent with lispdir.m4 for example.
-  dnl Query distutils for this directory.
+  dnl Query sysconfig or distutils (per above) for this directory.
   dnl
   AC_CACHE_CHECK([for $am_display_PYTHON script directory (pythondir)],
   [am_cv_python_pythondir],
@@ -257,7 +257,19 @@ except ImportError:
    am_cv_python_pythondir=`$PYTHON -c "
 $am_python_setup_sysconfig
 if can_use_sysconfig:
-  sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
+  try:
+    if hasattr(sysconfig, 'get_default_scheme'):
+      scheme = sysconfig.get_default_scheme()
+    else:
+      scheme = sysconfig._get_default_scheme()
+    if scheme == 'posix_local':
+      # Debian's default scheme installs to /usr/local/ but we want to
+      # follow the prefix, as we always have.
+      # See bugs#54412, #64837, et al.
+      scheme = 'posix_prefix'
+    sitedir = sysconfig.get_path('purelib', scheme, vars={'base':'$am_py_prefix'})
+  except:
+    sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
 else:
   from distutils import sysconfig
   sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
@@ -287,7 +299,7 @@ sys.stdout.write(sitedir)"`

   dnl 3. pyexecdir: directory for installing python extension modules
   dnl    (shared libraries).
-  dnl Query distutils for this directory.
+  dnl Query sysconfig or distutils for this directory.
   dnl
   AC_CACHE_CHECK([for $am_display_PYTHON extension module directory (pyexecdir)],
   [am_cv_python_pyexecdir],
@@ -299,7 +311,17 @@ sys.stdout.write(sitedir)"`
    am_cv_python_pyexecdir=`$PYTHON -c "
 $am_python_setup_sysconfig
 if can_use_sysconfig:
-  sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_exec_prefix'})
+  try:
+    if hasattr(sysconfig, 'get_default_scheme'):
+      scheme = sysconfig.get_default_scheme()
+    else:
+      scheme = sysconfig._get_default_scheme()
+    if scheme == 'posix_local':
+      # See scheme comments above.
+      scheme = 'posix_prefix'
+    sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'})
+  except:
+    sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_exec_prefix'})
 else:
   from distutils import sysconfig
   sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix')

compile finished at Wed Jan 17 14:46:23 2024