Control: tags -1 + patch

The Technical Committee was recently asked about this bug report,
in #1026104. That was not an actionable report for the TC because no
concrete alternative had been proposed, but it prompted me to follow up
on this in my non-TC role as an ordinary Debian developer.

On Mon, 23 Nov 2020 at 12:18:40 -0500, Sandro Tosi wrote:
> > Maybe they can be relaxed to Recommends or Suggests or something, if
> > "I installed this package while python3.9 was the default, and I can't
> > run f2py3.8" would be wishlist/wontfix rather than RC.
> 
> numpy provides compiled extensions for all supported python3 versions,
> so it has to depend on all of them since an extension compiled for 3.8
> (as an example) needs to have a 3.8 runtime environment available to
> be able to be imported and used; and so for all the other versions.
> this is by design and wont change.

There is an important difference between numpy and other packages that
provide compiled extensions, though: normally, if another package
provides compiled extensions for both python3.11 and python3.10 during
the 3.10 -> 3.11 transition, dh-python will give us a dependency on:

    python3 (>= 3.10~), python3 (<< 3.12)

For example, python3-dbus is currently in that state. If python3-numpy
looked more like this, then I would consider #945824 to have been solved.

The key difference between python3-dbus and python3-numpy is that
in addition to a Python library, numpy also provides some CLI
tools (the /usr/bin/f2py* family), and some of those tools
are installed with version-specific names and a shebang line like
"#!/usr/bin/python3.11". *That*, and not the extension module, is why
dh-python generates a version-specific dependency on each of python3.10
and python3.11 at the moment.

It is entirely possible to avoid that dependency without modifying or
avoiding dh-python. Please see the attached patches 0001 and 0002 for
a proposed implementation of this, also available at
<https://salsa.debian.org/python-team/packages/numpy/-/merge_requests/5>.
During the python3.10 -> python3.11 transition, it generates this
dependency, which would be satisfied by whichever of python3.10 or
python3.11 is currently the default:

     Depends: python3-pkg-resources, python3 (<< 3.12), python3 (>= 3.10~), 
python3:any, libblas3 | libblas.so.3, libc6 (>= 2.35), liblapack3 | 
liblapack.so.3

That's similar to what happens in other compiled extensions like
python3-dbus, and seems ideal to me.

Patch 0002 makes the conservative assumption that the f2py3.x scripts
might have non-trivial differences in a future version, and might not
just be generated entry point wrappers with essentially the same content.
If you are confident that the f2py3.x scripts will continue to be
functionally equivalent except for their shebang lines (which seems a
reasonably safe assumption to me, but I don't know numpy well), then
patch 0003 could additionally be applied, as a simplification. This is
also available at
<https://salsa.debian.org/python-team/packages/numpy/-/merge_requests/6>.

Outside numpy, it looks like python3-coverage could also benefit from this
technique.

Other than python3-numpy, python3-coverage and the python3-all*
metapackages, I believe the only package in unstable that depends on both
python3.10 and python3.11 is python3-dbus-tests, which exists to provide
autopkgtest coverage and is not intended to be installed by end-users
(so I think the extra dependency is a non-issue there, and arguably even a
positive thing).

    smcv
>From 6b07e7acae1b329d0749bb19bb5193935129c120 Mon Sep 17 00:00:00 2001
From: Simon McVittie <s...@debian.org>
Date: Wed, 11 Jan 2023 11:04:28 +0000
Subject: [PATCH 1/3] d/control: Add Suggests on python3-all-dev

Each of the f2py3.x scripts needs python3.x-dev, and the python3-all-dev
metapackage is an easy way to install those packages for all currently
supported Python versions.
---
 debian/control | 1 +
 1 file changed, 1 insertion(+)

diff --git a/debian/control b/debian/control
index 6d723b4a..2ed14660 100644
--- a/debian/control
+++ b/debian/control
@@ -30,6 +30,7 @@ Depends: python3-pkg-resources,
          ${shlibs:Depends},
 Suggests: gcc,
           gfortran,
+          python3-all-dev,
           python3-dev,
           python3-pytest,
 Provides: dh-sequence-numpy3,
-- 
2.39.0

>From 0466e388242f3c8c03df66a38da490006ebb3a8f Mon Sep 17 00:00:00 2001
From: Simon McVittie <s...@debian.org>
Date: Wed, 11 Jan 2023 11:16:40 +0000
Subject: [PATCH 2/3] Avoid hard dependency on supported-but-non-default Python
 interpreters

Each of the f2py3.x scripts is intended to be run by a corresponding
python3.x interpreter, but if we install them in the simplest possible
way, dh-python will generate a hard dependency on every supported
interpreter during each transitional period in which more than one
version is supported.

Instead, install the version-specific Python scripts into /usr/libexec,
and use wrapper scripts in /usr/bin to display an error message if the
intended interpreter is not currently installed.

Closes: #945824
---
 debian/f2py.in               | 14 ++++++++++++++
 debian/python3-numpy.install |  2 +-
 debian/rules                 | 14 +++++++++++---
 3 files changed, 26 insertions(+), 4 deletions(-)
 create mode 100644 debian/f2py.in

diff --git a/debian/f2py.in b/debian/f2py.in
new file mode 100644
index 00000000..abd154c6
--- /dev/null
+++ b/debian/f2py.in
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+set -e
+
+if [ -x /usr/bin/python@VERSION@ ]; then
+    exec /usr/bin/python@VERSION@ /usr/libexec/f2py@VERSION@ "$@"
+fi
+
+cat >&2 <<EOF
+f2py@VERSION@: error: python@VERSION@ is not installed.
+Please run f2py or f2py3 instead, or install the python@VERSION@ package.
+EOF
+
+exit 1
diff --git a/debian/python3-numpy.install b/debian/python3-numpy.install
index b39b57e5..7c36cb4c 100644
--- a/debian/python3-numpy.install
+++ b/debian/python3-numpy.install
@@ -2,7 +2,7 @@ debian/dh_numpy3 usr/bin
 debian/numpy3.pm usr/share/perl5/Debian/Debhelper/Sequence/
 debian/versions usr/share/numpy3/
 usr/bin/f2py3
-usr/bin/f2py3.*
+usr/bin/f2py3.* usr/libexec
 usr/lib/python3*/*-packages/*.egg-info
 usr/lib/python3*/*-packages/*/*.py
 usr/lib/python3*/*-packages/*/*/*.cpython-3?[!d][!d]*.so
diff --git a/debian/rules b/debian/rules
index 43b2ec15..30119b75 100755
--- a/debian/rules
+++ b/debian/rules
@@ -48,12 +48,14 @@ override_dh_python3:
 	fi
 
 override_dh_install:
-	# add shebang information to f2py script
+	# We use #!/usr/bin/python3 so that dh-python won't generate a
+	# dependency on each of the interpreters. A wrapper script generated
+	# from debian/f2py.in is responsible for using the correct
+	# interpreter if available, or showing an error message.
 	set -e; for v in $(PY3VERS); do \
-		sed -i "1s,#!.*python[^ ]*\(.*\),#!/usr/bin/python$$v," debian/tmp/usr/bin/f2py$$v; \
+		sed -i "1s,#!.*python[^ ]*\(.*\),#!/usr/bin/python3," debian/tmp/usr/bin/f2py$$v; \
 	done
 	cp -a debian/tmp/usr/bin/f2py$(PY3DEF) debian/tmp/usr/bin/f2py3
-	sed -i "1s,#!.*python[^ ]*\(.*\),#!/usr/bin/python3," debian/tmp/usr/bin/f2py3
 
 	# install numpy.i into the include directory
 	cp -a tools/swig/numpy.i debian/tmp/usr/lib/python3/dist-packages/numpy/core/include/numpy
@@ -67,6 +69,12 @@ override_dh_install:
 		mkdir -p $(CURDIR)/debian/python3-numpy/usr/include/python$$i$$ABITAG; \
 		dh_link -ppython3-numpy usr/lib/python3/dist-packages/numpy/core/include/numpy usr/include/python$$i$$ABITAG/numpy; \
 	done
+	# Create wrappers to run python$$i without dh-python generating a
+	# hard dependency on all of those interpreters (#945824)
+	set -e; for i in $(PY3VERS); do \
+	sed -e "s,@VERSION@,$$i,g" debian/f2py.in > "debian/python3-numpy/usr/bin/f2py$$i"; \
+	chmod 0755 "debian/python3-numpy/usr/bin/f2py$$i"; \
+	done
 
 override_dh_gencontrol:
 	python3 debian/versions3.helper >> debian/python3-numpy.substvars
-- 
2.39.0

>From 81e830a057d6364c3d102ec9d511bb6fda051fcd Mon Sep 17 00:00:00 2001
From: Simon McVittie <s...@debian.org>
Date: Wed, 11 Jan 2023 11:34:24 +0000
Subject: [PATCH 3/3] Simplify f2py wrappers by assuming all entry-point
 scripts are equivalent

Because the f2py executable is a generated entry-point script, the only
part of its content that varies is the shebang line, so we don't need
to install all the scripts into /usr/libexec and can simply use
/usr/bin/f2py as the underlying implementation.
---
 debian/f2py.in               | 2 +-
 debian/python3-numpy.install | 1 -
 debian/rules                 | 9 ++-------
 3 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/debian/f2py.in b/debian/f2py.in
index abd154c6..dc6378ce 100644
--- a/debian/f2py.in
+++ b/debian/f2py.in
@@ -3,7 +3,7 @@
 set -e
 
 if [ -x /usr/bin/python@VERSION@ ]; then
-    exec /usr/bin/python@VERSION@ /usr/libexec/f2py@VERSION@ "$@"
+    exec /usr/bin/python@VERSION@ /usr/bin/f2py "$@"
 fi
 
 cat >&2 <<EOF
diff --git a/debian/python3-numpy.install b/debian/python3-numpy.install
index 7c36cb4c..630598b4 100644
--- a/debian/python3-numpy.install
+++ b/debian/python3-numpy.install
@@ -2,7 +2,6 @@ debian/dh_numpy3 usr/bin
 debian/numpy3.pm usr/share/perl5/Debian/Debhelper/Sequence/
 debian/versions usr/share/numpy3/
 usr/bin/f2py3
-usr/bin/f2py3.* usr/libexec
 usr/lib/python3*/*-packages/*.egg-info
 usr/lib/python3*/*-packages/*/*.py
 usr/lib/python3*/*-packages/*/*/*.cpython-3?[!d][!d]*.so
diff --git a/debian/rules b/debian/rules
index 30119b75..4ea589ba 100755
--- a/debian/rules
+++ b/debian/rules
@@ -48,14 +48,9 @@ override_dh_python3:
 	fi
 
 override_dh_install:
-	# We use #!/usr/bin/python3 so that dh-python won't generate a
-	# dependency on each of the interpreters. A wrapper script generated
-	# from debian/f2py.in is responsible for using the correct
-	# interpreter if available, or showing an error message.
-	set -e; for v in $(PY3VERS); do \
-		sed -i "1s,#!.*python[^ ]*\(.*\),#!/usr/bin/python3," debian/tmp/usr/bin/f2py$$v; \
-	done
 	cp -a debian/tmp/usr/bin/f2py$(PY3DEF) debian/tmp/usr/bin/f2py3
+	sed -i "1s,#!.*python[^ ]*\(.*\),#!/usr/bin/python3," debian/tmp/usr/bin/f2py3
+	rm -f debian/tmp/usr/bin/f2py3.*
 
 	# install numpy.i into the include directory
 	cp -a tools/swig/numpy.i debian/tmp/usr/lib/python3/dist-packages/numpy/core/include/numpy
-- 
2.39.0

Reply via email to