diff options
Diffstat (limited to 'gnu/packages/python.scm')
-rw-r--r-- | gnu/packages/python.scm | 488 |
1 files changed, 223 insertions, 265 deletions
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm index 27e9b70432..8e8f46467b 100644 --- a/gnu/packages/python.scm +++ b/gnu/packages/python.scm @@ -54,11 +54,12 @@ ;;; Copyright © 2018 Nicolas Goaziou <mail@nicolasgoaziou.fr> ;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com> ;;; Copyright © 2018 Clément Lassieur <clement@lassieur.org> -;;; Copyright © 2018, 2019 Maxim Cournoyer <maxim.cournoyer@gmail.com> +;;; Copyright © 2018, 2019, 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; Copyright © 2018 Luther Thompson <lutheroto@gmail.com> ;;; Copyright © 2018 Vagrant Cascadian <vagrant@debian.org> ;;; Copyright © 2019 Tanguy Le Carrour <tanguy@bioneland.org> ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> +;;; Copyright © 2020 Greg Hogan <code@greghogan.com> ;;; ;;; This file is part of GNU Guix. ;;; @@ -95,65 +96,93 @@ #:use-module (gnu packages tcl) #:use-module (gnu packages tls) #:use-module (gnu packages xml) + #:use-module (guix gexp) #:use-module (guix packages) #:use-module (guix download) #:use-module (guix utils) #:use-module (guix build-system gnu) #:use-module (guix build-system trivial) #:use-module (srfi srfi-1) - #:use-module (srfi srfi-26)) + #:use-module (srfi srfi-26) + + #:export (customize-site + guix-pythonpath-search-path)) + +(define* (customize-site version) + "Generate a install-sitecustomize.py phase, using VERSION." + `(lambda* (#:key inputs outputs #:allow-other-keys) + (let* ((out (assoc-ref outputs "out")) + (site-packages (string-append + out "/lib/python" + ,(version-major+minor version) + "/site-packages")) + (sitecustomize.py (assoc-ref inputs "sitecustomize.py")) + (dest (string-append site-packages "/sitecustomize.py"))) + (mkdir-p site-packages) + (copy-file sitecustomize.py dest) + ;; Set the correct permissions on the installed file, else the byte + ;; compilation phase fails with a permission denied error. + (chmod dest #o644)))) + +(define (guix-pythonpath-search-path version) + "Generate a GUIX_PYTHONPATH search path specification, using VERSION." + (search-path-specification (variable "GUIX_PYTHONPATH") + (files (list (string-append + "lib/python" + (version-major+minor version) + "/site-packages"))))) (define-public python-2.7 (package (name "python2") - (version "2.7.17") + (version "2.7.18") (source (origin - (method url-fetch) - (uri (string-append "https://www.python.org/ftp/python/" - version "/Python-" version ".tar.xz")) - (sha256 - (base32 - "0hds28cg226m8j8sr394nm9yc4gxhvlv109w0avsf2mxrlrz0hsd")) - (patches (search-patches "python-2.7-search-paths.patch" - "python-2-deterministic-build-info.patch" - "python-2.7-site-prefixes.patch" - "python-2.7-source-date-epoch.patch" - "python-2.7-adjust-tests.patch" - "python-cross-compile.patch")) - (modules '((guix build utils))) - (snippet - '(begin - ;; Ensure the bundled copies of these libraries are not used. - (for-each delete-file-recursively - '("Modules/_ctypes/libffi" "Modules/expat" "Modules/zlib")) + (method url-fetch) + (uri (string-append "https://www.python.org/ftp/python/" + version "/Python-" version ".tar.xz")) + (sha256 + (base32 + "0hzgxl94hnflis0d6m4szjx0b52gah7wpmcg5g00q7am6xwhwb5n")) + (patches (search-patches "python-2.7-search-paths.patch" + "python-2-deterministic-build-info.patch" + "python-2.7-site-prefixes.patch" + "python-2.7-source-date-epoch.patch" + "python-2.7-adjust-tests.patch" + "python-cross-compile.patch")) + (modules '((guix build utils))) + (snippet + '(begin + ;; Ensure the bundled copies of these libraries are not used. + (for-each delete-file-recursively + '("Modules/_ctypes/libffi" "Modules/expat" "Modules/zlib")) - (substitute* "Modules/Setup.dist" - ;; Link Expat instead of embedding the bundled one. - (("^#pyexpat.*") "pyexpat pyexpat.c -lexpat\n")) + (substitute* "Modules/Setup.dist" + ;; Link Expat instead of embedding the bundled one. + (("^#pyexpat.*") "pyexpat pyexpat.c -lexpat\n")) - ;; Suboptimal to delete failing tests here, but if we delete them in - ;; the arguments then we need to make sure to strip out that phase - ;; when it gets inherited by python and python-minimal. - (for-each delete-file - '("Lib/test/test_compileall.py" - "Lib/test/test_ctypes.py" ; fails on mips64el - "Lib/test/test_distutils.py" - "Lib/test/test_import.py" - "Lib/test/test_shutil.py" - "Lib/test/test_socket.py" - "Lib/test/test_subprocess.py")) - #t)))) + ;; Suboptimal to delete failing tests here, but if we delete them in + ;; the arguments then we need to make sure to strip out that phase + ;; when it gets inherited by python and python-minimal. + (for-each delete-file + '("Lib/test/test_compileall.py" + "Lib/test/test_ctypes.py" ; fails on mips64el + "Lib/test/test_distutils.py" + "Lib/test/test_import.py" + "Lib/test/test_shutil.py" + "Lib/test/test_socket.py" + "Lib/test/test_subprocess.py")) + #t)))) (outputs '("out" - "tk")) ;tkinter; adds 50 MiB to the closure + "tk")) ;tkinter; adds 50 MiB to the closure (build-system gnu-build-system) (arguments `(#:test-target "test" #:configure-flags - (list "--enable-shared" ;allow embedding - "--with-system-expat" ;for XML support - "--with-system-ffi" ;build ctypes - "--with-ensurepip=install" ;install pip and setuptools + (list "--enable-shared" ;allow embedding + "--with-system-expat" ;for XML support + "--with-system-ffi" ;build ctypes + "--with-ensurepip=install" ;install pip and setuptools "--enable-unicode=ucs4" ;; Prevent the installed _sysconfigdata.py from retaining a reference @@ -181,12 +210,12 @@ ;; https://github.com/python/cpython/commit/529525fb5a8fd9b96ab4021311a598c77588b918. " --exclude test_urllib2_localnet test_httplib")) - #:modules ((ice-9 ftw) (ice-9 match) - (guix build utils) (guix build gnu-build-system)) - #:phases - (modify-phases %standard-phases - (add-before - 'configure 'patch-lib-shells + #:modules ((ice-9 ftw) (ice-9 match) + (guix build utils) (guix build gnu-build-system)) + #:phases + (modify-phases %standard-phases + (add-before + 'configure 'patch-lib-shells (lambda _ ;; This variable is used in setup.py to enable cross compilation ;; specific switches. As it is not set properly by configure @@ -204,38 +233,36 @@ "Lib/test/test_subprocess.py")) (("/bin/sh") (which "sh"))) #t)) - ,@(if (hurd-system?) - `((add-before 'build 'patch-regen-for-hurd - (lambda* (#:key inputs #:allow-other-keys) - (let ((libc (assoc-ref inputs "libc"))) - (substitute* "Lib/plat-generic/regen" - (("/usr/include/") (string-append libc "/include/"))) - #t)))) - '()) - (add-before 'configure 'do-not-record-configure-flags - (lambda* (#:key configure-flags #:allow-other-keys) - ;; Remove configure flags from the installed '_sysconfigdata.py' - ;; and 'Makefile' so we don't end up keeping references to the - ;; build tools. - ;; - ;; Preserve at least '--with-system-ffi' since otherwise the - ;; thing tries to build libffi, fails, and we end up with a - ;; Python that lacks ctypes. - (substitute* "configure" - (("^CONFIG_ARGS=.*$") - (format #f "CONFIG_ARGS='~a'\n" - (if (member "--with-system-ffi" configure-flags) - "--with-system-ffi" - "")))) - #t)) - (add-before - 'check 'pre-check + ,@(if (hurd-system?) + `((add-before 'build 'patch-regen-for-hurd + (lambda* (#:key inputs #:allow-other-keys) + (let ((libc (assoc-ref inputs "libc"))) + (substitute* "Lib/plat-generic/regen" + (("/usr/include/") (string-append libc "/include/"))) + #t)))) + '()) + (add-before 'configure 'do-not-record-configure-flags + (lambda* (#:key configure-flags #:allow-other-keys) + ;; Remove configure flags from the installed '_sysconfigdata.py' + ;; and 'Makefile' so we don't end up keeping references to the + ;; build tools. + ;; + ;; Preserve at least '--with-system-ffi' since otherwise the + ;; thing tries to build libffi, fails, and we end up with a + ;; Python that lacks ctypes. + (substitute* "configure" + (("^CONFIG_ARGS=.*$") + (format #f "CONFIG_ARGS='~a'\n" + (if (member "--with-system-ffi" configure-flags) + "--with-system-ffi" + "")))) + #t)) + (add-before 'check 'pre-check (lambda _ ;; 'Lib/test/test_site.py' needs a valid $HOME (setenv "HOME" (getcwd)) #t)) - (add-after - 'unpack 'set-source-file-times-to-1980 + (add-after 'unpack 'set-source-file-times-to-1980 ;; XXX One of the tests uses a ZIP library to pack up some of the ;; source tree, and fails with "ZIP does not support timestamps ;; before 1980". Work around this by setting the file times in the @@ -246,96 +273,98 @@ (utime file circa-1980 circa-1980) #t)) #t))) - (add-after 'install 'remove-tests - ;; Remove 25 MiB of unneeded unit tests. Keep test_support.* - ;; because these files are used by some libraries out there. - (lambda* (#:key outputs #:allow-other-keys) - (let ((out (assoc-ref outputs "out"))) - (match (scandir (string-append out "/lib") - (lambda (name) - (string-prefix? "python" name))) - ((pythonX.Y) - (let ((testdir (string-append out "/lib/" pythonX.Y - "/test"))) - (with-directory-excursion testdir - (for-each delete-file-recursively - (scandir testdir - (match-lambda - ((or "." "..") #f) - ("support" #f) - (file - (not - (string-prefix? "test_support." - file)))))) - (call-with-output-file "__init__.py" (const #t)) - #t))))))) - (add-after 'remove-tests 'rebuild-bytecode - (lambda* (#:key outputs #:allow-other-keys) - (let ((out (assoc-ref outputs "out"))) - ;; Disable hash randomization to ensure the generated .pycs - ;; are reproducible. - (setenv "PYTHONHASHSEED" "0") - (for-each - (lambda (opt) - (format #t "Compiling with optimization level: ~a\n" - (if (null? opt) "none" (car opt))) - (for-each (lambda (file) - (apply invoke - `(,,(if (%current-target-system) - "python2" - '(string-append out "/bin/python")) - ,@opt - "-m" "compileall" - "-f" ; force rebuild - ;; Don't build lib2to3, because it contains Python 3 code. - "-x" "lib2to3/.*" - ,file))) - (find-files out "\\.py$"))) - (list '() '("-O") '("-OO"))) - #t))) - (add-after 'install 'move-tk-inter - (lambda* (#:key outputs #:allow-other-keys) - ;; When Tkinter support is built move it to a separate output so - ;; that the main output doesn't contain a reference to Tcl/Tk. - (let ((out (assoc-ref outputs "out")) - (tk (assoc-ref outputs "tk"))) - (when tk - (match (find-files out "tkinter.*\\.so") - ((tkinter.so) - ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we - ;; want it under TK/lib/pythonX.Y/site-packages. - (let* ((len (string-length out)) - (target (string-append - tk "/" - (string-drop - (dirname (dirname tkinter.so)) - len) - "/site-packages"))) - (install-file tkinter.so target) - (delete-file tkinter.so))))) - #t)))))) + (add-after 'install 'remove-tests + ;; Remove 25 MiB of unneeded unit tests. Keep test_support.* + ;; because these files are used by some libraries out there. + (lambda* (#:key outputs #:allow-other-keys) + (let ((out (assoc-ref outputs "out"))) + (match (scandir (string-append out "/lib") + (lambda (name) + (string-prefix? "python" name))) + ((pythonX.Y) + (let ((testdir (string-append out "/lib/" pythonX.Y + "/test"))) + (with-directory-excursion testdir + (for-each delete-file-recursively + (scandir testdir + (match-lambda + ((or "." "..") #f) + ("support" #f) + (file + (not + (string-prefix? "test_support." + file)))))) + (call-with-output-file "__init__.py" (const #t))))))))) + (add-after 'remove-tests 'rebuild-bytecode + (lambda* (#:key outputs #:allow-other-keys) + (let ((out (assoc-ref outputs "out"))) + ;; Disable hash randomization to ensure the generated .pycs + ;; are reproducible. + (setenv "PYTHONHASHSEED" "0") + (for-each + (lambda (opt) + (format #t "Compiling with optimization level: ~a\n" + (if (null? opt) "none" (car opt))) + (apply invoke + `(,,(if (%current-target-system) + "python2" + '(string-append out "/bin/python")) + ,@opt + "-m" "compileall" + "-f" ; force rebuild + ;; Don't build lib2to3, because it contains Python 3 code. + "-x" "lib2to3/.*" + ,out))) + ;; Python 2 has a single file extension (.pyo) for the chosen + ;; level of optimization, so it doesn't make sense to byte + ;; compile with more than one level. + (list '() '("-OO"))) + #t))) + (add-after 'install 'move-tk-inter + (lambda* (#:key outputs #:allow-other-keys) + ;; When Tkinter support is built move it to a separate output so + ;; that the main output doesn't contain a reference to Tcl/Tk. + (let ((out (assoc-ref outputs "out")) + (tk (assoc-ref outputs "tk"))) + (when tk + (match (find-files out "tkinter.*\\.so") + ((tkinter.so) + ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we + ;; want it under TK/lib/pythonX.Y/site-packages. + (let* ((len (string-length out)) + (target (string-append + tk "/" + (string-drop + (dirname (dirname tkinter.so)) + len) + "/site-packages"))) + (install-file tkinter.so target) + (delete-file tkinter.so))))) + #t))) + (add-after 'install 'install-sitecustomize.py + ,(customize-site version))))) (inputs `(("bzip2" ,bzip2) ("expat" ,expat) ("gdbm" ,gdbm) - ("libffi" ,libffi) ; for ctypes - ("sqlite" ,sqlite) ; for sqlite extension + ("libffi" ,libffi) ; for ctypes + ("sqlite" ,sqlite) ; for sqlite extension ("openssl" ,openssl) ("readline" ,readline) ("zlib" ,zlib) ("tcl" ,tcl) - ("tk" ,tk))) ; for tkinter + ("tk" ,tk))) ; for tkinter (native-inputs `(("pkg-config" ,pkg-config) + ("sitecustomize.py" ,(local-file (search-auxiliary-file + "python/sitecustomize.py"))) ;; When cross-compiling, a native version of Python itself is needed. ,@(if (%current-target-system) `(("python2" ,this-package) ("which" ,which)) '()))) (native-search-paths - (list (search-path-specification - (variable "PYTHONPATH") - (files '("lib/python2.7/site-packages"))))) + (list (guix-pythonpath-search-path version))) (home-page "https://www.python.org") (synopsis "High-level, dynamically-typed programming language") (description @@ -361,23 +390,24 @@ data types.") (name "python") (properties `((superseded . ,python-2))))) -(define-public python-3.8 - (package (inherit python-2) +(define-public python-3.9 + (package + (inherit python-2) (name "python") - (version "3.8.2") + (version "3.9.1") (source (origin (method url-fetch) (uri (string-append "https://www.python.org/ftp/python/" version "/Python-" version ".tar.xz")) (patches (search-patches - "python-CVE-2020-26116.patch" - "python-3-fix-tests.patch" - "python-3.8-fix-tests.patch" + "python-3-arm-alignment.patch" "python-3-deterministic-build-info.patch" + "python-3-fix-tests.patch" + "python-3-hurd-configure.patch" "python-3-search-paths.patch")) (sha256 (base32 - "1ps5v323cp5czfshqjmbsqw7nvrdpcbk06f62jbzaqik4gfffii6")) + "1zq3k4ymify5ig739zyvx9s2ainvchxb1zpy139z74krr653y74r")) (modules '((guix build utils))) (snippet '(begin @@ -392,11 +422,8 @@ data types.") ((#:make-flags _) `(list (string-append (format #f "TESTOPTS=-j~d" (parallel-job-count)) - ;; test_mmap fails on low-memory systems. - " --exclude test_mmap" - ;; test_socket may hang and eventually run out of memory - ;; on some systems: <https://bugs.python.org/issue34587>. - " test_socket" + ;; test_mmap fails on low-memory systems + " --exclude test_mmap test_socket" ,@(if (hurd-target?) '(" test_posix" ;multiple errors " test_time" @@ -430,35 +457,17 @@ data types.") " test_write_pty") '())))) ((#:phases phases) - `(modify-phases ,phases - ,@(if (hurd-system?) - `((delete 'patch-regen-for-hurd)) ;regen was removed after 3.5.9 - '()) - ,@(if (hurd-target?) - ;; The build system refuses to cross-compile for unknown targets - ;; even though it works fine. Add GNU/Hurd target. - ;; TODO: Make it a patch in a future rebuild cycle. - '((add-before 'configure 'support-hurd-cross-compile - (lambda _ - (substitute* "configure" - (("\\*-\\*-vxworks.*" all) - (string-append "*-*-gnu)\nac_sys_system=GNU\n;;\n" all))) - #t))) - '()) - (add-before 'check 'set-TZDIR - (lambda* (#:key inputs native-inputs #:allow-other-keys) - ;; test_email requires the Olson time zone database. - (setenv "TZDIR" - (string-append (assoc-ref - (or native-inputs inputs) "tzdata") - "/share/zoneinfo")) - #t)) - ;; Unset SOURCE_DATE_EPOCH while running the test-suite and set it - ;; again afterwards. See <https://bugs.python.org/issue34022>. - (add-before 'check 'unset-SOURCE_DATE_EPOCH - (lambda _ (unsetenv "SOURCE_DATE_EPOCH") #t)) - (add-after 'check 'reset-SOURCE_DATE_EPOCH - (lambda _ (setenv "SOURCE_DATE_EPOCH" "1") #t)) + `(modify-phases ,phases + ,@(if (hurd-system?) + `((delete 'patch-regen-for-hurd)) ;regen was removed after 3.5.9 + '()) + (add-before 'check 'set-TZDIR + (lambda* (#:key inputs native-inputs #:allow-other-keys) + ;; test_email requires the Olson time zone database. + (setenv "TZDIR" + (string-append (assoc-ref + (or native-inputs inputs) "tzdata") + "/share/zoneinfo")))) (replace 'rebuild-bytecode (lambda* (#:key outputs #:allow-other-keys) (let ((out (assoc-ref outputs "out"))) @@ -467,87 +476,39 @@ data types.") (setenv "PYTHONHASHSEED" "0") (for-each (lambda (opt) - (format #t "Compiling with optimization level: ~a\n" - (if (null? opt) "none" (car opt))) - (for-each (lambda (file) - (apply invoke - `(,,(if (%current-target-system) - "python3" - '(string-append out - "/bin/python3")) - ,@opt - "-m" "compileall" - "-f" ; force rebuild - ;; Don't build lib2to3, because it's Python 2 code. - "-x" "lib2to3/.*" - ,file))) - (find-files out "\\.py$"))) - (list '() '("-O") '("-OO"))) - #t))) - ;; XXX: Apply patch on ARM platforms only to avoid a full rebuild. - ;; Remove this phase in the next rebuild cycle. - ,@(let ((system (or (%current-target-system) - (%current-system)))) - (if (any (cute string-prefix? <> system) - '("arm" "aarch64")) - '((add-after 'unpack 'apply-alignment-patch - (lambda* (#:key native-inputs inputs #:allow-other-keys) - (invoke "patch" "-p1" "--force" "--input" - (assoc-ref (or native-inputs inputs) - "arm-alignment.patch"))))) - '())))))) + (format #t "Compiling with optimization level: ~a\n" opt) + (lambda (file) + (apply invoke + `(,,(if (%current-target-system) + "python3" + '(string-append out + "/bin/python3")) + ,opt + "-m" "compileall" + "-f" ; force rebuild + "--invalidation-mode=unchecked-hash" + ;; Don't build lib2to3, because it's Python 2 code. + "-x" "lib2to3/.*" + ,out)))) + (list "none" "-O" "-OO"))))) + (replace 'install-sitecustomize.py + ,(customize-site version)))))) (native-inputs `(("tzdata" ,tzdata-for-tests) - - ;; Disable unaligned accesses in the sha3 module on ARM as - ;; it causes a test failure when building 32-bit Python on a - ;; 64-bit kernel. See <https://bugs.python.org/issue36515>. - ;; TODO: make this a regular patch in the next rebuild cycle. - ,@(let ((system (or (%current-target-system) - (%current-system)))) - (if (any (cute string-prefix? <> system) - '("arm" "aarch64")) - `(("arm-alignment.patch" ,(search-patch "python-3-arm-alignment.patch"))) - '())) - ,@(if (%current-target-system) `(("python3" ,this-package)) '()) ,@(package-native-inputs python-2))) (native-search-paths - (list (search-path-specification - (variable "PYTHONPATH") - (files (list (string-append "lib/python" - (version-major+minor version) - "/site-packages")))))))) - -(define-public python-3.9 - (package (inherit python-3.8) - (name "python-next") - (version "3.9.1") - (source (origin - (method url-fetch) - (uri (string-append "https://www.python.org/ftp/python/" - version "/Python-" version ".tar.xz")) - (patches (search-patches - "python-3.9-fix-tests.patch" - "python-3-deterministic-build-info.patch" - "python-3-search-paths.patch")) - (sha256 - (base32 - "1zq3k4ymify5ig739zyvx9s2ainvchxb1zpy139z74krr653y74r")) - (modules '((guix build utils))) - (snippet - '(begin - ;; Delete the bundled copy of libexpat. - (delete-file-recursively "Modules/expat") - (substitute* "Modules/Setup" - ;; Link Expat instead of embedding the bundled one. - (("^#pyexpat.*") "pyexpat pyexpat.c -lexpat\n")) - #t)))))) + (list (guix-pythonpath-search-path version) + ;; Used to locate tzdata by the zoneinfo module introduced in + ;; Python 3.9. + (search-path-specification + (variable "PYTHONTZPATH") + (files (list "share/zoneinfo"))))))) ;; Current 3.x version. -(define-public python-3 python-3.8) +(define-public python-3 python-3.9) ;; Current major version. (define-public python python-3) @@ -814,9 +775,6 @@ ease from the desktop to a microcontroller or embedded system.") "targetpypystandalone")) ;; Build c modules and package everything, so tests work. (with-directory-excursion "pypy/tool/release" - (unsetenv "PYTHONPATH") ; Do not use the system’s python libs: - ; AttributeError: module 'enum' has no - ; attribute 'IntFlag' (invoke "python2" "package.py" "--archive-name" "pypy-dist" "--builddir" (getcwd))))) |