~ruther/guix-local

efbce9a69a6dc5576ecfe8500c9e3834d629cf42 — Lars-Dominik Braun 2 years ago a163b85
build-system/pyproject: Use TOML parser.

More reliable than regular expressions.

* guix/build-system/pyproject.scm (%pyproject-build-system-modules): Add (guix build toml).
(pyproject-build): Add argument #:backend-path.
* guix/build/pyproject-build-system.scm (build): Add support for
auto-detected and override backend-path.
* gnu/packages/python-build.scm (python-tomli)[arguments]: Remove
'add-self-to-path, because it is not necessary any more.
(python-poetry-core): Same.
(python-hatchling): Same.
(python-pdm-backend): Same.
M gnu/packages/python-build.scm => gnu/packages/python-build.scm +4 -26
@@ 191,13 191,7 @@ Python file, so it can be easily copied into your project.")
        (base32 "0kwazq3i18rphcr8gak4fgzdcj5w5bbn4k4j2l6ma32gj496qlny"))))
    (build-system pyproject-build-system)
    (arguments
     `(#:tests? #f                      ;disabled to avoid extra dependencies
       #:phases
       (modify-phases %standard-phases
         (add-before 'build 'add-self-to-path
           (lambda _
             ;; The build system of tomli requires... tomli.
             (setenv "PYTHONPATH" "src"))))))
     `(#:tests? #f))                      ;disabled to avoid extra dependencies
    (native-inputs (list python-flit-core-bootstrap python-six-bootstrap))
    (home-page "https://github.com/hukkin/tomli")
    (synopsis "Small and fast TOML parser")


@@ 567,13 561,7 @@ compatible build front-ends to build Poetry managed projects.")
        (base32 "053c8dw632p7jkhjb51k0wcx6hdw4r3lk97mds76df653qxnqmf6"))))
    (build-system pyproject-build-system)
    (arguments
     `(#:tests? #f                      ;disabled to avoid extra dependencies
       #:phases
       (modify-phases %standard-phases
         (add-before 'build 'add-self-to-path
           (lambda _
             ;; The build system requires itself.
             (setenv "PYTHONPATH" "src"))))))
     `(#:tests? #f))                      ;disabled to avoid extra dependencies
    (home-page "https://github.com/python-poetry/poetry-core")
    (synopsis "Poetry PEP 517 build back-end")
    (description


@@ 744,12 732,7 @@ reflected in the package visible to Python, without needing a reinstall.")
                "1nn5cyc9fgrbawz38drfkl2s588k2gn3yqdm2cldbx9zy0fsjbj6"))))
    (build-system pyproject-build-system)
    (arguments
     (list #:tests? #f                  ;to keep dependencies to a minimum
           #:phases #~(modify-phases %standard-phases
                        (add-before 'build 'add-src-to-path
                          ;; Hatchling uses itself to build itself.
                          (lambda _
                            (setenv "PYTHONPATH" "src"))))))
     (list #:tests? #f))                  ;to keep dependencies to a minimum
    (propagated-inputs (list python-editables
                             python-packaging-bootstrap
                             python-pathspec


@@ 823,12 806,7 @@ version control system (like Git) to determine project versions.")
    (build-system pyproject-build-system)
    (arguments
     (list
      #:tests? #f ; Depends on pytest, which we cannot import into this module.
      #:phases
      #~(modify-phases %standard-phases
          (add-after 'unpack 'set-pythonpath
            (lambda _
              (setenv "PYTHONPATH" (string-append (getcwd) "/src")))))))
      #:tests? #f)) ; Depends on pytest, which we cannot import into this module.
    (home-page "https://pdm-backend.fming.dev/")
    (synopsis
     "PEP 517 build backend for PDM")

M guix/build-system/pyproject.scm => guix/build-system/pyproject.scm +3 -0
@@ 46,6 46,7 @@
  ;; Build-side modules imported by default.
  `((guix build pyproject-build-system)
    (guix build json)
    (guix build toml)
    ,@%python-build-system-modules))

(define (default-python)


@@ 93,6 94,7 @@
                          #:key source
                          (tests? #t)
                          (configure-flags ''())
                          (backend-path #f)
                          (build-backend #f)
                          (test-backend #f)
                          (test-flags ''())


@@ 118,6 120,7 @@
                 #:source #+source
                 #:configure-flags #$configure-flags
                 #:system #$system
                 #:backend-path #$backend-path
                 #:build-backend #$build-backend
                 #:test-backend #$test-backend
                 #:test-flags #$test-flags

M guix/build/pyproject-build-system.scm => guix/build/pyproject-build-system.scm +31 -24
@@ 21,6 21,7 @@
  #:use-module ((guix build python-build-system) #:prefix python:)
  #:use-module (guix build utils)
  #:use-module (guix build json)
  #:use-module (guix build toml)
  #:use-module (ice-9 match)
  #:use-module (ice-9 ftw)
  #:use-module (ice-9 format)


@@ 60,8 61,8 @@
;;; wheel and expected to be created by the installing utility.
;;; TODO: Add support for PEP-621 entry points.
;;;
;;; Caveats:
;;; - There is no support for in-tree build backends.
;;; This module also supports in-tree build backends, which can be
;;; overridden by #:backend-path.
;;;
;;; Code:
;;;


@@ 86,23 87,23 @@
;; Raised, when no wheel has been built by the build system.
(define-condition-type &no-wheels-built &python-build-error no-wheels-built?)

(define* (build #:key outputs build-backend configure-flags #:allow-other-keys)
(define* (build #:key outputs build-backend backend-path configure-flags #:allow-other-keys)
  "Build a given Python package."

  (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"))
         (pyproject.toml (if (file-exists? "pyproject.toml")
                             (parse-toml-file "pyproject.toml")
                             '()))
         ;; backend-path is prepended to sys.path, so in-tree backends can be
         ;; found. We assume toml is json-compatible and do not encode the resulting
         ;; JSON list expression.
         (auto-backend-path (recursive-assoc-ref
                             pyproject.toml
                             '("build-system" "backend-path")))
         (use-backend-path (call-with-output-string
                            (cut write-json
                             (or backend-path auto-backend-path '()) <>)))
         ;; 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.


@@ 111,10 112,9 @@
         ;; 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))
         (auto-build-backend (recursive-assoc-ref
                              pyproject.toml
                              '("build-system" "build-backend")))
         ;; 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.


@@ 122,15 122,22 @@
                                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)
     (string-append
      "Using '~a' to build wheels, auto-detected '~a', override '~a'.~%"
      "Prepending '~a' to sys.path, auto-detected '~a', override '~a'.~%")
     use-build-backend auto-build-backend build-backend
     use-backend-path auto-backend-path backend-path)
    (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)"
backend_path = json.loads (sys.argv[1]) or []
backend_path.extend (sys.path)
sys.path = backend_path
config_settings = json.loads (sys.argv[4])
builder = importlib.import_module(sys.argv[2])
builder.build_wheel(sys.argv[3], config_settings=config_settings)"
     use-backend-path
     use-build-backend
     wheel-dir
     config-settings)))