summaryrefslogtreecommitdiff
path: root/guix/build/python-build-system.scm
diff options
context:
space:
mode:
Diffstat (limited to 'guix/build/python-build-system.scm')
-rw-r--r--guix/build/python-build-system.scm70
1 files changed, 50 insertions, 20 deletions
diff --git a/guix/build/python-build-system.scm b/guix/build/python-build-system.scm
index 09bd8465c8..aad86258c7 100644
--- a/guix/build/python-build-system.scm
+++ b/guix/build/python-build-system.scm
@@ -6,6 +6,9 @@
;;; Copyright © 2016 Hartmut Goebel <h.goebel@crazy-compilers.com>
;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2018 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2019, 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net>
+;;; Copyright © 2020 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -27,6 +30,7 @@
#:use-module (guix build utils)
#:use-module (ice-9 match)
#:use-module (ice-9 ftw)
+ #:use-module (ice-9 format)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
#:export (%standard-phases
@@ -154,9 +158,14 @@
(major+minor (take components 2)))
(string-join major+minor ".")))
+(define (python-output outputs)
+ "Return the path of the python output, if there is one, or fall-back to out."
+ (or (assoc-ref outputs "python")
+ (assoc-ref outputs "out")))
+
(define (site-packages inputs outputs)
"Return the path of the current output's Python site-package."
- (let* ((out (assoc-ref outputs "out"))
+ (let* ((out (python-output outputs))
(python (assoc-ref inputs "python")))
(string-append out "/lib/python"
(python-version python)
@@ -172,18 +181,31 @@ when running checks after installing the package."
(if old-path (string-append ":" old-path) "")))
#t))
-(define* (install #:key outputs (configure-flags '()) use-setuptools?
+(define* (install #:key inputs outputs (configure-flags '()) use-setuptools?
#:allow-other-keys)
"Install a given Python package."
- (let* ((out (assoc-ref outputs "out"))
- (params (append (list (string-append "--prefix=" out))
+ (let* ((out (python-output 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=/")
+ "--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))
#t))
(define* (wrap #:key inputs outputs #:allow-other-keys)
@@ -199,12 +221,8 @@ when running checks after installing the package."
(string-append dir "/sbin"))))
outputs))
- (let* ((out (assoc-ref outputs "out"))
- (python (assoc-ref inputs "python"))
- (var `("PYTHONPATH" prefix
- ,(cons (string-append out "/lib/python"
- (python-version python)
- "/site-packages")
+ (let* ((var `("PYTHONPATH" prefix
+ ,(cons (site-packages inputs outputs)
(search-path-as-string->list
(or (getenv "PYTHONPATH") ""))))))
(for-each (lambda (dir)
@@ -220,11 +238,7 @@ 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* ((out (assoc-ref outputs "out"))
- (python (assoc-ref inputs "python"))
- (site-packages (string-append out "/lib/python"
- (python-version python)
- "/site-packages"))
+ (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)
@@ -248,18 +262,34 @@ installed with setuptools."
"Improve determinism of pyc files."
;; Use deterministic hashes for strings, bytes, and datetime objects.
(setenv "PYTHONHASHSEED" "0")
+ ;; Prevent Python from creating .pyc files when loading modules (such as
+ ;; when running a test suite).
+ (setenv "PYTHONDONTWRITEBYTECODE" "1")
+ #t)
+
+(define* (ensure-no-cythonized-files #:rest _)
+ "Check the source code for @code{.c} files which may have been pre-generated
+by Cython."
+ (for-each
+ (lambda (file)
+ (let ((generated-file
+ (string-append (string-drop-right file 3) "c")))
+ (when (file-exists? generated-file)
+ (format #t "Possible Cythonized file found: ~a~%" generated-file))))
+ (find-files "." "\\.pyx$"))
#t)
(define %standard-phases
;; The build phase only builds C extensions and copies the Python sources,
- ;; while the install phase byte-compiles and copies them to the prefix
- ;; directory. The tests are run after the install phase because otherwise
- ;; the cached .pyc generated during the tests execution seem to interfere
- ;; with the byte compilation of the install phase.
+ ;; while the install phase copies then byte-compiles the sources to the
+ ;; 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
enable-bytecode-determinism)
+ (add-after 'enable-bytecode-determinism 'ensure-no-cythonized-files
+ ensure-no-cythonized-files)
(delete 'bootstrap)
(delete 'configure) ;not needed
(replace 'build build)