Package: src:python3.15
Version: 3.15.0~rc2-2
Tags: patch, forky, sid
Severity: important
Hi!
Python 3.15 brings the stabilization of abi3t, the free threaded (no
gil) abi. Python extensions that use the Limited API can then be built
to provide a free threaded extension.
I've worked on a proposal that creates the -nogil packages from the
python3.15 package [1]. This would add the python3.15t interpreter and
its corresponding standard library.
In the MR I've taken some decisions, like the names of the packages and
the shipping of the standard library. I've also added the triggers so
that if the -nogil package is included, the pyc files are generated.
For convenience, I'm attaching the diff here as well, but if you have
comments, it's probably better to discuss in Salsa.
Happy hacking,
[1]: https://salsa.debian.org/cpython-team/python3/-/merge_requests/46
--
"Can you imagine what I would do if I could do all I can?" -- Sun Tzu
Saludos /\/\ /\ >< `/
diff --git a/.gitignore b/.gitignore
index 53fe32b..dcca30c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,9 +67,12 @@ debian/idle-python3.15
debian/libpython3.15-dbg
debian/libpython3.15-dev
debian/libpython3.15-minimal
+debian/libpython3.15-nogil
+debian/libpython3.15-nogil-dev
debian/libpython3.15-stdlib
debian/libpython3.15-testsuite
debian/libpython3.15
+debian/python3.15-nogil
debian/python3.15-dbg
debian/python3.15-dev
debian/python3.15-doc
@@ -82,6 +85,7 @@ debian/python3.15-tk
debian/python3.15
debian/test_results
debian/tmp-dbg
+debian/tmp-nogil
debian/tmp-shdbg
debian/tmp
@@ -105,6 +109,9 @@ debian/libpython3.15-minimal.overrides
debian/libpython3.15-minimal.postinst
debian/libpython3.15-minimal.postrm
debian/libpython3.15-minimal.prerm
+debian/libpython3.15-nogil-dev.overrides
+debian/libpython3.15-nogil.overrides
+debian/libpython3.15-nogil.prerm
debian/libpython3.15-stdlib.overrides
debian/libpython3.15-stdlib.prerm
debian/libpython3.15-testsuite.overrides
@@ -141,6 +148,10 @@ debian/python3.15-nopie.preinst
debian/python3.15-nopie.postrm
debian/python3.15-tk.postinst
debian/python3.15-tk.prerm
+debian/python3.15-nogil.overrides
+debian/python3.15-nogil.postinst
+debian/python3.15-nogil.prerm
+debian/python3.15-nogil.triggers
debian/python3.15.desktop
debian/python3.15.overrides
debian/python3.15.postinst
diff --git a/debian/PVER-nogil.overrides.in b/debian/PVER-nogil.overrides.in
new file mode 100644
index 0000000..fd8fd92
--- /dev/null
+++ b/debian/PVER-nogil.overrides.in
@@ -0,0 +1,8 @@
+# no, it's not unusual
+@PVER@-nogil binary: unusual-interpreter
+
+# pointless lintian ...
+@PVER@-nogil binary: hardening-no-fortify-functions
+
+# pyexpat.c contains expat error messages that lintian mis-attributes to embedding
+@PVER@-nogil binary: embedded-library
diff --git a/debian/PVER-nogil.postinst.in b/debian/PVER-nogil.postinst.in
new file mode 100644
index 0000000..1519d9b
--- /dev/null
+++ b/debian/PVER-nogil.postinst.in
@@ -0,0 +1,41 @@
+#! /bin/sh
+
+set -e
+
+compile_distpackages()
+{
+ if [ -x /usr/bin/@PVER@t ] && [ -d /usr/lib/python3/dist-packages ]; then
+ /usr/bin/@PVER@t -E -S -m compileall -q /usr/lib/python3/dist-packages
+ if grep -sq '^byte-compile[^#]*optimize' /etc/python/debian_config; then
+ /usr/bin/@PVER@t -E -S -O -m compileall -q /usr/lib/python3/dist-packages
+ fi
+ fi
+}
+
+case "$1" in
+ configure)
+ files=$(LC_ALL=C.UTF8 dpkg -L lib@PVER@-nogil@HOST_QUAL@ 2>/dev/null | sed -n '/^\/usr\/lib\/@PVER@t\/.*\.py$/p')
+ if [ -n "$files" ]; then
+ /usr/bin/@PVER@t -E -S /usr/lib/@PVER@t/py_compile.py $files
+ if grep -sq '^byte-compile[^#]*optimize' /etc/python/debian_config; then
+ /usr/bin/@PVER@t -E -S -O /usr/lib/@PVER@t/py_compile.py $files
+ fi
+ else
+ echo >&2 "@PVER@-nogil: can't get files for byte-compilation"
+ fi
+ compile_distpackages
+ ;;
+ triggered)
+ for trigger in $2; do
+ case "$trigger" in
+ /usr/lib/python3/dist-packages)
+ compile_distpackages
+ ;;
+ esac
+ done
+ ;;
+esac
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/PVER-nogil.prerm.in b/debian/PVER-nogil.prerm.in
new file mode 100644
index 0000000..54526d6
--- /dev/null
+++ b/debian/PVER-nogil.prerm.in
@@ -0,0 +1,40 @@
+#! /bin/sh
+
+set -e
+
+remove_bytecode()
+{
+ pkg=$1
+ max=$(LANG=C LC_ALL=C xargs --show-limits < /dev/null 2>&1 | awk '/Maximum length/ {print int($NF / 4)}')
+ LC_ALL=C.UTF8 dpkg -L $pkg 2>/dev/null \
+ | awk -F/ 'BEGIN {OFS="/"} /\.py$/ {$NF=sprintf("__pycache__/%s.*.py[co]", substr($NF,1,length($NF)-3)); print}' \
+ | xargs --max-chars="$max" echo \
+ | while read files; do rm -f $files; done
+ find /usr/lib/@PVER@t -name __pycache__ -type d -empty -print 2>/dev/null \
+ | xargs -r rm -rf
+}
+
+clean_distpackages_bytecode()
+{
+ if [ -d /usr/lib/python3/dist-packages ]; then
+ find /usr/lib/python3/dist-packages -name "*cpython-@EXT_VER@t*.py[co]" -delete 2>/dev/null || true
+ find /usr/lib/python3/dist-packages -name __pycache__ -type d -empty -delete 2>/dev/null || true
+ fi
+}
+
+case "$1" in
+ remove|upgrade)
+ remove_bytecode lib@PVER@-nogil@HOST_QUAL@
+ clean_distpackages_bytecode
+ ;;
+ deconfigure)
+ ;;
+ failed-upgrade)
+ ;;
+ *)
+ echo "prerm called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+#DEBHELPER#
diff --git a/debian/PVER-nogil.triggers.in b/debian/PVER-nogil.triggers.in
new file mode 100644
index 0000000..72a007d
--- /dev/null
+++ b/debian/PVER-nogil.triggers.in
@@ -0,0 +1 @@
+interest-noawait /usr/lib/python3/dist-packages
diff --git a/debian/control b/debian/control
index 1d34aad..5abf73b 100644
--- a/debian/control
+++ b/debian/control
@@ -262,6 +262,41 @@ Description: Debug Build of the Python Interpreter (version 3.15)
.
See the README.debug for more information.
+Package: python3.15-nogil
+Architecture: linux-any
+Multi-Arch: allowed
+Depends: python3.15-minimal (= ${binary:Version}), libpython3.15-nogil (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
+Suggests: libpython3.15-nogil-dev
+Description: Free-threaded build of the Python Interpreter (version 3.15)
+ A build of the Python interpreter configured with --disable-gil, which runs
+ Python code without the global interpreter lock (PEP 703). The interpreter is
+ installed as python3.15t.
+XB-Cnf-Visible-Pkgname: python3.15t
+
+Package: libpython3.15-nogil
+Architecture: linux-any
+Multi-Arch: same
+Section: libs
+Pre-Depends: ${misc:Pre-Depends}
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Free-threaded Python runtime library (version 3.15)
+ A build of the Python runtime configured with --disable-gil, which runs Python
+ code without the global interpreter lock (PEP 703).
+ .
+ This package contains the standard library and the shared runtime library for
+ the free-threaded interpreter.
+
+Package: libpython3.15-nogil-dev
+Architecture: linux-any
+Multi-Arch: same
+Section: libdevel
+Depends: libpython3.15-nogil (= ${binary:Version}), libpython3.15-dev (= ${binary:Version}),
+ ${shlibs:Depends}, ${misc:Depends}
+Description: Header files and a static library for free-threaded Python (v3.15)
+ Header files, a static library and development tools for building Python
+ extension modules against the free-threaded (--disable-gil, PEP 703) build of
+ Python 3.15.
+
Package: python3.15-full
Architecture: any
Multi-Arch: allowed
diff --git a/debian/control.in b/debian/control.in
index 3477d96..f4caec8 100644
--- a/debian/control.in
+++ b/debian/control.in
@@ -262,6 +262,41 @@ Description: Debug Build of the Python Interpreter (version @VER@)
.
See the README.debug for more information.
+Package: @PVER@-nogil
+Architecture: linux-any
+Multi-Arch: allowed
+Depends: @PVER@-minimal (= ${binary:Version}), lib@PVER@-nogil (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
+Suggests: lib@PVER@-nogil-dev
+Description: Free-threaded build of the Python Interpreter (version @VER@)
+ A build of the Python interpreter configured with --disable-gil, which runs
+ Python code without the global interpreter lock (PEP 703). The interpreter is
+ installed as @PVER@t.
+XB-Cnf-Visible-Pkgname: @PVER@t
+
+Package: lib@PVER@-nogil
+Architecture: linux-any
+Multi-Arch: same
+Section: libs
+Pre-Depends: ${misc:Pre-Depends}
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Free-threaded Python runtime library (version @VER@)
+ A build of the Python runtime configured with --disable-gil, which runs Python
+ code without the global interpreter lock (PEP 703).
+ .
+ This package contains the standard library and the shared runtime library for
+ the free-threaded interpreter.
+
+Package: lib@PVER@-nogil-dev
+Architecture: linux-any
+Multi-Arch: same
+Section: libdevel
+Depends: lib@PVER@-nogil (= ${binary:Version}), lib@PVER@-dev (= ${binary:Version}),
+ ${shlibs:Depends}, ${misc:Depends}
+Description: Header files and a static library for free-threaded Python (v@VER@)
+ Header files, a static library and development tools for building Python
+ extension modules against the free-threaded (--disable-gil, PEP 703) build of
+ Python @VER@.
+
Package: @PVER@-full
Architecture: any
Multi-Arch: allowed
diff --git a/debian/libPVER-nogil-dev.overrides.in b/debian/libPVER-nogil-dev.overrides.in
new file mode 100644
index 0000000..9e29825
--- /dev/null
+++ b/debian/libPVER-nogil-dev.overrides.in
@@ -0,0 +1,8 @@
+lib@PVER@-nogil-dev binary: python3-script-but-no-python3-dep
+
+lib@PVER@-nogil-dev binary: arch-dependent-file-not-in-arch-specific-directory
+
+lib@PVER@-nogil-dev binary: package-contains-python-header-in-incorrect-directory
+
+# no, it's not unusual
+lib@PVER@-nogil-dev binary: unusual-interpreter
diff --git a/debian/libPVER-nogil.overrides.in b/debian/libPVER-nogil.overrides.in
new file mode 100644
index 0000000..ce846b6
--- /dev/null
+++ b/debian/libPVER-nogil.overrides.in
@@ -0,0 +1,22 @@
+# the package is lib@PVER@-nogil, the soname is libpython@VER@t
+lib@PVER@-nogil binary: package-name-doesnt-match-sonames
+
+# no, it's not unusual
+lib@PVER@-nogil binary: unusual-interpreter
+
+# the standard library ships plenty of scripts, but this package is the
+# interpreter's own runtime and must not depend on the default python3
+lib@PVER@-nogil binary: python3-script-but-no-python3-dep
+
+# pointless lintian ...
+lib@PVER@-nogil binary: hardening-no-fortify-functions
+
+# the extensions in /usr/lib/python@VER@t/lib-dynload carry the multiarch
+# triplet in their file names instead, exactly as for the default flavour
+lib@PVER@-nogil binary: arch-dependent-file-not-in-arch-specific-directory
+
+# yes, some extensions don't have references to any external lib
+lib@PVER@-nogil binary: shared-lib-without-dependency-information
+
+# pyexpat.c contains expat error messages that lintian mis-attributes to embedding
+lib@PVER@-nogil binary: embedded-library
diff --git a/debian/libPVER-nogil.prerm.in b/debian/libPVER-nogil.prerm.in
new file mode 100644
index 0000000..36a617e
--- /dev/null
+++ b/debian/libPVER-nogil.prerm.in
@@ -0,0 +1,42 @@
+#! /bin/sh
+
+set -e
+
+remove_bytecode()
+{
+ pkg=$1
+ max=$(LANG=C LC_ALL=C xargs --show-limits < /dev/null 2>&1 | awk '/Maximum length/ {print int($NF / 4)}')
+ LC_ALL=C.UTF8 dpkg -L $pkg 2>/dev/null \
+ | awk -F/ 'BEGIN {OFS="/"} /\.py$/ {$NF=sprintf("__pycache__/%s.*.py[co]", substr($NF,1,length($NF)-3)); print}' \
+ | xargs --max-chars="$max" echo \
+ | while read files; do rm -f $files; done
+ # source and bytecode filename mismatch
+ rm -f /usr/lib/@PVER@t/__pycache__/__phello__.cpython-*.py*
+ find /usr/lib/@PVER@t \
+ \( -name __pycache__ -type d -empty -print \) 2>/dev/null \
+ | xargs -r rm -rf
+}
+
+case "$1" in
+ remove)
+ pc=$(LC_ALL=C.UTF8 dpkg-query -f '${db:Status-Abbrev} ${binary:Package}\n' -W lib@PVER@-nogil \
+ | grep -v '^.n' | wc -l)
+ if [ "$pc" -le 1 ]; then
+ remove_bytecode lib@PVER@-nogil@HOST_QUAL@
+ fi
+ ;;
+ upgrade)
+ remove_bytecode lib@PVER@-nogil@HOST_QUAL@
+ # byte compilation in @PVER@-nogil postinst, strict dependency
+ ;;
+ deconfigure)
+ ;;
+ failed-upgrade)
+ ;;
+ *)
+ echo "prerm called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+#DEBHELPER#
diff --git a/debian/patches/distutils-install-layout.diff b/debian/patches/distutils-install-layout.diff
index 4ca5d36..8adbcf0 100644
--- a/debian/patches/distutils-install-layout.diff
+++ b/debian/patches/distutils-install-layout.diff
@@ -43,29 +43,29 @@ Forwarded: not-needed
for prefix in prefixes:
if not prefix or prefix in seen:
continue
-@@ -764,10 +772,21 @@ def getsitepackages(prefixes=None):
+@@ -764,11 +772,21 @@ def getsitepackages(prefixes=None):
if sys.platlibdir != "lib":
libdirs.append("lib")
+ if is_virtual_environment:
+ sitepackages.append(os.path.join(prefix, "lib",
-+ "python%d.%d" % sys.version_info[:2],
++ f"python{ver[0]}.{ver[1]}{abi_thread}",
+ "site-packages"))
+ sitepackages.append(os.path.join(prefix, "local/lib",
-+ "python%d.%d" % sys.version_info[:2],
++ f"python{ver[0]}.{ver[1]}{abi_thread}",
+ "dist-packages"))
-+ sitepackages.append(os.path.join(prefix, "lib",
-+ "python3",
-+ "dist-packages"))
-+ # this one is deprecated for Debian
for libdir in libdirs:
path = os.path.join(prefix, libdir,
f"{implementation}{ver[0]}.{ver[1]}{abi_thread}",
- "site-packages")
+ "dist-packages")
sitepackages.append(path)
++ sitepackages.append(os.path.join(prefix, "lib",
++ "python3",
++ "dist-packages"))
else:
sitepackages.append(prefix)
+ sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))
--- a/Lib/test/test_site.py
+++ b/Lib/test/test_site.py
@@ -354,16 +354,16 @@ class HelperFunctionsTests(unittest.Test
@@ -74,7 +74,7 @@ Forwarded: not-needed
if sys.platlibdir != "lib":
- self.assertEqual(len(dirs), 2)
- wanted = os.path.join('xoxo', sys.platlibdir,
-+ self.assertEqual(len(dirs), 3)
++ self.assertEqual(len(dirs), 4)
+ wanted = os.path.join('xoxo', 'local', 'lib',
f'python{sysconfig._get_python_version_abi()}',
- 'site-packages')
@@ -84,8 +84,9 @@ Forwarded: not-needed
- self.assertEqual(len(dirs), 1)
+ self.assertEqual(len(dirs), 3)
wanted = os.path.join('xoxo', 'lib',
- f'python{sysconfig._get_python_version_abi()}',
+- f'python{sysconfig._get_python_version_abi()}',
- 'site-packages')
++ 'python3',
+ 'dist-packages')
self.assertEqual(dirs[-1], wanted)
else:
diff --git a/debian/patches/sysconfig-debian-schemes.diff b/debian/patches/sysconfig-debian-schemes.diff
index 699c161..7500de9 100644
--- a/debian/patches/sysconfig-debian-schemes.diff
+++ b/debian/patches/sysconfig-debian-schemes.diff
@@ -14,8 +14,8 @@ This adds two schemes:
'data': '{base}',
},
+ 'deb_system': {
-+ 'stdlib': '{installed_base}/lib/python{py_version_short}',
-+ 'platstdlib': '{platbase}/lib/python{py_version_short}',
++ 'stdlib': '{installed_base}/lib/python{py_version_short}{abi_thread}',
++ 'platstdlib': '{platbase}/lib/python{py_version_short}{abi_thread}',
+ 'purelib': '{base}/lib/python3/dist-packages',
+ 'platlib': '{platbase}/lib/python3/dist-packages',
+ 'include':
@@ -26,10 +26,10 @@ This adds two schemes:
+ 'data': '{base}',
+ },
+ 'posix_local': {
-+ 'stdlib': '{installed_base}/lib/python{py_version_short}',
-+ 'platstdlib': '{platbase}/lib/python{py_version_short}',
-+ 'purelib': '{base}/local/lib/python{py_version_short}/dist-packages',
-+ 'platlib': '{platbase}/local/lib/python{py_version_short}/dist-packages',
++ 'stdlib': '{installed_base}/lib/python{py_version_short}{abi_thread}',
++ 'platstdlib': '{platbase}/lib/python{py_version_short}{abi_thread}',
++ 'purelib': '{base}/local/lib/python{py_version_short}{abi_thread}/dist-packages',
++ 'platlib': '{platbase}/local/lib/python{py_version_short}{abi_thread}/dist-packages',
+ 'include':
+ '{installed_base}/include/python{py_version_short}{abiflags}',
+ 'platinclude':
diff --git a/debian/rules b/debian/rules
index 0841e5f..a7cb2a2 100755
--- a/debian/rules
+++ b/debian/rules
@@ -92,6 +92,10 @@ SVER=3.15.0~rc1
NVER=3.16
PVER=python$(VER)
EXT_VER=$(subst .,,$(VER))
+# LDVERSION and interpreter name of the free-threaded flavour: 3.15t / python3.15t.
+# Upstream derives these from ABIFLAGS/ABI_THREAD (configure.ac:1768, 6656).
+TVER=$(VER)t
+PTVER=python$(TVER)
PRIORITY=$(shell echo $(VER) | tr -d '.')0
PREVVER := $(shell awk '/^python/ && NR > 1 {print substr($$2,2,length($$2)-2); exit}' debian/changelog)
@@ -122,6 +126,10 @@ with_gdbm := yes
with_interp := static
#with_interp := shared
+ifeq ($(DEB_HOST_ARCH_OS),linux)
+ with_nogil := yes
+endif
+
PY_INTERPRETER = /usr/bin/python$(VER)
ifeq ($(DEFAULT_VERSION),yes)
@@ -269,11 +277,17 @@ buildd_nopie := $(CURDIR)/build-nopie
buildd_shared := $(CURDIR)/build-shared
buildd_debug := $(CURDIR)/build-debug
buildd_shdebug := $(CURDIR)/build-shdebug
+buildd_nogil := $(CURDIR)/build-nogil
+buildd_shnogil := $(CURDIR)/build-shnogil
d := debian/tmp
scriptdir = usr/share/lib/python$(VER)
scriptdir = usr/share/python$(VER)
scriptdir = usr/lib/python$(VER)
+# The free-threaded flavour gets its own stdlib directory: upstream derives
+# LIBDEST from ABI_THREAD, not ABIFLAGS, so unlike the -dbg flavour it does
+# not share $(scriptdir). See configure.ac:6709.
+ftscriptdir = usr/lib/python$(TVER)
# package names and directories
p_base := $(PVER)
@@ -290,12 +304,15 @@ p_dbg := $(PVER)-dbg
p_udeb := $(PVER)-udeb
p_venv := $(PVER)-venv
p_full := $(PVER)-full
+p_nogil := $(PVER)-nogil
p_lbase := lib$(PVER)-stdlib
p_lmin := lib$(PVER)-minimal
p_ldev := lib$(PVER)-dev
p_ldbg := lib$(PVER)-dbg
p_ltst := lib$(PVER)-testsuite
+p_lnogil := lib$(PVER)-nogil
+p_lnogildev := lib$(PVER)-nogil-dev
d_base := debian/$(p_base)
d_min := debian/$(p_min)
@@ -311,12 +328,15 @@ d_dbg := debian/$(p_dbg)
d_udeb := debian/$(p_udeb)
d_venv := debian/$(p_venv)
d_full := debian/$(p_full)
+d_nogil := debian/$(p_nogil)
d_lbase := debian/$(p_lbase)
d_lmin := debian/$(p_lmin)
d_ldev := debian/$(p_ldev)
d_ldbg := debian/$(p_ldbg)
d_ltst := debian/$(p_ltst)
+d_lnogil := debian/$(p_lnogil)
+d_lnogildev := debian/$(p_lnogildev)
build-arch: stamps/stamp-build
build-indep: stamps/stamp-build-doc
@@ -326,6 +346,8 @@ stamps/stamp-build: stamps/stamp-build-static \
stamps/stamp-mincheck \
stamps/stamp-build-shared stamps/stamp-build-debug \
stamps/stamp-build-shared-debug \
+ $(if $(filter yes, $(with_nogil)),stamps/stamp-build-nogil) \
+ $(if $(filter yes, $(with_nogil)),stamps/stamp-build-shared-nogil) \
stamps/stamp-check stamps/stamp-pybench
touch $@
@@ -402,6 +424,11 @@ ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE))
endif
endif
+nogil_configure_args = \
+ $(filter-out --enable-experimental-jit=%,$(common_configure_args)) \
+ --disable-gil \
+ --with-mimalloc
+
stamps/stamp-configure-shared: stamps/stamp-patch
rm -rf $(buildd_shared)
mkdir -p $(buildd_shared)
@@ -537,6 +564,61 @@ stamps/stamp-build-shared-debug: stamps/stamp-configure-shared-debug
$(MAKE) $(NJOBS) -C $(buildd_shdebug)
touch $@
+stamps/stamp-configure-nogil: stamps/stamp-patch
+ rm -rf $(buildd_nogil)
+ mkdir -p $(buildd_nogil)
+ cd $(buildd_nogil) && \
+ AR="$(AR)" RANLIB="$(RANLIB)" LLVM_VERSION="$(LLVM_VERSION)" \
+ CFLAGS_NODIST="$(DPKG_PIE_CPPFLAGS) $(OPT_PIE_CFLAGS)" \
+ LDFLAGS_NODIST="$(DPKG_PIE_LDFLAGS) $(LTO_CFLAGS)" \
+ $(config_site) \
+ ../configure \
+ $(nogil_configure_args)
+
+ $(call __post_configure,$(buildd_nogil))
+ touch $@
+
+stamps/stamp-build-nogil: stamps/stamp-configure-nogil
+ dh_testdir
+ $(MAKE) $(NJOBS) -C $(buildd_nogil)
+
+ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
+ : # check that the GIL really is disabled, and that the flavour works
+ cd $(buildd_nogil) && ./python -c 'import sys; assert sys.abiflags == "t", sys.abiflags'
+ cd $(buildd_nogil) && ./python -c 'import sys; assert not sys._is_gil_enabled()'
+ cd $(buildd_nogil) && ./python -c 'import math, cmath'
+ cd $(buildd_nogil) && ./python -c 'import _decimal'
+ ifneq (,$(filter $(DEB_HOST_ARCH_OS), linux))
+ cd $(buildd_nogil) && ./python -c 'from _multiprocessing import SemLock'
+ endif
+ : # the SOABI must carry the t abiflag, or extensions would collide
+ cd $(buildd_nogil) && ./python -c 'import sysconfig; \
+ soabi = sysconfig.get_config_var("SOABI"); \
+ assert soabi.startswith("cpython-$(EXT_VER)t-"), soabi'
+endif
+ touch $@
+
+stamps/stamp-configure-shared-nogil: stamps/stamp-patch
+ rm -rf $(buildd_shnogil)
+ mkdir -p $(buildd_shnogil)
+ cd $(buildd_shnogil) && \
+ AR="$(AR)" RANLIB="$(RANLIB)" LLVM_VERSION="$(LLVM_VERSION)" \
+ CFLAGS_NODIST="$(DPKG_CPPFLAGS) $(OPT_CFLAGS)" \
+ LDFLAGS_NODIST="$(DPKG_LDFLAGS) $(LTO_CFLAGS)" \
+ $(config_site) \
+ ../configure \
+ $(nogil_configure_args) \
+ --enable-shared
+
+ $(call __post_configure,$(buildd_shnogil))
+ touch $@
+
+stamps/stamp-build-shared-nogil: stamps/stamp-configure-shared-nogil
+ dh_testdir
+ : # build the shared nogil library
+ $(MAKE) $(NJOBS) -C $(buildd_shnogil)
+ touch $@
+
define __post_configure
egrep \
@@ -805,6 +887,7 @@ stamps/stamp-build-doc: stamps/stamp-doc-html stamps/stamp-doc-info
control-file:
sed -e "s/@PVER@/$(PVER)/g" \
-e "s/@VER@/$(VER)/g" \
+ -e "s/@EXT_VER@/$(EXT_VER)/g" \
-e "s/@PYSTDDEP@/$(PYSTDDEP)/g" \
-e "s/@PRIO@/$(PY_PRIO)/g" \
-e "s/@MINPRIO@/$(PY_MINPRIO)/g" \
@@ -842,10 +925,12 @@ clean: control-file
$(MAKE) -C Doc clean
sed 's/^@/#/' Makefile.pre.in | $(MAKE) -f - srcdir=. distclean
rm -rf $(buildd_static) $(buildd_shared) $(buildd_debug) $(buildd_shdebug) $(buildd_nopie)
+ rm -rf $(buildd_nogil) $(buildd_shnogil)
find -name '*.py[co]' | xargs -r rm -f
rm -f Lib/dist-packages
rm -rf locales
rm -rf $(d)-dbg
+ rm -rf $(d)-nogil
rm -f configure
rm -f netlify.toml
rm -rf $(TEST_DIR) debian/testdir
@@ -867,6 +952,7 @@ stamps/stamp-control:
f2=`echo $$f | sed "s,PVER,$(PVER),g;s/@VER@/$(VER)/g;s,\.in$$,,"`; \
if [ $$f2 != debian/control ]; then \
sed -e "s/@PVER@/$(PVER)/g;s/@VER@/$(VER)/g;s/@SVER@/$(SVER)/g" \
+ -e "s/@EXT_VER@/$(EXT_VER)/g" \
-e "s/@PRIORITY@/$(PRIORITY)/g" \
-e "s,@SCRIPTDIR@,/$(scriptdir),g" \
-e "s,@INFO@,$(info_docs),g" \
@@ -1247,13 +1333,6 @@ endif
cp -p debian/$(PVER).desktop \
$(d_base)/usr/share/applications/$(PVER).desktop
- : # remove some things
- -find debian -name .cvsignore | xargs rm -f
- -find debian -name '*.py[co]' | xargs rm -f
-
- : # remove empty directories, when all components are in place
- -find debian ! -name lib-dynload ! -name dist-packages -type d -empty -delete
-
: # install debug package
rm -rf $(d)-dbg
install -d $(d)-dbg/$(scriptdir)/lib-dynload
@@ -1382,6 +1461,146 @@ endif
ln -sf $(PVER).1.gz $(d_dbg)/usr/share/man/man1/$(PVER)d.1.gz
ln -sf $(PVER)-config.1.gz $(d_dbg)/usr/share/man/man1/$(PVER)d-config.1.gz
+ifeq ($(with_nogil),yes)
+ rm -rf $(d)-nogil
+ install -d $(d)-nogil
+ $(MAKE) -C $(buildd_nogil) install DESTDIR=$(CURDIR)/$(d)-nogil
+
+ rm -f $(d)-nogil/usr/bin/python3 $(d)-nogil/usr/bin/python3-config
+ rm -f $(d)-nogil/usr/bin/$(PVER) $(d)-nogil/usr/bin/$(PVER)-config
+ rm -f $(d)-nogil/usr/bin/idle3 $(d)-nogil/usr/bin/idle$(VER)
+ rm -f $(d)-nogil/usr/bin/pydoc3 $(d)-nogil/usr/bin/pydoc$(VER)
+ cd $(d)-nogil/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig && \
+ rm -f python3.pc python3-embed.pc \
+ python-$(VER).pc python-$(VER)-embed.pc
+ : # nothing named $(VER) may be left behind; fail the build if it is
+ test -z "$$(find $(d)-nogil/usr/bin $(d)-nogil/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig \
+ -maxdepth 1 \( -name 'python3' -o -name 'python3-*' \
+ -o -name 'python$(VER)' -o -name 'python$(VER)-*' \
+ -o -name 'python-$(VER).pc' -o -name 'python-$(VER)-embed.pc' \) -print)"
+
+ : # the config Makefile and sysconfig data come from the shared build,
+ : # so that extensions are linked the way the shared library was
+ sed $(sysconfig_substflags) \
+ $(buildd_shnogil)/Makefile \
+ > $(d)-nogil/$(ftscriptdir)/config-$(TVER)-$(DEB_HOST_MULTIARCH)/Makefile
+ sed $(sysconfig_substflags) \
+ $(buildd_shnogil)/$(shell cat $(buildd_shnogil)/pybuilddir.txt)/_sysconfigdata_t_$(PLAT)_$(DEB_HOST_MULTIARCH).py \
+ > $(d)-nogil/$(ftscriptdir)/_sysconfigdata_t_$(PLAT)_$(DEB_HOST_MULTIARCH).py
+ sed -i $(sysconfig_substflags) \
+ $(d)-nogil/$(ftscriptdir)/_sysconfigdata_t_$(PLAT)_$(DEB_HOST_MULTIARCH).py
+ sed $(sysconfig_substflags) \
+ $(buildd_shnogil)/$(shell cat $(buildd_shnogil)/pybuilddir.txt)/_sysconfig_vars_t_$(PLAT)_$(DEB_HOST_MULTIARCH).json \
+ > $(d)-nogil/$(ftscriptdir)/_sysconfig_vars_t_$(PLAT)_$(DEB_HOST_MULTIARCH).json
+ sed -i $(sysconfig_substflags) \
+ $(d)-nogil/$(ftscriptdir)/_sysconfig_vars_t_$(PLAT)_$(DEB_HOST_MULTIARCH).json
+
+ : # fix /usr/local path in build-details.*.json
+ sed -i -e '/base_interpreter/s,/usr/local/,/usr/,' \
+ $(d)-nogil/$(ftscriptdir)/build-details.t.$(DEB_HOST_MULTIARCH).json
+
+ : # ---- $(p_lnogil): stdlib, extensions and the shared library ----
+ dh_installdirs -p$(p_lnogil) \
+ $(ftscriptdir) \
+ usr/lib/$(DEB_HOST_MULTIARCH)
+ cp -a $(d)-nogil/$(ftscriptdir)/. $(d_lnogil)/$(ftscriptdir)/
+ cp -p $(buildd_shnogil)/libpython$(TVER).so.1.0 \
+ $(d_lnogil)/usr/lib/$(DEB_HOST_MULTIARCH)/
+ dh_link -p$(p_lnogil) \
+ /usr/lib/$(DEB_HOST_MULTIARCH)/libpython$(TVER).so.1.0 \
+ /usr/lib/$(DEB_HOST_MULTIARCH)/libpython$(TVER).so.1
+
+ : # Move the test framework into $(p_lnogil) and remove the full testsuite
+ mkdir -p $(d_lnogil)/$(ftscriptdir)/test-keep
+ mv $(d_lnogil)/$(ftscriptdir)/test/{libregrtest,support} \
+ $(d_lnogil)/$(ftscriptdir)/test/typinganndata \
+ $(d_lnogil)/$(ftscriptdir)/test/{regrtest,test_support,__init__,__main__}.py \
+ $(d_lnogil)/$(ftscriptdir)/test-keep/
+ rm -rf $(d_lnogil)/$(ftscriptdir)/test
+ mv $(d_lnogil)/$(ftscriptdir)/test-keep $(d_lnogil)/$(ftscriptdir)/test
+
+ # Mark the interpreter as being PEP668 EXTERNALLY-MANAGED
+ install -m 644 debian/EXTERNALLY-MANAGED \
+ $(d_lnogil)/$(ftscriptdir)
+
+ dh_link -p$(p_lnogil) \
+ /etc/$(PVER)/sitecustomize.py /$(ftscriptdir)/sitecustomize.py
+
+ rm -f $(d_lnogil)/$(ftscriptdir)/idlelib/idle.bat
+ rm -rf $(d_lnogil)/$(ftscriptdir)/ctypes/macholib
+ rm -rf $(d_lnogil)/$(ftscriptdir)/ensurepip/_bundled
+ rm -rf $(d_lnogil)/$(ftscriptdir)/site-packages
+ find $(d_lnogil) -name 'wininst*.exe' | xargs -r rm -f
+
+ifneq ($(with_dbmmodule),yes)
+ rm -f $(d_lnogil)/$(ftscriptdir)/lib-dynload/_dbm*.so
+endif
+ifneq ($(with_tk),yes)
+ rm -f $(d_lnogil)/$(ftscriptdir)/lib-dynload/_tkinter*.so
+ rm -rf $(d_lnogil)/$(ftscriptdir)/tkinter
+endif
+ifneq ($(with_gdbm),yes)
+ rm -f $(d_lnogil)/$(ftscriptdir)/lib-dynload/_gdbm*.so
+endif
+
+ : # ---- $(p_lnogildev): headers, static library, pkgconfig, config dir ----
+ dh_installdirs -p$(p_lnogildev) \
+ usr/bin \
+ usr/share/man/man1 \
+ usr/include/$(PTVER) \
+ usr/include/$(DEB_HOST_MULTIARCH)/$(PTVER) \
+ usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig \
+ $(ftscriptdir)
+
+ : # the build machinery belongs in -dev, not in the runtime package
+ mv $(d_lnogil)/$(ftscriptdir)/config-$(TVER)-$(DEB_HOST_MULTIARCH) \
+ $(d_lnogildev)/$(ftscriptdir)/
+ dh_link -p$(p_lnogildev) \
+ /usr/lib/$(DEB_HOST_MULTIARCH)/libpython$(TVER).so.1.0 \
+ /usr/lib/$(DEB_HOST_MULTIARCH)/libpython$(TVER).so \
+ /$(ftscriptdir)/config-$(TVER)-$(DEB_HOST_MULTIARCH)/libpython$(TVER).a \
+ /usr/lib/$(DEB_HOST_MULTIARCH)/libpython$(TVER).a
+
+ : # Every header except pyconfig.h is ABI-independent - only pyconfig.h
+ : # defines Py_GIL_DISABLED, the rest merely test it - so symlink them
+ : # into $(PVER) and keep this package Multi-Arch: same.
+ for i in $(d_ldev)/usr/include/$(PVER)/*; do \
+ i=$$(basename $$i); \
+ case $$i in pyconfig.h) continue; esac; \
+ ln -sf ../$(PVER)/$$i $(d_lnogildev)/usr/include/$(PTVER)/$$i; \
+ done
+ cp -p $(buildd_nogil)/pyconfig.h $(d_lnogildev)/usr/include/$(DEB_HOST_MULTIARCH)/$(PTVER)/
+ sed 's/@subdir@/$(PTVER)/;s/@header@/pyconfig.h/' \
+ debian/multiarch.h.in > $(d_lnogildev)/usr/include/$(PTVER)/pyconfig.h
+
+ cp $(d)-nogil/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/python-$(TVER).pc \
+ $(d_lnogildev)/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/.
+ cp $(d)-nogil/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/python-$(TVER)-embed.pc \
+ $(d_lnogildev)/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/.
+
+ : # in $(p_lnogildev), prefix python-config with triplets
+ sed -i $(sysconfig_substflags) $(d)-nogil/usr/bin/$(PTVER)-config
+ cp $(d)-nogil/usr/bin/$(PTVER)-config \
+ $(d_lnogildev)/usr/bin/$(DEB_HOST_MULTIARCH)-$(PTVER)-config
+ ln -sf $(DEB_HOST_MULTIARCH)-$(PVER)-config.1.gz \
+ $(d_lnogildev)/usr/share/man/man1/$(DEB_HOST_MULTIARCH)-$(PTVER)-config.1.gz
+ifneq ($(DEB_HOST_MULTIARCH),$(DEB_HOST_GNU_TYPE))
+ ln -sf $(DEB_HOST_MULTIARCH)-$(PTVER)-config \
+ $(d_lnogildev)/usr/bin/$(DEB_HOST_GNU_TYPE)-$(PTVER)-config
+ ln -sf $(DEB_HOST_MULTIARCH)-$(PVER)-config.1.gz \
+ $(d_lnogildev)/usr/share/man/man1/$(DEB_HOST_GNU_TYPE)-$(PTVER)-config.1.gz
+endif
+
+ : # ---- $(p_nogil): the interpreter itself ----
+ dh_installdirs -p$(p_nogil) \
+ usr/bin \
+ usr/share/man/man1
+ cp -p $(buildd_nogil)/python $(d_nogil)/usr/bin/$(PTVER)
+ ln -sf $(DEB_HOST_MULTIARCH)-$(PTVER)-config $(d_nogil)/usr/bin/$(PTVER)-config
+ ln -sf $(PVER).1.gz $(d_nogil)/usr/share/man/man1/$(PTVER).1.gz
+ ln -sf $(PVER)-config.1.gz $(d_nogil)/usr/share/man/man1/$(PTVER)-config.1.gz
+endif
+
ifeq ($(with_udeb),yes)
: # Copy the most important files from $(p_min) into $(p_udeb).
dh_installdirs -p$(p_udeb) \
@@ -1428,6 +1647,13 @@ endif
install -D -m 644 $$i debian/$$b/usr/share/lintian/overrides/$$b; \
done
+ : # remove some things
+ -find debian -name .cvsignore | xargs rm -f
+ -find debian -name '*.py[co]' | xargs rm -f
+
+ : # remove empty directories, when all components are in place
+ -find debian ! -name lib-dynload ! -name dist-packages -type d -empty -delete
+
touch stamps/stamp-install
# Build architecture-independent files here.
@@ -1512,6 +1738,16 @@ binary-arch: build-arch install
rm -rf debian/$$i/usr/share/doc/$$i; \
ln -s $(p_lbase) debian/$$i/usr/share/doc/$$i; \
done
+ifeq ($(with_nogil),yes)
+ for i in $(p_nogil); do \
+ rm -rf debian/$$i/usr/share/doc/$$i; \
+ ln -s $(p_min) debian/$$i/usr/share/doc/$$i; \
+ done
+ for i in $(p_lnogildev); do \
+ rm -rf debian/$$i/usr/share/doc/$$i; \
+ ln -s $(p_lnogil) debian/$$i/usr/share/doc/$$i; \
+ done
+endif
-find debian ! -perm -200 -print -exec chmod +w {} \;
ifneq ($(with_tk),yes)
rm -f $(d_lbase)/$(scriptdir)/tkinter
@@ -1550,6 +1786,9 @@ endif
dh_makeshlibs -p$(p_lib) -V '$(p_lib)'
dh_makeshlibs -p$(p_ldbg) -V '$(p_ldbg)'
+ifeq ($(with_nogil),yes)
+ dh_makeshlibs -p$(p_lnogil) -V '$(p_lnogil)'
+endif
# don't include the following symbols, found in extensions
# which either can be built as builtin or extension.
sed -ri \