Subject: Re: [bug#46848] [PATCHES] [core-updates] PEP 517 python-build-system

From: Lars-Dominik Braun <[email-masked]>
Date: Sun, 24 Apr 2022 11:13:39 +0200

Hi Maxim,

> When you judge the branch ready to merge, could you please send a subset
> of the patches (at least the ones touching the python-build-system
> directly) to this issue (marked as v2 -- git send-email -v2) so that
> they can be more easily commented?
I had some time to finish my work, so I pushed all of my changes to
wip-python-pep517 and attached changes that do not fix individual packages
to this email. Since my last version I added support for building Python
2 packages, although we should really phase out Python 2 asap. I kept
support for nose and setup.py’s test target, because they are still
in use/valuable, but we can also remove them if you prefer.

Please have a look when time permits. If all is good we can move on to
fix failing packages.

Thank you very much,
Lars

>From 720dbe22d431262938be29dd9a9ddb78c44a99b3 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <[email-masked]>
Date: Fri, 19 Feb 2021 17:22:35 +0100
Subject: [PATCH v3 001/150] build/python: Handle missing setuptools in
 sanity-check.py

Just skip testing if required dependencies (setuptools) are not
available.

* gnu/packages/aux-files/python/sanity-check.py: Handle ImportError.
---
 gnu/packages/aux-files/python/sanity-check.py | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/aux-files/python/sanity-check.py b/gnu/packages/aux-files/python/sanity-check.py
index 182133bb3d..1366b68e3d 100644
--- a/gnu/packages/aux-files/python/sanity-check.py
+++ b/gnu/packages/aux-files/python/sanity-check.py
@@ -19,9 +19,13 @@
 
 from __future__ import print_function  # Python 2 support.
 import importlib
-import pkg_resources
 import sys
 import traceback
+try:
+    import pkg_resources
+except ImportError:
+    print('Warning: Skipping, because python-setuptools are not available.')
+    sys.exit(0)
 
 try:
     from importlib.machinery import PathFinder
-- 
2.35.1

>From 4539d2994f454ca3528985bb140ec4aba8e919da Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <[email-masked]>
Date: Sat, 23 Apr 2022 11:07:58 +0200
Subject: [PATCH v3 002/150] gnu: python{,2}-setuptools: Move to python-build.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/python-xyz.scm (python{,2}-setuptools): Move…
* gnu/packages/python-build.scm: …here.
---
 gnu/packages/python-build.scm | 90 +++++++++++++++++++++++++++++++++++
 gnu/packages/python-xyz.scm   | 90 -----------------------------------
 2 files changed, 90 insertions(+), 90 deletions(-)

diff --git a/gnu/packages/python-build.scm b/gnu/packages/python-build.scm
index 2abb781f76..f167c3953f 100644
--- a/gnu/packages/python-build.scm
+++ b/gnu/packages/python-build.scm
@@ -39,6 +39,96 @@ (define-module (gnu packages python-build)
 ;;;
 ;;; Code:
 
+(define-public python-setuptools
+  (package
+    (name "python-setuptools")
+    (version "52.0.0")
+    (source
+     (origin
+      (method url-fetch)
+      (uri (pypi-uri "setuptools" version))
+      (sha256
+       (base32
+        "15ibjdjhkwgj6qbmpsxikkqdfsb1550z46fly7dm15ah4bk1wfpv"))
+      (modules '((guix build utils)))
+      (snippet
+       '(begin
+          ;; Remove included binaries which are used to build self-extracting
+          ;; installers for Windows.
+          ;; TODO: Find some way to build them ourself so we can include them.
+          (for-each delete-file (find-files "setuptools" "^(cli|gui).*\\.exe$"))
+          #t))))
+    (build-system python-build-system)
+    ;; FIXME: Tests require pytest, which itself relies on setuptools.
+    ;; One could bootstrap with an internal untested setuptools.
+    (arguments
+     `(#:tests? #f))
+    (home-page "https://pypi.org/project/setuptools/")
+    (synopsis
+     "Library designed to facilitate packaging Python projects")
+    (description
+     "Setuptools is a fully-featured, stable library designed to facilitate
+packaging Python projects, where packaging includes:
+Python package and module definitions,
+distribution package metadata,
+test hooks,
+project installation,
+platform-specific details,
+Python 3 support.")
+    ;; TODO: setuptools now bundles the following libraries:
+    ;; packaging, pyparsing, six and appdirs. How to unbundle?
+    (license (list license:psfl        ; setuptools itself
+                   license:expat       ; six, appdirs, pyparsing
+                   license:asl2.0      ; packaging is dual ASL2/BSD-2
+                   license:bsd-2))
+    (properties `((python2-variant . ,(delay python2-setuptools))))))
+
+;; Newer versions of setuptools no longer support Python 2.
+(define-public python2-setuptools
+  (package
+    (name "python2-setuptools")
+    (version "41.0.1")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "setuptools" version ".zip"))
+       (sha256
+        (base32
+         "04sns22y2hhsrwfy1mha2lgslvpjsjsz8xws7h2rh5a7ylkd28m2"))
+       (modules '((guix build utils)))
+       (snippet
+        '(begin
+           ;; Remove included binaries which are used to build self-extracting
+           ;; installers for Windows.
+           ;; TODO: Find some way to build them ourself so we can include them.
+           (for-each delete-file (find-files "setuptools" "^(cli|gui).*\\.exe$"))
+           #t))))
+    (build-system python-build-system)
+    ;; FIXME: Tests require pytest, which itself relies on setuptools.
+    ;; One could bootstrap with an internal untested setuptools.
+    (arguments
+     `(#:tests? #f))
+    (native-inputs
+     (list unzip))
+    (home-page "https://pypi.org/project/setuptools/")
+    (synopsis
+     "Library designed to facilitate packaging Python projects")
+    (description
+     "Setuptools is a fully-featured, stable library designed to facilitate
+packaging Python projects, where packaging includes:
+Python package and module definitions,
+distribution package metadata,
+test hooks,
+project installation,
+platform-specific details,
+Python 3 support.")
+    ;; TODO: setuptools now bundles the following libraries:
+    ;; packaging, pyparsing, six and appdirs. How to unbundle?
+    (license (list license:psfl         ; setuptools itself
+                   license:expat        ; six, appdirs, pyparsing
+                   license:asl2.0       ; packaging is dual ASL2/BSD-2
+                   license:bsd-2))))
+
 (define-public python-wheel
   (package
     (name "python-wheel")
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index 219a0d9213..f2532abc52 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -1792,96 +1792,6 @@ (define-public python2-serpent
        `(("python-enum34" ,python2-enum34)
          ,@(package-propagated-inputs base))))))
 
-(define-public python-setuptools
-  (package
-    (name "python-setuptools")
-    (version "52.0.0")
-    (source
-     (origin
-      (method url-fetch)
-      (uri (pypi-uri "setuptools" version))
-      (sha256
-       (base32
-        "15ibjdjhkwgj6qbmpsxikkqdfsb1550z46fly7dm15ah4bk1wfpv"))
-      (modules '((guix build utils)))
-      (snippet
-       '(begin
-          ;; Remove included binaries which are used to build self-extracting
-          ;; installers for Windows.
-          ;; TODO: Find some way to build them ourself so we can include them.
-          (for-each delete-file (find-files "setuptools" "^(cli|gui).*\\.exe$"))
-          #t))))
-    (build-system python-build-system)
-    ;; FIXME: Tests require pytest, which itself relies on setuptools.
-    ;; One could bootstrap with an internal untested setuptools.
-    (arguments
-     `(#:tests? #f))
-    (home-page "https://pypi.org/project/setuptools/")
-    (synopsis
-     "Library designed to facilitate packaging Python projects")
-    (description
-     "Setuptools is a fully-featured, stable library designed to facilitate
-packaging Python projects, where packaging includes:
-Python package and module definitions,
-distribution package metadata,
-test hooks,
-project installation,
-platform-specific details,
-Python 3 support.")
-    ;; TODO: setuptools now bundles the following libraries:
-    ;; packaging, pyparsing, six and appdirs. How to unbundle?
-    (license (list license:psfl        ; setuptools itself
-                   license:expat       ; six, appdirs, pyparsing
-                   license:asl2.0      ; packaging is dual ASL2/BSD-2
-                   license:bsd-2))
-    (properties `((python2-variant . ,(delay python2-setuptools))))))
-
-;; Newer versions of setuptools no longer support Python 2.
-(define-public python2-setuptools
-  (package
-    (name "python2-setuptools")
-    (version "41.0.1")
-    (source
-     (origin
-       (method url-fetch)
-       (uri (pypi-uri "setuptools" version ".zip"))
-       (sha256
-        (base32
-         "04sns22y2hhsrwfy1mha2lgslvpjsjsz8xws7h2rh5a7ylkd28m2"))
-       (modules '((guix build utils)))
-       (snippet
-        '(begin
-           ;; Remove included binaries which are used to build self-extracting
-           ;; installers for Windows.
-           ;; TODO: Find some way to build them ourself so we can include them.
-           (for-each delete-file (find-files "setuptools" "^(cli|gui).*\\.exe$"))
-           #t))))
-    (build-system python-build-system)
-    ;; FIXME: Tests require pytest, which itself relies on setuptools.
-    ;; One could bootstrap with an internal untested setuptools.
-    (arguments
-     `(#:tests? #f))
-    (native-inputs
-     (list unzip))
-    (home-page "https://pypi.org/project/setuptools/")
-    (synopsis
-     "Library designed to facilitate packaging Python projects")
-    (description
-     "Setuptools is a fully-featured, stable library designed to facilitate
-packaging Python projects, where packaging includes:
-Python package and module definitions,
-distribution package metadata,
-test hooks,
-project installation,
-platform-specific details,
-Python 3 support.")
-    ;; TODO: setuptools now bundles the following libraries:
-    ;; packaging, pyparsing, six and appdirs. How to unbundle?
-    (license (list license:psfl         ; setuptools itself
-                   license:expat        ; six, appdirs, pyparsing
-                   license:asl2.0       ; packaging is dual ASL2/BSD-2
-                   license:bsd-2))))
-
 (define-public python-setuptools-declarative-requirements
   (package
     (name "python-setuptools-declarative-requirements")
-- 
2.35.1

>From 9a120ae0f1791410e41951982ea3f44ad602dfec Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <[email-masked]>
Date: Sat, 23 Apr 2022 11:36:55 +0200
Subject: [PATCH v3 003/150] python-build-system: Use PEP 517-compatible
 builds.

This is effectively an entire rewrite of python-build-system. It supports
all PEP 517-compatible build backends.

* gnu/packages/python-commencement.scm: New file containing new Python
toolchain package(s).
* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
* gnu/packages/python-build.scm (python-setuptools-bootstrap): New variable.
(python2-setuptools-bootstrap): New variable.
(python-wheel): Break bootstrap cycle.
(python-wheel-bootstrap): New variable.
(python2-wheel-bootstrap): New variable.
* gnu/packages/python.scm (python-2.7): Do not install setuptools and pip.
* guix/build-system/python.scm (%python-build-system-modules): Use
(guix build json).
(default-python): Default to python-toolchain-for-build.
(lower): Add default wheel output, remove test-target and
use-setuptools? flags, add build-backend, test-backend and test-flags.
* guix/build/python-build-system.scm: Rewrite build system.
---
 gnu/local.mk                       |   1 +
 gnu/packages/python-build.scm      | 104 ++++++-
 gnu/packages/python.scm            |   2 +-
 guix/build-system/python.scm       |  26 +-
 guix/build/python-build-system.scm | 436 +++++++++++++++++++----------
 5 files changed, 397 insertions(+), 172 deletions(-)

diff --git a/gnu/local.mk b/gnu/local.mk
index 0e721236d9..4298a2621b 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -495,6 +495,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/packages/python.scm			\
   %D%/packages/python-build.scm			\
   %D%/packages/python-check.scm			\
+  %D%/packages/python-commencement.scm		\
   %D%/packages/python-compression.scm		\
   %D%/packages/python-crypto.scm		\
   %D%/packages/python-science.scm		\
diff --git a/gnu/packages/python-build.scm b/gnu/packages/python-build.scm
index f167c3953f..e23382972c 100644
--- a/gnu/packages/python-build.scm
+++ b/gnu/packages/python-build.scm
@@ -29,7 +29,9 @@ (define-module (gnu packages python-build)
   #:use-module (guix gexp)
   #:use-module (guix download)
   #:use-module (guix git-download)
-  #:use-module (guix packages))
+  #:use-module (guix packages)
+  #:use-module (gnu packages)
+  #:use-module (gnu packages python))
 
 ;;; Commentary:
 ;;;
@@ -58,11 +60,23 @@ (define-public python-setuptools
           ;; TODO: Find some way to build them ourself so we can include them.
           (for-each delete-file (find-files "setuptools" "^(cli|gui).*\\.exe$"))
           #t))))
+    (outputs '("out" "wheel"))
     (build-system python-build-system)
     ;; FIXME: Tests require pytest, which itself relies on setuptools.
     ;; One could bootstrap with an internal untested setuptools.
     (arguments
-     `(#:tests? #f))
+     `(#:tests? #f
+       #:python ,python-wrapper ; Break cycle with default build system’s setuptools dependency.
+       #:phases (modify-phases %standard-phases
+                  ;; Use this setuptools’ sources to bootstrap themselves.
+                  (add-before 'build 'set-PYTHONPATH
+                    (lambda _
+                      (format #t "current working dir ~s~%" (getcwd))
+                      (setenv "GUIX_PYTHONPATH"
+                              (string-append ".:" (getenv "GUIX_PYTHONPATH")))
+                      #t)))))
+    ;; Required to build wheels.
+    (propagated-inputs `(("python-wheel" ,python-wheel)))
     (home-page "https://pypi.org/project/setuptools/")
     (synopsis
      "Library designed to facilitate packaging Python projects")
@@ -83,6 +97,14 @@ (define-public python-setuptools
                    license:bsd-2))
     (properties `((python2-variant . ,(delay python2-setuptools))))))
 
+;; Break loop between python-setuptools and python-wheel.
+(define-public python-setuptools-bootstrap
+  (package
+    (inherit python-setuptools)
+    (name "python-setuptools-bootstrap")
+    (propagated-inputs `(("python-wheel" ,python-wheel-bootstrap)))
+    (properties `((python2-variant . ,(delay python2-setuptools-bootstrap))))))
+
 ;; Newer versions of setuptools no longer support Python 2.
 (define-public python2-setuptools
   (package
@@ -107,9 +129,10 @@ (define-public python2-setuptools
     ;; FIXME: Tests require pytest, which itself relies on setuptools.
     ;; One could bootstrap with an internal untested setuptools.
     (arguments
-     `(#:tests? #f))
-    (native-inputs
-     (list unzip))
+     `(#:tests? #f
+       #:python ,python-2 ; Break loop to python2-toolchain-for-build
+       ))
+    (propagated-inputs `(("python2-wheel" ,python2-wheel)))
     (home-page "https://pypi.org/project/setuptools/")
     (synopsis
      "Library designed to facilitate packaging Python projects")
@@ -129,6 +152,12 @@ (define-public python2-setuptools
                    license:asl2.0       ; packaging is dual ASL2/BSD-2
                    license:bsd-2))))
 
+(define-public python2-setuptools-bootstrap
+  (package
+    (inherit python2-setuptools)
+    (name "python2-setuptools-bootstrap")
+    (propagated-inputs `(("python2-wheel" ,python2-wheel-bootstrap)))))
+
 (define-public python-wheel
   (package
     (name "python-wheel")
@@ -142,10 +171,8 @@ (define-public python-wheel
           "1bbga5i49rj1cwi4sjpkvfhl1f8vl9lfky2lblsy768nk4wp5vz2"))))
     (build-system python-build-system)
     (arguments
-     ;; FIXME: The test suite runs "python setup.py bdist_wheel", which in turn
-     ;; fails to find the newly-built bdist_wheel library, even though it is
-     ;; available on PYTHONPATH.  What search path is consulted by setup.py?
-     '(#:tests? #f))
+     `(#:python ,python-wrapper)) ; Break cycle with python-toolchain-for-build.
+    (native-inputs `(("python-setuptools" ,python-setuptools-bootstrap)))
     (home-page "https://bitbucket.org/pypa/wheel/")
     (synopsis "Format for built Python packages")
     (description
@@ -158,8 +185,65 @@ (define-public python-wheel
 installed with a newer @code{pip} or with wheel's own command line utility.")
     (license license:expat)))
 
+(define-public python-wheel-bootstrap
+  (package
+    (inherit python-wheel)
+    (name "python-wheel-bootstrap")
+    (build-system copy-build-system)
+    (native-inputs '()) ; Break cycle to setuptools.
+    (arguments
+     `(#:install-plan
+       ;; XXX: Do not hard-code Python version.
+       '(("src/wheel" "lib/python3.9/site-packages/wheel"))
+       #:phases
+       (modify-phases %standard-phases
+         ;; Add metadata for setuptools, so it will find the wheel-building code.
+         (add-after 'install 'install-metadata
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (site-dir (string-append out "/lib/python3.9/site-packages"))
+                    (metadata-dir (string-append site-dir "/wheel.egg-info")))
+               (mkdir-p metadata-dir)
+               (call-with-output-file (string-append metadata-dir "/entry_points.txt")
+                 (lambda (port)
+                   (format port "~
+                           [distutils.commands]~@
+                           bdist_wheel = wheel.bdist_wheel:bdist_wheel~%")))))))))
+    (properties `((python2-variant . ,(delay python2-wheel-bootstrap))))))
+
 (define-public python2-wheel
-  (package-with-python2 python-wheel))
+  (package
+    (inherit (package-with-python2 python-wheel))
+    (arguments `(#:python ,python-2))))
+
+(define-public python2-wheel-bootstrap
+  (package
+    (inherit python2-wheel)
+    (name "python2-wheel-bootstrap")
+    (build-system copy-build-system)
+    (native-inputs '()) ; Break cycle to setuptools.
+    (arguments
+     `(#:install-plan
+       ;; XXX: Do not hard-code Python version.
+       '(("src/wheel" "lib/python2.7/site-packages/wheel"))
+       #:phases
+       (modify-phases %standard-phases
+         ;; Add metadata for setuptools, so it will find the wheel-building code.
+         (add-after 'install 'install-metadata
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (site-dir (string-append out "/lib/python2.7/site-packages"))
+                    (metadata-dir (string-append site-dir "/wheel.egg-info")))
+               (mkdir-p metadata-dir)
+               (call-with-output-file (string-append metadata-dir "/entry_points.txt")
+                 (lambda (port)
+                   (format port "~
+                           [distutils.commands]~@
+                           bdist_wheel = wheel.bdist_wheel:bdist_wheel~%")))
+               (call-with-output-file (string-append metadata-dir "/PKG-INFO")
+                 (lambda (port)
+                   (format port "~
+                           Version: ~a" (version))))))))))))
 
 ;;; XXX: Not really at home, but this seems the best place to prevent circular
 ;;; module dependencies.
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 3bc3346c21..4399d30aad 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -183,7 +183,7 @@ (define-public python-2.7
        (list "--enable-shared"          ;allow embedding
              "--with-system-expat"      ;for XML support
              "--with-system-ffi"        ;build ctypes
-             "--with-ensurepip=install" ;install pip and setuptools
+             "--with-ensurepip=no"      ;do not install pip and setuptools
              "--with-computed-gotos"    ;main interpreter loop optimization
              "--enable-unicode=ucs4"
 
diff --git a/guix/build-system/python.scm b/guix/build-system/python.scm
index efade6f74b..aad861d278 100644
--- a/guix/build-system/python.scm
+++ b/guix/build-system/python.scm
@@ -62,18 +62,19 @@ (define* (pypi-uri name version #:optional (extension ".tar.gz"))
 (define %python-build-system-modules
   ;; Build-side modules imported by default.
   `((guix build python-build-system)
+    (guix build json)
     ,@%gnu-build-system-modules))
 
 (define (default-python)
   "Return the default Python package."
   ;; Lazily resolve the binding to avoid a circular dependency.
-  (let ((python (resolve-interface '(gnu packages python))))
-    (module-ref python 'python-wrapper)))
+  (let ((python (resolve-interface '(gnu packages python-commencement))))
+    (module-ref python 'python-toolchain-for-build)))
 
 (define (default-python2)
   "Return the default Python 2 package."
-  (let ((python (resolve-interface '(gnu packages python))))
-    (module-ref python 'python-2)))
+  (let ((python (resolve-interface '(gnu packages python-commencement))))
+    (module-ref python 'python2-toolchain-for-build)))
 
 (define sanity-check.py
   ;; The script used to validate the installation of a Python package.
@@ -165,26 +166,26 @@ (define private-keywords
          (build-inputs `(("python" ,python)
                          ("sanity-check.py" ,(local-file sanity-check.py))
                          ,@native-inputs))
-         (outputs outputs)
+         (outputs (append outputs '(wheel)))
          (build python-build)
          (arguments (strip-keyword-arguments private-keywords arguments)))))
 
 (define* (python-build name inputs
                        #:key source
                        (tests? #t)
-                       (test-target "test")
-                       (use-setuptools? #t)
                        (configure-flags ''())
+                       (build-backend #f)
+                       (test-backend #f)
+                       (test-flags #f)
                        (phases '%standard-phases)
-                       (outputs '("out"))
+                       (outputs '("out" "wheel"))
                        (search-paths '())
                        (system (%current-system))
                        (guile #f)
                        (imported-modules %python-build-system-modules)
                        (modules '((guix build python-build-system)
                                   (guix build utils))))
-  "Build SOURCE using PYTHON, and with INPUTS.  This assumes that SOURCE
-provides a 'setup.py' file as its build system."
+  "Build SOURCE using PYTHON, and with INPUTS."
   (define build
     (with-imported-modules imported-modules
       #~(begin
@@ -194,9 +195,10 @@ (define build
               #~(python-build #:name #$name
                               #:source #+source
                               #:configure-flags #$configure-flags
-                              #:use-setuptools? #$use-setuptools?
                               #:system #$system
-                              #:test-target #$test-target
+                              #:build-backend #$build-backend
+                              #:test-backend #$test-backend
+                              #:test-flags #$test-flags
                               #:tests? #$tests?
                               #:phases #$(if (pair? phases)
                                              (sexp->gexp phases)
diff --git a/guix/build/python-build-system.scm b/guix/build/python-build-system.scm
index 08871f60cd..15cbdd4e7c 100644
--- a/guix/build/python-build-system.scm
+++ b/guix/build/python-build-system.scm
@@ -30,11 +30,16 @@
 (define-module (guix build python-build-system)
   #:use-module ((guix build gnu-build-system) #:prefix gnu:)
   #:use-module (guix build utils)
+  #:use-module (guix build json)
   #:use-module (ice-9 match)
   #:use-module (ice-9 ftw)
   #:use-module (ice-9 format)
+  #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 regex)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-26)
+  #:use-module (srfi srfi-34)
+  #:use-module (srfi srfi-35)
   #:export (%standard-phases
             add-installed-pythonpath
             site-packages
@@ -43,96 +48,45 @@ (define-module (guix build python-build-system)
 
 ;; Commentary:
 ;;
-;; Builder-side code of the standard Python package build procedure.
+;; PEP 517-compatible build system for Python packages.
 ;;
+;; PEP 517 mandates the use of a TOML file called pyproject.toml at the
+;; project root, describing build and runtime dependencies, as well as the
+;; build system, which can be different from setuptools. This module uses
+;; that file to extract the build system used and call its wheel-building
+;; entry point build_wheel (see 'build). setuptools’ wheel builder is
+;; used as a fallback if either no pyproject.toml exists or it does not
+;; declare a build-system. It supports config_settings through the
+;; standard #:configure-flags argument.
 ;;
-;; Backgound about the Python installation methods
+;; This wheel, which is just a ZIP file with a file structure defined
+;; by PEP 427 (https://www.python.org/dev/peps/pep-0427/), is then unpacked
+;; and its contents are moved to the appropriate locations in 'install.
 ;;
-;; In Python there are different ways to install packages: distutils,
-;; setuptools, easy_install and pip.  All of these are sharing the file
-;; setup.py, introduced with distutils in Python 2.0. The setup.py file can be
-;; considered as a kind of Makefile accepting targets (or commands) like
-;; "build" and "install".  As of autumn 2016 the recommended way to install
-;; Python packages is using pip.
+;; Then entry points, as defined by the PyPa Entry Point Specification
+;; (https://packaging.python.org/specifications/entry-points/) are read
+;; from a file called entry_points.txt in the package’s site-packages
+;; subdirectory and scripts are written to bin/. These are not part of a
+;; wheel and expected to be created by the installing utility.
 ;;
-;; For both distutils and setuptools, running "python setup.py install" is the
-;; way to install Python packages.  With distutils the "install" command
-;; basically copies all packages into <prefix>/lib/pythonX.Y/site-packages.
-;;
-;; Some time later "setuptools" was established to enhance distutils.  To use
-;; setuptools, the developer imports setuptools in setup.py.  When importing
-;; setuptools, the original "install" command gets overwritten by setuptools'
-;; "install" command.
-;;
-;; The command-line tools easy_install and pip are both capable of finding and
-;; downloading the package source from PyPI (the Python Package Index).  Both
-;; of them import setuptools and execute the "setup.py" file under their
-;; control.  Thus the "setup.py" behaves as if the developer had imported
-;; setuptools within setup.py - even is still using only distutils.
-;;
-;; Setuptools' "install" command (to be more precise: the "easy_install"
-;; command which is called by "install") will put the path of the currently
-;; installed version of each package and it's dependencies (as declared in
-;; setup.py) into an "easy-install.pth" file.  In Guix each packages gets its
-;; own "site-packages" directory and thus an "easy-install.pth" of its own.
-;; To avoid conflicts, the python build system renames the file to
-;; <packagename>.pth in the phase rename-pth-file.  To ensure that Python will
-;; process the .pth file, easy_install also creates a basic "site.py" in each
-;; "site-packages" directory.  The file is the same for all packages, thus
-;; there is no need to rename it.  For more information about .pth files and
-;; the site module, please refere to
-;; https://docs.python.org/3/library/site.html.
-;;
-;; The .pth files contain the file-system paths (pointing to the store) of all
-;; dependencies.  So the dependency is hidden in the .pth file but is not
-;; visible in the file-system.  Now if packages A and B both required packages
-;; P, but in different versions, Guix will not detect this when installing
-;; both A and B to a profile. (For details and example see
-;; https://lists.gnu.org/archive/html/guix-devel/2016-10/msg01233.html.)
-;;
-;; Pip behaves a bit different then easy_install: it always executes
-;; "setup.py" with the option "--single-version-externally-managed" set.  This
-;; makes setuptools' "install" command run the original "install" command
-;; instead of the "easy_install" command, so no .pth file (and no site.py)
-;; will be created.  The "site-packages" directory only contains the package
-;; and the related .egg-info directory.
-;;
-;; This is exactly what we need for Guix and this is what we mimic in the
-;; install phase below.
-;;
-;; As a draw back, the magic of the .pth file of linking to the other required
-;; packages is gone and these packages have now to be declared as
-;; "propagated-inputs".
-;;
-;; Note: Importing setuptools also adds two sub-commands: "install_egg_info"
-;; and "install_scripts".  These sub-commands are executed even if
-;; "--single-version-externally-managed" is set, thus the .egg-info directory
-;; and the scripts defined in entry-points will always be created.
-
-
-(define setuptools-shim
-  ;; Run setup.py with "setuptools" being imported, which will patch
-  ;; "distutils". This is needed for packages using "distutils" instead of
-  ;; "setuptools" since the former does not understand the
-  ;; "--single-version-externally-managed" flag.
-  ;; Python code taken from pip 9.0.1 pip/utils/setuptools_build.py
-  (string-append
-   "import setuptools, tokenize;__file__='setup.py';"
-   "f=getattr(tokenize, 'open', open)(__file__);"
-   "code=f.read().replace('\\r\\n', '\\n');"
-   "f.close();"
-   "exec(compile(code, __file__, 'exec'))"))
-
-(define (call-setuppy command params use-setuptools?)
-  (if (file-exists? "setup.py")
-      (begin
-         (format #t "running \"python setup.py\" with command ~s and parameters ~s~%"
-                command params)
-         (if use-setuptools?
-             (apply invoke "python" "-c" setuptools-shim
-                    command params)
-             (apply invoke "python" "./setup.py" command params)))
-      (error "no setup.py found")))
+;; Caveats:
+;; - There is no support for in-tree build backends.
+
+;; Base error type.
+(define-condition-type &python-build-error &error
+  python-build-error?)
+
+;; Raised when 'check cannot find a valid test system in the inputs.
+(define-condition-type &test-system-not-found &python-build-error
+  test-system-not-found?)
+
+;; Raised when multiple wheels are created by 'build.
+(define-condition-type &cannot-extract-multiple-wheels &python-build-error
+  cannot-extract-multiple-wheels?)
+
+;; Raised, when no wheel has been built by the build system.
+(define-condition-type &no-wheels-built &python-build-error
+  no-wheels-built?)
 
 (define* (sanity-check #:key tests? inputs outputs #:allow-other-keys)
   "Ensure packages depending on this package via setuptools work properly,
@@ -143,25 +97,83 @@ (define* (sanity-check #:key tests? inputs outputs #:allow-other-keys)
     (with-directory-excursion "/tmp"
       (invoke "python" sanity-check.py (site-packages inputs outputs)))))
 
-(define* (build #:key use-setuptools? #:allow-other-keys)
+(define* (build #:key outputs build-backend configure-flags #:allow-other-keys)
   "Build a given Python package."
-  (call-setuppy "build" '() use-setuptools?)
-  #t)
 
-(define* (check #:key tests? test-target use-setuptools? #:allow-other-keys)
+  (define (pyproject.toml->build-backend file)
+    "Look up the build backend in a pyproject.toml file."
+    (call-with-input-file file
+      (lambda (in)
+        (let loop ((line (read-line in 'concat)))
+          (if (eof-object? line)
+              #f
+              (let ((m (string-match "build-backend = [\"'](.+)[\"']" line)))
+                (if m (match:substring m 1)
+                    (loop (read-line in 'concat)))))))))
+
+  (let* ((wheel-output (assoc-ref outputs "wheel"))
+         (wheel-dir (if wheel-output wheel-output "dist"))
+         ;; There is no easy way to get data from Guile into Python via
+         ;; s-expressions, but we have JSON serialization already, which Python
+         ;; also supports out-of-the-box.
+         (config-settings (call-with-output-string (cut write-json configure-flags <>)))
+         ;; python-setuptools’ default backend supports setup.py *and*
+         ;; pyproject.toml. Allow overriding this automatic detection via
+         ;; build-backend.
+         (auto-build-backend (if (file-exists? "pyproject.toml")
+                               (pyproject.toml->build-backend "pyproject.toml")
+                               #f))
+         ;; Use build system detection here and not in importer, because a) we
+         ;; have alot of legacy packages and b) the importer cannot update arbitrary
+         ;; fields in case a package switches its build system.
+         (use-build-backend (or
+                              build-backend
+                              auto-build-backend
+                              "setuptools.build_meta")))
+    (format #t "Using '~a' to build wheels, auto-detected '~a', override '~a'.~%"
+               use-build-backend auto-build-backend build-backend)
+    (mkdir-p wheel-dir)
+    ;; Call the PEP 517 build function, which drops a .whl into wheel-dir.
+    (invoke "python" "-c" "import sys, importlib, json
+config_settings = json.loads (sys.argv[3])
+builder = importlib.import_module(sys.argv[1])
+builder.build_wheel(sys.argv[2], config_settings=config_settings)"
+            use-build-backend wheel-dir config-settings)))
+
+(define* (check #:key inputs outputs tests? test-backend test-flags #:allow-other-keys)
   "Run the test suite of a given Python package."
   (if tests?
-      ;; Running `setup.py test` creates an additional .egg-info directory in
-      ;; build/lib in some cases, e.g. if the source is in a sub-directory
-      ;; (given with `package_dir`). This will by copied to the output, too,
-      ;; so we need to remove.
-      (let ((before (find-files "build" "\\.egg-info$" #:directories? #t)))
-        (call-setuppy test-target '() use-setuptools?)
-        (let* ((after (find-files "build" "\\.egg-info$" #:directories? #t))
-               (inter (lset-difference string=? after before)))
-          (for-each delete-file-recursively inter)))
-      (format #t "test suite not run~%"))
-  #t)
+    ;; Unfortunately with PEP 517 there is no common method to specify test
+    ;; systems. Guess test system based on inputs instead.
+    (let* ((pytest (which "pytest"))
+           (nosetests (which "nosetests"))
+           (nose2 (which "nose2"))
+           (have-setup-py (file-exists? "setup.py"))
+           (use-test-backend
+            (or
+              test-backend
+              ;; Prefer pytest
+              (if pytest 'pytest #f)
+              (if nosetests 'nose #f)
+              (if nose2 'nose2 #f)
+              ;; But fall back to setup.py, which should work for most
+              ;; packages. XXX: would be nice not to depend on setup.py here? fails
+              ;; more often than not to find any tests at all. Maybe we can run
+              ;; `python -m unittest`?
+              (if have-setup-py 'setup.py #f))))
+        (format #t "Using ~a~%" use-test-backend)
+        (match use-test-backend
+          ('pytest
+           (apply invoke (cons pytest (or test-flags '("-vv")))))
+          ('nose
+           (apply invoke (cons nosetests (or test-flags '("-v")))))
+          ('nose2
+           (apply invoke (cons nose2 (or test-flags '("-v" "--pretty-assert")))))
+          ('setup.py
+           (apply invoke (append '("python" "setup.py") (or test-flags '("test" "-v")))))
+          ;; The developer should explicitly disable tests in this case.
+          (else (raise (condition (&test-system-not-found))))))
+      (format #t "test suite not run~%")))
 
 (define (python-version python)
   (let* ((version     (last (string-split python #\-)))
@@ -196,33 +208,175 @@ (define* (add-install-to-path #:key outputs #:allow-other-keys)
                                 "/bin:"
                                 (getenv "PATH"))))
 
-(define* (install #:key inputs outputs (configure-flags '()) use-setuptools?
-                  #:allow-other-keys)
-  "Install a given Python package."
-  (let* ((out (python-output outputs))
+(define* (install #:key inputs outputs (configure-flags '()) #:allow-other-keys)
+  "Install a wheel file according to PEP 427"
+  ;; See https://www.python.org/dev/peps/pep-0427/#installing-a-wheel-distribution-1-0-py32-none-any-whl
+  (let* ((site-dir (site-packages inputs outputs))
+         (python (assoc-ref inputs "python"))
+         (out (assoc-ref outputs "out")))
+    (define (extract file)
+      "Extract wheel (ZIP file) into site-packages directory"
+      ;; Use Python’s zipfile to avoid extra dependency
+      (invoke "python" "-m" "zipfile" "-e" file site-dir))
+
+    (define python-hashbang
+      (string-append "#!" python "/bin/python"))
+
+    (define* (merge-directories source destination #:optional (post-move #f))
+      "Move all files in SOURCE into DESTINATION, merging the two directories."
+      (format #t "Merging directory ~a into ~a~%" source destination)
+      (for-each
+        (lambda (file)
+          (format #t "~a/~a -> ~a/~a~%" source file destination file)
+          (mkdir-p destination)
+          (rename-file
+              (string-append source "/" file)
+              (string-append destination "/" file))
+          (when post-move
+            (post-move file)))
+        (scandir source (negate (cut member <> '("." "..")))))
+      (rmdir source))
+
+    (define (expand-data-directory directory)
+      "Move files from all .data subdirectories to their respective
+destinations."
+      ;; Python’s distutils.command.install defines this mapping from source to
+      ;; destination mapping.
+      (let ((source (string-append directory "/scripts"))
+            (destination (string-append out "/bin")))
+        (when (file-exists? source)
+          (merge-directories
+           source
+           destination
+           (lambda (f)
+             (let ((dest-path (string-append destination "/" f)))
+               (chmod dest-path #o755)
+               (substitute* dest-path (("#!python") python-hashbang)))))))
+      ;; data can create arbitrary directory structures. Most commonly
+      ;; it is used for share/.
+      (let ((source (string-append directory "/data"))
+            (destination out))
+        (when (file-exists? source)
+          (merge-directories source destination)))
+      (let* ((distribution (car (string-split (basename directory) #\-)))
+            (source (string-append directory "/headers"))
+            (destination (string-append out "/include/python" (python-version python) "/" distribution)))
+        (when (file-exists? source)
+          (merge-directories source destination))))
+    
+  (define (list-directories base predicate)
+    ;; Cannot use find-files here, because it’s recursive.
+    (scandir
+      base
+      (lambda (name)
+        (let ((stat (lstat (string-append base "/" name))))
+        (and
+          (not (member name '("." "..")))
+          (eq? (stat:type stat) 'directory)
+          (predicate name stat))))))
+
+  (let* ((wheel-output (assoc-ref outputs "wheel"))
+         (wheel-dir (if wheel-output wheel-output "dist"))
+         (wheels (map (cut string-append wheel-dir "/" <>)
+                      (scandir wheel-dir (cut string-suffix? ".whl" <>)))))
+    (cond
+    ((> (length wheels) 1) ; This code does not support multiple wheels
+                                ; yet, because their outputs would have to be
+                                ; merged properly.
+      (raise (condition (&cannot-extract-multiple-wheels))))
+      ((= (length wheels) 0)
+       (raise (condition (&no-wheels-built)))))
+    (for-each extract wheels))
+  (let ((datadirs (map
+                    (cut string-append site-dir "/" <>)
+                    (list-directories site-dir (file-name-predicate "\\.data$")))))
+    (for-each (lambda (directory)
+                (expand-data-directory directory)
+                (rmdir directory))
+              datadirs))))
+
+(define* (compile-bytecode #:key inputs outputs (configure-flags '()) #:allow-other-keys)
+  "Compile installed byte-code in site-packages."
+  (let* ((site-dir (site-packages inputs outputs))
          (python (assoc-ref inputs "python"))
          (major-minor (map string->number
                            (take (string-split (python-version python) #\.) 2)))
          (<3.7? (match major-minor
                    ((major minor)
-                    (or (< major 3) (and (= major 3) (< minor 7))))))
-         (params (append (list (string-append "--prefix=" out)
-                               "--no-compile")
-                         (if use-setuptools?
-                             ;; distutils does not accept these flags
-                             (list "--single-version-externally-managed"
-                                   "--root=/")
-                             '())
-                         configure-flags)))
-    (call-setuppy "install" params use-setuptools?)
-    ;; Rather than produce potentially non-reproducible .pyc files on Pythons
-    ;; older than 3.7, whose 'compileall' module lacks the
-    ;; '--invalidation-mode' option, do not generate any.
-    (unless <3.7?
-      (invoke "python" "-m" "compileall" "--invalidation-mode=unchecked-hash"
-              out))))
-
-(define* (wrap #:key inputs outputs #:allow-other-keys)
+                    (or (< major 3) (and (= major 3) (< minor 7)))))))
+    (if <3.7?
+      ;; These versions don’t have the hash invalidation modes and do
+      ;; not produce reproducible bytecode files.
+      (format #t "Skipping bytecode compilation for Python version ~a < 3.7~%" (python-version python))
+      (invoke "python" "-m" "compileall" "--invalidation-mode=unchecked-hash" site-dir))))
+
+(define* (create-entrypoints #:key inputs outputs (configure-flags '()) #:allow-other-keys)
+  "Implement Entry Points Specification
+(https://packaging.python.org/specifications/entry-points/) by PyPa,
+which creates runnable scripts in bin/ from entry point specification
+file entry_points.txt. This is necessary, because wheels do not contain
+these binaries and installers are expected to create them."
+
+  (define (entry-points.txt->entry-points file)
+    "Specialized parser for Python configfile-like files, in particular
+entry_points.txt. Returns a list of console_script and gui_scripts
+entry points."
+    (call-with-input-file file
+      (lambda (in)
+        (let loop ((line (read-line in))
+                   (inside #f)
+                   (result '()))
+          (if (eof-object? line)
+            result
+            (let* ((group-match (string-match "^\\[(.+)\\]$" line))
+                  (group-name (if group-match (match:substring group-match 1) #f))
+                  (next-inside
+                   (if (not group-name)
+                     inside
+                     (or
+                       (string=? group-name "console_scripts")
+                       (string=? group-name "gui_scripts"))))
+                  (item-match (string-match "^([^ =]+)\\s*=\\s*([^:]+):(.+)$" line)))
+              (if (and inside item-match)
+                (loop (read-line in) next-inside (cons (list
+                                                        (match:substring item-match 1)
+                                                        (match:substring item-match 2)
+                                                        (match:substring item-match 3))
+                                                         result))
+                (loop (read-line in) next-inside result))))))))
+
+  (define (create-script path name module function)
+    "Create a Python script from an entry point’s NAME, MODULE and
+  FUNCTION and return write it to PATH/NAME."
+    (let ((interpreter (which "python"))
+          (file-path (string-append path "/" name)))
+      (format #t "Creating entry point for '~a.~a' at '~a'.~%" module function
+                 file-path)
+      (call-with-output-file file-path
+        (lambda (port)
+          ;; Technically the script could also include search-paths,
+          ;; but having a generic 'wrap phases also handles manually
+          ;; written entry point scripts.
+          (format port "#!~a
+# Auto-generated entry point script.
+import sys
+import ~a as mod
+sys.exit (mod.~a ())~%" interpreter module function)))
+        (chmod file-path #o755)))
+
+  (let* ((site-dir (site-packages inputs outputs))
+         (out (assoc-ref outputs "out"))
+         (bin-dir (string-append out "/bin"))
+         (entry-point-files (find-files site-dir "^entry_points.txt$")))
+    (mkdir-p bin-dir)
+    (for-each
+      (lambda (f)
+        (for-each
+          (lambda (ep) (apply create-script (cons bin-dir ep)))
+          (entry-points.txt->entry-points f)))
+      entry-point-files)))
+
+(define* (wrap #:key inputs outputs search-paths #:allow-other-keys)
   (define (list-of-files dir)
     (find-files dir (lambda (file stat)
                       (and (eq? 'regular (stat:type stat))
@@ -250,29 +404,11 @@ (define (sh) (force %sh))
                             files)))
               bindirs)))
 
-(define* (rename-pth-file #:key name inputs outputs #:allow-other-keys)
-  "Rename easy-install.pth to NAME.pth to avoid conflicts between packages
-installed with setuptools."
-  ;; Even if the "easy-install.pth" is not longer created, we kept this phase.
-  ;; There still may be packages creating an "easy-install.pth" manually for
-  ;; some good reason.
-  (let* ((site-packages (site-packages inputs outputs))
-         (easy-install-pth (string-append site-packages "/easy-install.pth"))
-         (new-pth (string-append site-packages "/" name ".pth")))
-    (when (file-exists? easy-install-pth)
-      (rename-file easy-install-pth new-pth))))
-
-(define* (ensure-no-mtimes-pre-1980 #:rest _)
-  "Ensure that there are no mtimes before 1980-01-02 in the source tree."
-  ;; Rationale: patch-and-repack creates tarballs with timestamps at the POSIX
-  ;; epoch, 1970-01-01 UTC.  This causes problems with Python packages,
-  ;; because Python eggs are ZIP files, and the ZIP format does not support
-  ;; timestamps before 1980.
-  (let ((early-1980 315619200))  ; 1980-01-02 UTC
-    (ftw "." (lambda (file stat flag)
-               (unless (<= early-1980 (stat:mtime stat))
-                 (utime file early-1980 early-1980))
-               #t))))
+(define* (set-SOURCE-DATE-EPOCH #:rest _)
+  "Set the 'SOURCE_DATE_EPOCH' environment variable.  This is used by tools
+that incorporate timestamps as a way to tell them to use a fixed timestamp.
+See https://reproducible-builds.org/specs/source-date-epoch/."
+  (setenv "SOURCE_DATE_EPOCH" "315619200")) ;; python-wheel respects this variable and sets pre-1980 times on files in zip files, which is unsupported
 
 (define* (enable-bytecode-determinism #:rest _)
   "Improve determinism of pyc files."
@@ -299,11 +435,11 @@ (define %standard-phases
   ;; prefix directory.  The check phase is moved after the installation phase
   ;; to ease testing the built package.
   (modify-phases gnu:%standard-phases
-    (add-after 'unpack 'ensure-no-mtimes-pre-1980 ensure-no-mtimes-pre-1980)
-    (add-after 'ensure-no-mtimes-pre-1980 'enable-bytecode-determinism
+    (add-after 'unpack 'enable-bytecode-determinism
       enable-bytecode-determinism)
     (add-after 'enable-bytecode-determinism 'ensure-no-cythonized-files
       ensure-no-cythonized-files)
+    (replace 'set-SOURCE-DATE-EPOCH set-SOURCE-DATE-EPOCH)
     (delete 'bootstrap)
     (delete 'configure)                 ;not needed
     (replace 'build build)
@@ -313,9 +449,11 @@ (define %standard-phases
     (add-after 'add-install-to-pythonpath 'add-install-to-path
       add-install-to-path)
     (add-after 'add-install-to-path 'wrap wrap)
+    ;; must be before tests, so they can use installed packages’ entry points.
+    (add-before 'wrap 'create-entrypoints create-entrypoints)
     (add-after 'wrap 'check check)
     (add-after 'check 'sanity-check sanity-check)
-    (add-before 'strip 'rename-pth-file rename-pth-file)))
+    (add-before 'check 'compile-bytecode compile-bytecode)))
 
 (define* (python-build #:key inputs (phases %standard-phases)
                        #:allow-other-keys #:rest args)
-- 
2.35.1

>From 7e9bea152a81cfe69c4641a26469219a147f1d87 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <[email-masked]>
Date: Sat, 8 Jan 2022 14:56:04 +0100
Subject: [PATCH v3 004/150] gnu: Use %python-build-system-module inside
 #:imported-modules.

It includes (guix build json), which is now required for (guix build
python-build-system).

* gnu/packages/boost.scm (boost): Use %python-build-system-module.
* gnu/packages/cups.scm (hplip): Likewise.
* gnu/packages/djvu.scm (didjvu): Likewise.
* gnu/packages/finance.scm (ledger): Likewise.
* gnu/packages/games.scm (fifengine): Likewise.
* gnu/packages/geo.scm (grass): Likewise.
(qgis): Likewise.
* gnu/packages/gnome.scm (system-config-printer): Likewise.
(gnome-tweaks): Likewise.
(lollypop): Likewise.
(soundconverter): Likewise.
(piper): Likewise.
* gnu/packages/graph.scm (python-graph-tool): Likewise.
* gnu/packages/graphics.scm (lib2geom): Likewise.
* gnu/packages/gstreamer.scm (python-gst): Likewise.
* gnu/packages/julia-xyz.scm (julia-pycall): Likewise.
* gnu/packages/lisp-xyz.scm (sbcl-burgled-batteries3): Likewise.
* gnu/packages/machine-learning.scm (ghmm): Likewise.
(tensorflow): Likewise.
* gnu/packages/maths.scm (nomad-optimizer): Likewise.
(gmsh): Likewise.
(z3): Likewise.
(ocaml-z3): Likewise.
(fp16): Likewise.
(optizelle): Likewise.
* gnu/packages/mpd.scm (sonata): Likewise.
* gnu/packages/music.scm (jack-select): Likewise.
* gnu/packages/networking.scm (opendht): Likewise.
* gnu/packages/openldap.scm (389-ds-base): Likewise.
* gnu/packages/qt.scm (python-sip-4): Likewise.
(python-pyqt): Likewise.
(python-pyqtwebengine): Likewise.
* gnu/packages/radio.scm (gnuradio): Likewise.
(gr-osmosdr): Likewise.
(gr-satellites): Likewise.
* gnu/packages/rpm.scm (libmodulemd): Likewise.
(createrepo-c): Likewise.
* gnu/packages/textutils.scm (opencc): Likewise.
* gnu/packages/version-control.scm (hg-commitsigs): Likewise.
* gnu/packages/virtualization.scm (ganeti): Likewise.
* gnu/packages/vpn.scm (bitmask): Likewise.
* gnu/packages/xdisorg.scm (redshift): Likewise.
---
 gnu/packages/boost.scm            |  3 ++-
 gnu/packages/cups.scm             |  2 +-
 gnu/packages/djvu.scm             |  2 +-
 gnu/packages/finance.scm          |  2 +-
 gnu/packages/geo.scm              |  4 ++--
 gnu/packages/gnome.scm            | 10 +++++-----
 gnu/packages/graph.scm            |  2 +-
 gnu/packages/graphics.scm         |  2 +-
 gnu/packages/gstreamer.scm        |  3 ++-
 gnu/packages/julia-xyz.scm        |  3 ++-
 gnu/packages/lisp-xyz.scm         |  3 ++-
 gnu/packages/machine-learning.scm |  4 ++--
 gnu/packages/maths.scm            | 12 ++++++------
 gnu/packages/mpd.scm              |  2 +-
 gnu/packages/music.scm            |  2 +-
 gnu/packages/networking.scm       |  2 +-
 gnu/packages/openldap.scm         |  2 +-
 gnu/packages/qt.scm               |  6 +++---
 gnu/packages/radio.scm            |  6 +++---
 gnu/packages/rpm.scm              |  5 +++--
 gnu/packages/textutils.scm        |  2 +-
 gnu/packages/version-control.scm  |  2 +-
 gnu/packages/virtualization.scm   |  2 +-
 gnu/packages/vpn.scm              |  2 +-
 gnu/packages/xdisorg.scm          |  2 +-
 25 files changed, 46 insertions(+), 41 deletions(-)

diff --git a/gnu/packages/boost.scm b/gnu/packages/boost.scm
index b53b1f4257..ff9b6a3167 100644
--- a/gnu/packages/boost.scm
+++ b/gnu/packages/boost.scm
@@ -42,6 +42,7 @@ (define-module (gnu packages boost)
   #:use-module (guix download)
   #:use-module (guix git-download)
   #:use-module (guix build-system gnu)
+  #:use-module (guix build-system python)
   #:use-module (guix build-system trivial)
   #:use-module (gnu packages)
   #:use-module (gnu packages compression)
@@ -86,7 +87,7 @@ (define-public boost
              `(("python" ,python-minimal-wrapper)))
        ("tcsh" ,tcsh)))
     (arguments
-     `(#:imported-modules ((guix build python-build-system)
+     `(#:imported-modules (,@%python-build-system-modules
                            ,@%gnu-build-system-modules)
        #:modules (((guix build python-build-system) #:select (python-version))
                   ,@%gnu-build-system-modules)
diff --git a/gnu/packages/cups.scm b/gnu/packages/cups.scm
index da113ac168..3a006c3993 100644
--- a/gnu/packages/cups.scm
+++ b/gnu/packages/cups.scm
@@ -562,7 +562,7 @@ (define-public hplip
                          (assoc-ref %outputs "out") "/etc/xdg")
          "--enable-qt5" "--disable-qt4")
 
-       #:imported-modules ((guix build python-build-system)
+       #:imported-modules (,@%python-build-system-modules
                            ,@%gnu-build-system-modules)
        #:modules ((guix build gnu-build-system)
                   (guix build utils)
diff --git a/gnu/packages/djvu.scm b/gnu/packages/djvu.scm
index 07c77f318e..b5ee1ebe19 100644
--- a/gnu/packages/djvu.scm
+++ b/gnu/packages/djvu.scm
@@ -356,7 +356,7 @@ (define-public didjvu
                   ((guix build python-build-system) #:prefix python:)
                   (guix build utils))
        #:imported-modules (,@%gnu-build-system-modules
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:test-target "test"
        #:phases
        (modify-phases %standard-phases
diff --git a/gnu/packages/finance.scm b/gnu/packages/finance.scm
index 84547639e4..1160fc341b 100644
--- a/gnu/packages/finance.scm
+++ b/gnu/packages/finance.scm
@@ -319,7 +319,7 @@ (define-public ledger
      `(#:modules (,@%cmake-build-system-modules
                   ((guix build python-build-system) #:select (python-version)))
        #:imported-modules (,@%cmake-build-system-modules
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:configure-flags
        `("-DBUILD_DOCS:BOOL=ON"
          "-DBUILD_WEB_DOCS:BOOL=ON"
diff --git a/gnu/packages/geo.scm b/gnu/packages/geo.scm
index c2569c27d4..ec6740ba9a 100644
--- a/gnu/packages/geo.scm
+++ b/gnu/packages/geo.scm
@@ -2182,7 +2182,7 @@ (define-public grass
                     ((guix build python-build-system) #:prefix python:)
                     (guix build utils))
          #:imported-modules (,@%gnu-build-system-modules
-                             (guix build python-build-system))
+                             ,@%python-build-system-modules)
          #:phases
          (modify-phases %standard-phases
            (replace 'configure
@@ -2309,7 +2309,7 @@ (define-public qgis
                   (guix build qt-utils)
                   (guix build utils))
        #:imported-modules (,@%cmake-build-system-modules
-                           (guix build python-build-system)
+                           ,@%python-build-system-modules
                            (guix build qt-utils))
        #:configure-flags
        '("-DWITH_QTWEBKIT=NO")
diff --git a/gnu/packages/gnome.scm b/gnu/packages/gnome.scm
index 19adb67423..a55c54e8cb 100644
--- a/gnu/packages/gnome.scm
+++ b/gnu/packages/gnome.scm
@@ -2941,7 +2941,7 @@ (define-public system-config-printer
     (build-system glib-or-gtk-build-system)
     (arguments
      (list
-      #:imported-modules `((guix build python-build-system)
+      #:imported-modules `(,@%python-build-system-modules
                            ,@%glib-or-gtk-build-system-modules)
       #:phases
       #~(modify-phases %standard-phases
@@ -9935,7 +9935,7 @@ (define-public gnome-tweaks
      `(#:glib-or-gtk? #t
        #:configure-flags '("-Dlocalstatedir=/tmp"
                            "-Dsysconfdir=/tmp")
-       #:imported-modules ((guix build python-build-system)
+       #:imported-modules (,@%python-build-system-modules
                            ,@%meson-build-system-modules)
        #:phases
        (modify-phases %standard-phases
@@ -10629,7 +10629,7 @@ (define-public lollypop
     (arguments
      `(#:imported-modules
        (,@%meson-build-system-modules
-        (guix build python-build-system))
+        ,@%python-build-system-modules)
        #:modules
        ((guix build meson-build-system)
         ((guix build python-build-system) #:prefix python:)
@@ -10889,7 +10889,7 @@ (define-public soundconverter
         (base32 "1jv8m82hi23ilrgdznlc1jhp2jm8bw1yrw0chh3qw2l0sixvkl11"))))
     (build-system glib-or-gtk-build-system)
     (arguments
-     `(#:imported-modules ((guix build python-build-system)
+     `(#:imported-modules (,@%python-build-system-modules
                            (guix build glib-or-gtk-build-system)
                            ,@%gnu-build-system-modules)
 
@@ -12133,7 +12133,7 @@ (define-public piper
            python-pycairo
            python-pygobject))
     (arguments
-     `(#:imported-modules ((guix build python-build-system)
+     `(#:imported-modules (,@%python-build-system-modules
                            ,@%meson-build-system-modules)
        #:modules (((guix build python-build-system) #:prefix python:)
                   (guix build meson-build-system)
diff --git a/gnu/packages/graph.scm b/gnu/packages/graph.scm
index 981c4d4793..1e5e64de62 100644
--- a/gnu/packages/graph.scm
+++ b/gnu/packages/graph.scm
@@ -621,7 +621,7 @@ (define-public python-graph-tool
     (build-system gnu-build-system)
     (arguments
      `(#:imported-modules (,@%gnu-build-system-modules
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:modules (,@%gnu-build-system-modules
                   ((guix build python-build-system) #:select (site-packages)))
        #:configure-flags
diff --git a/gnu/packages/graphics.scm b/gnu/packages/graphics.scm
index 2cc75d57cf..b48b105d68 100644
--- a/gnu/packages/graphics.scm
+++ b/gnu/packages/graphics.scm
@@ -752,7 +752,7 @@ (define-public lib2geom
                 "03bx9k1m4bfhmx0ldsg0bks6i8h7fmvl5vbg6gmpq0bk0nkmpnmv"))))
     (build-system cmake-build-system)
     (arguments
-     `(#:imported-modules ((guix build python-build-system)
+     `(#:imported-modules (,@%python-build-system-modules
                            ,@%cmake-build-system-modules)
        #:configure-flags '("-D2GEOM_BUILD_SHARED=ON"
                            "-D2GEOM_BOOST_PYTHON=ON"
diff --git a/gnu/packages/gstreamer.scm b/gnu/packages/gstreamer.scm
index 8b01c9b04b..1df699b6fe 100644
--- a/gnu/packages/gstreamer.scm
+++ b/gnu/packages/gstreamer.scm
@@ -34,6 +34,7 @@ (define-module (gnu packages gstreamer)
   #:use-module (guix build-system cmake)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system meson)
+  #:use-module (guix build-system python)
   #:use-module (guix build-system trivial)
   #:use-module (guix utils)
   #:use-module (gnu packages)
@@ -1072,7 +1073,7 @@ (define-public python-gst
                   (guix build utils)
                   ((guix build python-build-system) #:prefix python:))
        #:imported-modules (,@%meson-build-system-modules
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:configure-flags
        (list (string-append
               "-Dpygi-overrides-dir="
diff --git a/gnu/packages/julia-xyz.scm b/gnu/packages/julia-xyz.scm
index 5d45c07115..ab0b8a37b4 100644
--- a/gnu/packages/julia-xyz.scm
+++ b/gnu/packages/julia-xyz.scm
@@ -28,6 +28,7 @@ (define-module (gnu packages julia-xyz)
   #:use-module (guix packages)
   #:use-module (guix git-download)
   #:use-module (guix build-system julia)
+  #:use-module (guix build-system python)
   #:use-module (gnu packages gcc)
   #:use-module (gnu packages julia-jll)
   #:use-module (gnu packages python)
@@ -4160,7 +4161,7 @@ (define-public julia-pycall
     (build-system julia-build-system)
     (arguments
      (list
-      #:imported-modules `((guix build python-build-system)
+      #:imported-modules `(,@%python-build-system-modules
                            ,@%julia-build-system-modules)
       #:modules '((guix build julia-build-system)
                   (guix build utils)
diff --git a/gnu/packages/lisp-xyz.scm b/gnu/packages/lisp-xyz.scm
index 9317108f4c..263dd29234 100644
--- a/gnu/packages/lisp-xyz.scm
+++ b/gnu/packages/lisp-xyz.scm
@@ -64,6 +64,7 @@ (define-module (gnu packages lisp-xyz)
   #:use-module (guix utils)
   #:use-module (guix build-system asdf)
   #:use-module (guix build-system gnu)
+  #:use-module (guix build-system python)
   #:use-module (guix build-system trivial)
   #:use-module (gnu packages base)
   #:use-module (gnu packages c)
@@ -5344,7 +5345,7 @@ (define-public sbcl-burgled-batteries3
        `(#:tests? #f
          #:modules (((guix build python-build-system) #:select (python-version))
                     ,@%asdf-build-system-modules)
-         #:imported-modules ((guix build python-build-system)
+         #:imported-modules (,@%python-build-system-modules
                              ,@%asdf-build-system-modules)
          #:phases
          (modify-phases (@ (guix build asdf-build-system) %standard-phases)
diff --git a/gnu/packages/machine-learning.scm b/gnu/packages/machine-learning.scm
index 7f082ee677..48e6c1489d 100644
--- a/gnu/packages/machine-learning.scm
+++ b/gnu/packages/machine-learning.scm
@@ -234,7 +234,7 @@ (define-public ghmm
       (build-system gnu-build-system)
       (arguments
        `(#:imported-modules (,@%gnu-build-system-modules
-                             (guix build python-build-system))
+                             ,@%python-build-system-modules)
          #:modules          ((guix build python-build-system)
                              ,@%gnu-build-system-modules)
          #:phases
@@ -1884,7 +1884,7 @@ (define-public tensorflow
                   ((guix build python-build-system)
                    #:select (python-version)))
        #:imported-modules (,@%cmake-build-system-modules
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:phases
        (modify-phases %standard-phases
          (add-after 'unpack 'set-source-file-times-to-1980
diff --git a/gnu/packages/maths.scm b/gnu/packages/maths.scm
index f9767d2430..d02d1c2303 100644
--- a/gnu/packages/maths.scm
+++ b/gnu/packages/maths.scm
@@ -1953,7 +1953,7 @@ (define-public nomad-optimizer
      `(("python" ,python-wrapper)
        ("python-cython" ,python-cython)))
     (arguments
-     `(#:imported-modules ((guix build python-build-system)
+     `(#:imported-modules (,@%python-build-system-modules
                            ,@%cmake-build-system-modules)
        #:modules (((guix build python-build-system)
                    #:select (python-version site-packages))
@@ -2853,7 +2853,7 @@ (define-public gmsh
                            "-DENABLE_BUILD_SHARED:BOOL=ON"
                            "-DENABLE_BUILD_DYNAMIC:BOOL=ON")
        #:imported-modules (,@%cmake-build-system-modules
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:modules (((guix build python-build-system) #:select (site-packages))
                   (guix build cmake-build-system)
                   (guix build utils))
@@ -5710,7 +5710,7 @@ (define-public z3
                 "1hnbzq10d23drd7ksm3c1n2611c3kd0q0yxgz8y78zaafwczvwxx"))))
     (build-system gnu-build-system)
     (arguments
-     `(#:imported-modules ((guix build python-build-system)
+     `(#:imported-modules (,@%python-build-system-modules
                            ,@%gnu-build-system-modules)
        #:modules (((guix build python-build-system) #:select (site-packages))
                   (guix build gnu-build-system)
@@ -5765,7 +5765,7 @@ (define-public ocaml-z3
     (inherit z3)
     (name "ocaml-z3")
     (arguments
-     `(#:imported-modules ((guix build python-build-system)
+     `(#:imported-modules (,@%python-build-system-modules
                            ,@%gnu-build-system-modules)
        #:modules (((guix build python-build-system) #:select (site-packages))
                   (guix build gnu-build-system)
@@ -7333,7 +7333,7 @@ (define-public fp16
                 (patches (search-patches "fp16-system-libraries.patch"))))
       (build-system cmake-build-system)
       (arguments
-       `(#:imported-modules ((guix build python-build-system)
+       `(#:imported-modules (,@%python-build-system-modules
                              ,@%cmake-build-system-modules)
          #:modules (((guix build python-build-system)
                      #:select (site-packages))
@@ -7405,7 +7405,7 @@ (define-public optizelle
            #t))))
     (build-system cmake-build-system)
     (arguments
-     `(#:imported-modules ((guix build python-build-system)
+     `(#:imported-modules (,@%python-build-system-modules
                            ,@%cmake-build-system-modules)
        #:modules (((guix build python-build-system) #:select
                    (python-version))
diff --git a/gnu/packages/mpd.scm b/gnu/packages/mpd.scm
index 1ee6806735..e5795a724c 100644
--- a/gnu/packages/mpd.scm
+++ b/gnu/packages/mpd.scm
@@ -328,7 +328,7 @@ (define-public sonata
                   ((guix build glib-or-gtk-build-system) #:prefix glib-or-gtk:)
                   (guix build utils))
        #:imported-modules (,@%gnu-build-system-modules
-                           (guix build python-build-system)
+                           ,@%python-build-system-modules
                            (guix build glib-or-gtk-build-system))
        #:phases
        (modify-phases %standard-phases
diff --git a/gnu/packages/music.scm b/gnu/packages/music.scm
index 89d64957c8..2e4a08c283 100644
--- a/gnu/packages/music.scm
+++ b/gnu/packages/music.scm
@@ -3226,7 +3226,7 @@ (define-public jack-select
                   ((guix build python-build-system) #:prefix python:)
                   (guix build utils))
        #:imported-modules (,@%gnu-build-system-modules
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:make-flags
        (list (string-append "PREFIX=" (assoc-ref %outputs "out")))
        #:tests? #f                      ; there are none
diff --git a/gnu/packages/networking.scm b/gnu/packages/networking.scm
index b45f2f79f2..35cee1877a 100644
--- a/gnu/packages/networking.scm
+++ b/gnu/packages/networking.scm
@@ -3412,7 +3412,7 @@ (define-public opendht
     (build-system gnu-build-system)
     (arguments
      (list
-      #:imported-modules `((guix build python-build-system) ;for site-packages
+      #:imported-modules `(,@%python-build-system-modules ;for site-packages
                            ,@%gnu-build-system-modules)
       #:modules '(((guix build python-build-system) #:prefix python:)
                   (guix build gnu-build-system)
diff --git a/gnu/packages/openldap.scm b/gnu/packages/openldap.scm
index c8a47e45d5..ee3c2de367 100644
--- a/gnu/packages/openldap.scm
+++ b/gnu/packages/openldap.scm
@@ -259,7 +259,7 @@ (define-public 389-ds-base
                   ((guix build python-build-system)
                    #:select (add-installed-pythonpath python-version))
                   (guix build utils))
-       #:imported-modules ((guix build python-build-system)
+       #:imported-modules (,@%python-build-system-modules
                            ,@%gnu-build-system-modules)
        #:configure-flags
        (list (string-append "--with-db="
diff --git a/gnu/packages/qt.scm b/gnu/packages/qt.scm
index 0163d02bc0..f98920373d 100644
--- a/gnu/packages/qt.scm
+++ b/gnu/packages/qt.scm
@@ -2017,7 +2017,7 @@ (define-public python-sip-4
     (propagated-inputs `())
     (arguments
      `(#:tests? #f ; no check target
-       #:imported-modules ((guix build python-build-system)
+       #:imported-modules (,@%python-build-system-modules
                            ,@%gnu-build-system-modules)
        #:modules ((srfi srfi-1)
                   ((guix build python-build-system) #:select (python-version))
@@ -2082,7 +2082,7 @@ (define-public python-pyqt
      `(#:modules ((srfi srfi-1)
                   ((guix build python-build-system) #:select (python-version))
                   ,@%gnu-build-system-modules)
-       #:imported-modules ((guix build python-build-system)
+       #:imported-modules (,@%python-build-system-modules
                            ,@%gnu-build-system-modules)
        #:phases
        (modify-phases %standard-phases
@@ -2183,7 +2183,7 @@ (define-public python-pyqtwebengine
      `(#:modules ((srfi srfi-1)
                   ((guix build python-build-system) #:select (python-version))
                   ,@%gnu-build-system-modules)
-       #:imported-modules ((guix build python-build-system)
+       #:imported-modules (,@%python-build-system-modules
                            ,@%gnu-build-system-modules)
        #:phases
        (modify-phases %standard-phases
diff --git a/gnu/packages/radio.scm b/gnu/packages/radio.scm
index dfc274a1de..d49ae0f591 100644
--- a/gnu/packages/radio.scm
+++ b/gnu/packages/radio.scm
@@ -545,7 +545,7 @@ (define-public gnuradio
                   (ice-9 match))
        #:imported-modules (,@%cmake-build-system-modules
                            (guix build glib-or-gtk-build-system)
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:configure-flags
        (list (string-append "-DMATHJAX2_ROOT="
                             (assoc-ref %build-inputs "js-mathjax")
@@ -675,7 +675,7 @@ (define-public gr-osmosdr
                     ((guix build python-build-system) #:prefix python:)
                     (guix build utils))
          #:imported-modules (,@%cmake-build-system-modules
-                             (guix build python-build-system))
+                             ,@%python-build-system-modules)
          #:phases
          (modify-phases %standard-phases
            (add-after 'install 'wrap-python
@@ -807,7 +807,7 @@ (define-public gr-satellites
                   ((guix build python-build-system) #:prefix python:)
                   (guix build utils))
        #:imported-modules (,@%cmake-build-system-modules
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:phases
        (modify-phases %standard-phases
          (add-before 'check 'set-test-environment
diff --git a/gnu/packages/rpm.scm b/gnu/packages/rpm.scm
index 96c6776d1a..4583f1afc1 100644
--- a/gnu/packages/rpm.scm
+++ b/gnu/packages/rpm.scm
@@ -23,6 +23,7 @@ (define-module (gnu packages rpm)
   #:use-module (guix packages)
   #:use-module (guix build-system cmake)
   #:use-module (guix build-system meson)
+  #:use-module (guix build-system python)
   #:use-module (gnu packages bash)
   #:use-module (gnu packages check)
   #:use-module (gnu packages compression)
@@ -90,7 +91,7 @@ (define-public libmodulemd
        (list (string-append "-Dgobject_overrides_dir_py3="
                             (python:site-packages %build-inputs %outputs)))
        #:imported-modules (,@%meson-build-system-modules
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:modules ((guix build meson-build-system)
                   ((guix build python-build-system) #:prefix python:)
                   (guix build utils))
@@ -160,7 +161,7 @@ (define-public createrepo-c
     (build-system cmake-build-system)
     (arguments
      `(#:imported-modules (,@%cmake-build-system-modules
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:modules ((guix build cmake-build-system)
                   ((guix build python-build-system) #:prefix python:)
                   (guix build utils))
diff --git a/gnu/packages/textutils.scm b/gnu/packages/textutils.scm
index cbc657172d..faba62673f 100644
--- a/gnu/packages/textutils.scm
+++ b/gnu/packages/textutils.scm
@@ -1198,7 +1198,7 @@ (define-public opencc
        #:parallel-build? #f             ;occasionally failed.
        #:imported-modules
        (,@%cmake-build-system-modules
-        (guix build python-build-system))
+        ,@%python-build-system-modules)
        #:modules ((guix build cmake-build-system)
                   ((guix build python-build-system) #:prefix python:)
                   (guix build utils))
diff --git a/gnu/packages/version-control.scm b/gnu/packages/version-control.scm
index d77c2e51f6..5fb7de5f15 100644
--- a/gnu/packages/version-control.scm
+++ b/gnu/packages/version-control.scm
@@ -1835,7 +1835,7 @@ (define-public hg-commitsigs
                   "059gm66q06m6ayl4brsc517zkw3ahmz249b6xm1m32ac5y24wb9x"))))
       (build-system copy-build-system)
       (arguments
-       `(#:imported-modules ((guix build python-build-system)
+       `(#:imported-modules (,@%python-build-system-modules
                              ,@%copy-build-system-modules)
          #:modules ((srfi srfi-1)
                     (guix build python-build-system)
diff --git a/gnu/packages/virtualization.scm b/gnu/packages/virtualization.scm
index f3396e7c94..127306eb28 100644
--- a/gnu/packages/virtualization.scm
+++ b/gnu/packages/virtualization.scm
@@ -565,7 +565,7 @@ (define-public ganeti
     (arguments
      `(#:imported-modules (,@%gnu-build-system-modules
                            (guix build haskell-build-system)
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:modules (,@%gnu-build-system-modules
                   ((guix build haskell-build-system) #:prefix haskell:)
                   ((guix build python-build-system) #:select (site-packages))
diff --git a/gnu/packages/vpn.scm b/gnu/packages/vpn.scm
index 5bf5a62481..9e83f06551 100644
--- a/gnu/packages/vpn.scm
+++ b/gnu/packages/vpn.scm
@@ -114,7 +114,7 @@ (define-public bitmask
      `(#:imported-modules
        ((guix build cmake-build-system)
         (guix build copy-build-system)
-        (guix build python-build-system)
+        ,@%python-build-system-modules
         (guix build qt-build-system)
         (guix build qt-utils)
         ,@%go-build-system-modules)
diff --git a/gnu/packages/xdisorg.scm b/gnu/packages/xdisorg.scm
index d2caee85ec..ae610b0bea 100644
--- a/gnu/packages/xdisorg.scm
+++ b/gnu/packages/xdisorg.scm
@@ -1356,7 +1356,7 @@ (define-public redshift
     (build-system gnu-build-system)
     (arguments
      `(#:imported-modules (,@%gnu-build-system-modules
-                           (guix build python-build-system))
+                           ,@%python-build-system-modules)
        #:phases
        (modify-phases %standard-phases
          (add-after 'install 'split-outputs
-- 
2.35.1

>From dc9e54629f9f68060db6597686d30d4c44948062 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <[email-masked]>
Date: Sat, 23 Apr 2022 10:56:01 +0200
Subject: [PATCH v3 005/150] gnu: Use python2-toolchain-for-build instead of
 python-2.

* gnu/packages/check.scm (module-variable-resolver): New variable.
(python-commencement-packager): Likewise.
(python2-pytest): Use python2-toolchain-for-build.
(python2-pytest-mock): Likewise.
(python2-pyfakefs-bootstrap): Likewise.
* gnu/packages/python-xyz.scm (module-variable-resolver): Likewise.
(python-commencement-package): Likewise.
(python2-twodict): Likewise.
(python2-backport-ssl-match-hostname): Likewise.
(python2-openpyxl): Likewise.
(python2-element-tree): Likewise.
(python2-pybugz): Likewise.
(python2-enum): Likewise.
(python2-funcsigs): Likewise.
(python2-pystache): Likewise.
(python2-cython): Likewise.
(python2-matplotlib): Likewise.
(python2-elib.intl): Likewise.
(python2-importlib-resources): Likewise.
(python-dbus): Likewise.
(python2-beautifulsoup4): Likewise.
(python2-networkx): Likewise.
(python2-backports-shutil-get-terminal-size): Likewise.
(python2-pyroute2): Likewise.
(python2-ipaddr): Likewise.
(python-tlsh): Likewise.
(python2-functools32): Likewise.
(python2-subprocess32): Likewise.
(python2-futures): Likewise.
(python2-pathlib2): Likewise.
(python2-unicodecsv): Likewise.
(python2-s3cmd): Likewise.
(python2-shedskin): Likewise.
(python2-jsonrpclib): Likewise.
(python2-ruamel.ordereddict): Likewise.
(python2-tracing): Likewise.
(python2-backports-functools-lru-cache): Likewise.
(python2-argparse): Likewise.
(python2-stemming): Likewise.
(python2-couleur): Likewise.
(python2-steadymark): Likewise.
(python2-booleanoperations): Likewise.
(python2-pyro): Likewise.
(python2-scientific): Likewise.
(python2-mmtk): Likewise.
(python2-typing): Likewise.
(python2-quex-0.67.3): Likewise.
(python2-more-itertools): Likewise.
(python2-zeroconf): Likewise.
(python2-gamera): Likewise.
---
 gnu/packages/check.scm      | 13 +++--
 gnu/packages/python-xyz.scm | 97 ++++++++++++++++++++-----------------
 2 files changed, 63 insertions(+), 47 deletions(-)

diff --git a/gnu/packages/check.scm b/gnu/packages/check.scm
index 335ab7ab11..c0eadbad4b 100644
--- a/gnu/packages/check.scm
+++ b/gnu/packages/check.scm
@@ -91,6 +91,13 @@ (define-module (gnu packages check)
   #:use-module (guix build-system trivial)
   #:use-module (srfi srfi-1))
 
+(define (module-variable-resolver module)
+  (lambda (variable)
+     (module-ref (resolve-interface module) variable)))
+
+(define python-commencement-package
+  (module-variable-resolver '(gnu packages python-commencement)))
+
 (define-public pict
   (package
     (name "pict")
@@ -1062,7 +1069,7 @@ (define-public python2-pytest
                 "0ls3pqr86xgif6bphsb6wrww9r2vc7p7a2naq8zcq8115wwq5yjh"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        ,@(package-arguments python-pytest)))
     (propagated-inputs
      `(("python-atomicwrites" ,python2-atomicwrites)
@@ -1380,7 +1387,7 @@ (define-public python2-pytest-mock
           (base32
            "1i5mg3ff1qk0wqfcxfz60hwy3q5dskdp36i10ckigkzffg8hc3ad"))))
       (arguments
-       `(#:python ,python-2))
+       `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))
       (native-inputs
        `(("python2-setuptools-scm" ,python2-setuptools-scm)))
       (propagated-inputs
@@ -3024,7 +3031,7 @@ (define-public python2-pyfakefs-bootstrap
      (name "python2-pyfakefs-bootstrap")
      (native-inputs '())
      (arguments
-      `(#:python ,python-2
+      `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
         #:tests? #f)))))
 
 (define-public python-aiounittest
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index f2532abc52..c300e973c5 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -196,6 +196,8 @@ (define-module (gnu packages python-xyz)
   #:use-module (gnu packages python)
   #:use-module (gnu packages python-build)
   #:use-module (gnu packages python-check)
+  ;; Importing this module results in a cycle, see below.
+  ;#:use-module (gnu packages python-commencement)
   #:use-module (gnu packages python-compression)
   #:use-module (gnu packages python-crypto)
   #:use-module (gnu packages python-science)
@@ -243,6 +245,13 @@ (define-module (gnu packages python-xyz)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-26))
 
+(define (module-variable-resolver module)
+  (lambda (variable)
+     (module-ref (resolve-interface module) variable)))
+
+(define python-commencement-package
+  (module-variable-resolver '(gnu packages python-commencement)))
+
 (define-public python-xmldiff
   (package
     (name "python-xmldiff")
@@ -463,7 +472,7 @@ (define-public python2-twodict
         (base32 "0ifv7dv18jn2lg0a3l6zdlvmmlda2ivixfjbsda58a2ay6kxznr0"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2))))
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))))
 
 (define-public python-argopt
   (package
@@ -1210,7 +1219,7 @@ (define-public python2-backport-ssl-match-hostname
         "1wndipik52cyqy0677zdgp90i435pmvwd89cz98lm7ri0y3xjajh"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:tests? #f)) ; no test target
     (home-page "https://bitbucket.org/brandon/backports.ssl_match_hostname")
     (synopsis "Backport of ssl.match_hostname() function from Python 3.5")
@@ -2400,7 +2409,7 @@ (define-public python2-openpyxl
            (base32
             "1qzjj8nwj4dn0mhq1j64f136afiqqb81lvqiikipz3g1g0b80lqx"))))
       (arguments
-       `(#:python ,python-2
+       `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
          #:tests? #f)))))     ; No test suite.
 
 (define-public python-eventlet
@@ -2734,7 +2743,7 @@ (define-public python2-element-tree
                 "016bphqnlg0l4vslahhw4r0aanw95bpypy65r1i1acyb2wj5z7dj"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2                       ; seems to be part of Python 3
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)    ; seems to be part of Python 3
        #:tests? #f))                            ; no 'test' sub-command
     (synopsis "Toolkit for XML processing in Python")
     (description
@@ -2760,7 +2769,7 @@ (define-public python2-pybugz
                                        "pybugz-encode-error.patch"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2                         ; SyntaxError with Python 3
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)      ; SyntaxError with Python 3
        #:tests? #f))                              ; no 'test' sub-command
     (propagated-inputs
      `(("element-tree" ,python2-element-tree)))
@@ -2784,7 +2793,7 @@ (define-public python2-enum
                 "13lk3yrwj42vl30kw3c194f739nrfrdg64s6i0v2p636n4k8brsl"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2))
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))
     (home-page "https://pypi.org/project/enum/")
     (synopsis "Robust enumerated type support in Python")
     (description
@@ -3153,7 +3162,7 @@ (define-public python2-funcsigs
                 "0l4g5818ffyfmfs1a924811azhjj8ax9xd1cffr1mzd3ycn0zfx7"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2))
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))
     (native-inputs
      (list python2-unittest2))
     (home-page "http://funcsigs.readthedocs.org")
@@ -4051,7 +4060,7 @@ (define-public python2-pystache
                (strip-python2-variant python-pystache))))
     (package/inherit base
       (arguments
-       `(#:python ,python-2
+       `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
          #:phases
          (modify-phases %standard-phases
            (replace 'check
@@ -5541,7 +5550,7 @@ (define-public python2-cython
     (package/inherit base
       (name "python2-cython")
       (inputs
-       `(("python-2" ,python-2)))       ;this is not automatically changed
+       `(("python-2" ,(python-commencement-package 'python2-toolchain-for-build))))       ;this is not automatically changed
       (arguments
        (substitute-keyword-arguments (package-arguments base)
          ((#:phases phases)
@@ -6606,7 +6615,7 @@ (define-public python2-matplotlib
          ("python2-pytz" ,python2-pytz)
          ("python2-six" ,python2-six)
          ("python2-subprocess32" ,python2-subprocess32)
-         ("python2-tkinter" ,python-2 "tk"))))))
+         ("python2-tkinter" ,(python-commencement-package 'python2-toolchain-for-build) "tk"))))))
 
 (define-public python-matplotlib-documentation
   (package
@@ -7084,7 +7093,7 @@ (define-public python2-elib.intl
     (build-system python-build-system)
     (arguments
      ;; incompatible with Python 3 (exception syntax)
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:tests? #f))
     (home-page "https://github.com/dieterv/elib.intl")
     (synopsis "Enhanced internationalization for Python")
@@ -8236,7 +8245,7 @@ (define-public python2-importlib-resources
                 "0y3hg12iby1qyaspnbisz4s4vxax7syikk3skznwqizqyv89y9yk"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:phases (modify-phases %standard-phases
                   ;; The build system tests for python-wheel, but it is
                   ;; not required for Guix nor the test suite.  Just drop
@@ -9303,7 +9312,7 @@ (define-public python-dbus
 (define-public python2-dbus
   (package/inherit python-dbus
     (name "python2-dbus")
-    (inputs `(("python" ,python-2)
+    (inputs `(("python" ,(python-commencement-package 'python2-toolchain-for-build))
               ,@(alist-delete "python"
                               (package-inputs python-dbus))))
     (arguments
@@ -9402,7 +9411,7 @@ (define-public python2-beautifulsoup4
          (sha256
           (base32
            "09gbd49mwz86k572r1231x2rdp82p42zlnw0bz9b9mfi58r9wwl4"))))
-      (arguments `(#:python ,python-2)))))
+      (arguments `(#:python ,(python-commencement-package 'python2-toolchain-for-build))))))
 
 (define-public python-soupsieve
   (package
@@ -9521,7 +9530,7 @@ (define-public python2-networkx
                  (base32
                   "12swxb15299v9vqjsq4z8rgh5sdhvpx497xwnhpnb0gynrx6zra5"))))
       (arguments
-       `(#:python ,python-2))
+       `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))
       (native-inputs
        (list python2-nose unzip)))))
 
@@ -10089,7 +10098,7 @@ (define-public python2-backports-shutil-get-terminal-size
          "107cmn7g3jnbkp826zlj8rrj19fam301qvaqf0f3905f5217lgki"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:phases
        (modify-phases %standard-phases
          (replace 'check
@@ -11442,7 +11451,7 @@ (define-public python2-pyroute2
          "1gmz4r1w0yzj6fjjypnalmfyy0lnfznydyn62gi3wk50j5hhxbny"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2))                       ;Python 3.x is not supported
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))                       ;Python 3.x is not supported
     (home-page "https://github.com/svinota/pyroute2")
     (synopsis "Python netlink library")
     (description
@@ -12225,7 +12234,7 @@ (define-public python2-ipaddr
         (base32 "1dwq3ngsapjc93fw61rp17fvzggmab5x1drjzvd4y4q0i255nm8v"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2                         ;version 2 only
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)      ;version 2 only
        #:phases
        (modify-phases %standard-phases
          (replace 'check
@@ -12430,7 +12439,7 @@ (define-public python-tlsh
 (define-public python2-tlsh
   (package/inherit python-tlsh
     (name "python2-tlsh")
-    (inputs `(("python" ,python-2)))))
+    (inputs `(("python" ,(python-commencement-package 'python2-toolchain-for-build))))))
 
 (define-public python-termcolor
   (package
@@ -13985,7 +13994,7 @@ (define-public python2-functools32
           "0v8ya0b58x47wp216n1zamimv4iw57cxz3xxhzix52jkw3xks9gn"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:tests? #f)) ; no test target
     (home-page "https://github.com/MiCHiLU/python-functools32")
     (synopsis
@@ -14009,7 +14018,7 @@ (define-public python2-subprocess32
                (search-patches "python2-subprocess32-disable-input-test.patch"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        ;; The test suite fails with Python > 2.7.13:
        ;;     import test.support
        ;; ImportError: No module named support
@@ -14045,7 +14054,7 @@ (define-public python2-futures
           "0rdjmmsab550kxsssdq49jcniz77zlkpw4pvi9hvib3lsskjmh4y"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:phases
        (modify-phases %standard-phases
          (replace 'check
@@ -15406,7 +15415,7 @@ (define-public python2-pathlib2
     ;; version is 3.4 which already includes this package as part of the
     ;; standard library.
     (arguments
-     `(#:python ,python-2))
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))
     (propagated-inputs
      (list python2-scandir python2-six))
     (home-page "https://pypi.org/project/pathlib2/")
@@ -15484,7 +15493,7 @@ (define-public python2-unicodecsv
     (build-system python-build-system)
     (arguments
      `(;; It supports Python 3, but Python 3 can already do Unicode CSV.
-       #:python ,python-2))
+       #:python ,(python-commencement-package 'python2-toolchain-for-build)))
     (native-inputs
      (list python2-unittest2))
     (home-page "https://github.com/jdunck/python-unicodecsv")
@@ -15687,7 +15696,7 @@ (define-public python2-s3cmd
     (build-system python-build-system)
     (arguments
      ;; s3cmd is written for python2 only and contains no tests.
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:tests? #f))
     (propagated-inputs
      (list python2-dateutil
@@ -15876,7 +15885,7 @@ (define-public python2-shedskin
           "0nzwrzgw1ga8rw6f0ryq7zr9kkiavd1cqz5hzxkcbicl1dk7kz41"))))
   (build-system python-build-system)
   (arguments
-   `(#:python ,python-2
+   `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
      #:phases (modify-phases %standard-phases
                (add-after 'unpack 'fix-resulting-include-libs
                 (lambda* (#:key inputs #:allow-other-keys)
@@ -16406,7 +16415,7 @@ (define-public python2-jsonrpclib
     (build-system python-build-system)
     (arguments
      `(#:tests? #f
-       #:python ,python-2))
+       #:python ,(python-commencement-package 'python2-toolchain-for-build)))
     (home-page "https://github.com/joshmarshall/jsonrpclib/")
     (synopsis "Implementation of JSON-RPC specification for Python")
     (description
@@ -18635,7 +18644,7 @@ (define-public python2-ruamel.ordereddict
          "1xmkl8v9l9inm2pyxgc1fm5005yxm7fkd5gv74q7lj1iy5qc8n3h"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:phases
        (modify-phases %standard-phases
          (delete 'check)
@@ -18957,7 +18966,7 @@ (define-public python2-tracing
          "06cw4zg42fsvqy372vi2whj26w56vzg5axhzwdjc2bgwf03garbw"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2))
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))
     (home-page "https://liw.fi/tracing/")
     (synopsis "Python debug logging helper")
     (description "@code{python2-tracing} is a python library for
@@ -19136,7 +19145,7 @@ (define-public python2-backports-functools-lru-cache
     (native-inputs
      (list python2-setuptools-scm))
     (arguments
-     `(#:python ,python-2))
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))
     (home-page "https://github.com/jaraco/backports.functools_lru_cache")
     (synopsis "Backport of functools.lru_cache from Python 3.3")
     (description "@code{python2-backports-functools-lru-cache} is a backport
@@ -19252,7 +19261,7 @@ (define-public python2-argparse
          "1r6nznp64j68ih1k537wms7h57nvppq0szmwsaf99n71bfjqkc32"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2))
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))
     (home-page "https://github.com/ThomasWaldmann/argparse/")
     (synopsis "Python command-line parsing library")
     (description
@@ -19429,7 +19438,7 @@ (define-public python2-stemming
         (base32 "0ldwa24gnnxhniv0fhygkpc2mwgd93q10ag8rvzayv6hw418frsr"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2))
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))
     (home-page "https://bitbucket.org/mchaput/stemming/overview")
     (synopsis "Python implementations of various stemming algorithms")
     (description
@@ -19679,7 +19688,7 @@ (define-public python2-couleur
          "1qqaxyqz74wvid0cr119dhcwz0h0if5b5by44zl49pd5z65v58k1"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2))
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))
     (home-page "https://github.com/gabrielfalcao/couleur")
     (synopsis
      "ANSI terminal tool for python, colored shell and other handy fancy features")
@@ -19740,7 +19749,7 @@ (define-public python2-steadymark
     (native-inputs
      (list python2-couleur python2-sure python2-misaka))
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:phases
        (modify-phases %standard-phases
          (add-before 'build 'patch-setup-py
@@ -20909,7 +20918,7 @@ (define-public python2-booleanoperations
          "1hw42fazdpvsn77glx96hwsj9l17mvx37sc5707s08y5w6fx16mn"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2))
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))
     (native-inputs
      (list unzip python2-pytest python2-pytest-runner))
     (propagated-inputs
@@ -21085,7 +21094,7 @@ (define-public python2-pyro
     (build-system python-build-system)
     (arguments
      ;; Pyro is not compatible with Python 3
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        ;; Pyro has no test cases for automatic execution
        #:tests? #f))
     (home-page "https://pythonhosted.org/Pyro/")
@@ -21120,7 +21129,7 @@ (define-public python2-scientific
      (list python2-numpy-1.8 python2-pyro))
     (arguments
      ;; ScientificPython is not compatible with Python 3
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:tests? #f ; No test suite
        #:phases
        (modify-phases %standard-phases
@@ -21157,9 +21166,9 @@ (define-public python2-mmtk
      (list netcdf))
     (propagated-inputs
      `(("python-scientific" ,python2-scientific)
-       ("python-tkinter" ,python-2 "tk")))
+       ("python-tkinter" ,(python-commencement-package 'python2-toolchain-for-build) "tk")))
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:tests? #f
        #:phases
        (modify-phases %standard-phases
@@ -21754,7 +21763,7 @@ (define-public python2-typing
        (sha256
         (base32 "0c5il4d68fd4qrm5k3dps70j0xz0n5krj6lhwn9vzpal3whsvd0k"))))
     (build-system python-build-system)
-    (arguments (list #:python python-2))
+    (arguments (list #:python (python-commencement-package 'python2-toolchain-for-build)))
     (home-page "https://docs.python.org/3/library/typing.html")
     (synopsis "Type hints for Python")
     (description "This is a backport of the standard library @code{typing}
@@ -21926,7 +21935,7 @@ (define-public python2-quex-0.67.3
     (native-inputs
      (list unzip))
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:tests? #f
        #:phases
        (modify-phases %standard-phases
@@ -21998,7 +22007,7 @@ (define-public python2-more-itertools
                (base32
                 "1r12cm6mcdwdzz7d47a6g4l437xsvapdlgyhqay3i2nrlv03da9q"))))
     (arguments
-     `(#:python ,python-2))
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)))
     (propagated-inputs
      `(("python2-six" ,python2-six-bootstrap)))))
 
@@ -24203,7 +24212,7 @@ (define-public python2-zeroconf
          "0ykzg730n915qbrq9bn5pn06bv6rb5zawal4sqjyfnjjm66snkj3"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:phases
        (modify-phases %standard-phases
          (add-after 'unpack 'patch-requires
@@ -27189,7 +27198,7 @@ (define-public python2-gamera
     (inputs
      (list libpng libtiff zlib))
     (arguments
-     `(#:python ,python-2
+     `(#:python ,(python-commencement-package 'python2-toolchain-for-build)
        #:phases
        (modify-phases %standard-phases
          (add-after 'unpack 'disable-wx-support
-- 
2.35.1

>From 84c3af5cf41d402847adb33b11897d34f5a14179 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <[email-masked]>
Date: Wed, 19 Jan 2022 09:48:44 +0100
Subject: [PATCH v3 146/150] gnu: meson: Match shebang instead of
 setuptools-specific line.

* gnu/packages/build-tools.scm (meson)[arguments]: Replace substitute*
pattern.
---
 gnu/packages/build-tools.scm | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gnu/packages/build-tools.scm b/gnu/packages/build-tools.scm
index 437b0d3550..b343467699 100644
--- a/gnu/packages/build-tools.scm
+++ b/gnu/packages/build-tools.scm
@@ -289,12 +289,12 @@ (define-public meson
                              (python-version (assoc-ref inputs "python")))
                             (output (assoc-ref outputs "out")))
                         (substitute* (string-append output "/bin/meson")
-                          (("# EASY-INSTALL-ENTRY-SCRIPT")
-                           (format #f "\
+                          (("#!/(.+)" all)
+                           (format #f "~a\
 import sys
 sys.path.insert(0, '~a/lib/python~a/site-packages')
-# EASY-INSTALL-ENTRY-SCRIPT"
-                                   output python-version)))))))))
+"
+                                   all output python-version)))))))))
     (inputs (list python-wrapper ninja))
     (home-page "https://mesonbuild.com/")
     (synopsis "Build system designed to be fast and user-friendly")
-- 
2.35.1