diff options
| author | Nicolas Graves <ngraves@ngraves.fr> | 2026-01-17 14:27:18 +0100 |
|---|---|---|
| committer | Sharlatan Hellseher <sharlatanus@gmail.com> | 2026-05-24 10:14:18 +0100 |
| commit | 356f58222035d1199418f47ff0b4e5ca36502c07 (patch) | |
| tree | 3a526ba8018e45e0932a7544cd808cf8d8883c82 /gnu/packages/python.scm | |
| parent | 18a3715a185c0dbac6d69d868c39c4bc79ae2254 (diff) | |
gnu: python: Refactor module.
* gnu/packages/python.scm
(common-python-phases): New variable, encompassing phases used both in
all python packages. Add a warning comment.
(common-python3-phases): New variable, encompassing phases used in all
python@3 packages. Add a warning comment.
(python-2.7)[arguments]<#:phases>: Modify them
from (common-python-phases) base.
(python-3.10)[arguments]: Avoid substituting python-2.7 arguments.
<#:configure-flags>: ...except here, which is fine since it's not
further inherited.
<#:phases>: Modify them from (common-python3-phases) base.
(python-3.11)[arguments]<#:phases>: Modify them
from (common-python3-phases) base.
(python-2.7)[arguments]<#:phases>: Modify them
from (common-python3-phases) base.
Diffstat (limited to 'gnu/packages/python.scm')
| -rw-r--r-- | gnu/packages/python.scm | 1030 |
1 files changed, 325 insertions, 705 deletions
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm index 04b42331748..21f1a169eba 100644 --- a/gnu/packages/python.scm +++ b/gnu/packages/python.scm | |||
| @@ -63,6 +63,7 @@ | |||
| 63 | ;;; Copyright © 2021 Lars-Dominik Braun <lars@6xq.net> | 63 | ;;; Copyright © 2021 Lars-Dominik Braun <lars@6xq.net> |
| 64 | ;;; Copyright © 2025 Hugo Buddelmeijer <hugo@buddelmeijer.nl> | 64 | ;;; Copyright © 2025 Hugo Buddelmeijer <hugo@buddelmeijer.nl> |
| 65 | ;;; Copyright © 2025 Sharlatan Hellseher <sharlatanus@gmail.com> | 65 | ;;; Copyright © 2025 Sharlatan Hellseher <sharlatanus@gmail.com> |
| 66 | ;;; Copyright © 2025-2026 Nicolas Graves <ngraves@ngraves.fr> | ||
| 66 | ;;; | 67 | ;;; |
| 67 | ;;; This file is part of GNU Guix. | 68 | ;;; This file is part of GNU Guix. |
| 68 | ;;; | 69 | ;;; |
| @@ -105,6 +106,7 @@ | |||
| 105 | #:use-module (guix build-system copy) | 106 | #:use-module (guix build-system copy) |
| 106 | #:use-module (guix build-system gnu) | 107 | #:use-module (guix build-system gnu) |
| 107 | #:use-module (guix build-system trivial) | 108 | #:use-module (guix build-system trivial) |
| 109 | #:use-module (ice-9 optargs) | ||
| 108 | #:use-module (srfi srfi-1) | 110 | #:use-module (srfi srfi-1) |
| 109 | #:use-module (srfi srfi-26) | 111 | #:use-module (srfi srfi-26) |
| 110 | 112 | ||
| @@ -136,6 +138,225 @@ | |||
| 136 | (version-major+minor version) | 138 | (version-major+minor version) |
| 137 | "/site-packages"))))) | 139 | "/site-packages"))))) |
| 138 | 140 | ||
| 141 | ;; Modifying this is a world-rebuild! If possible, modify phases in python | ||
| 142 | ;; packages themselves. | ||
| 143 | (define (common-python-phases-edits) | ||
| 144 | #~((add-before 'configure 'patch-lib-shells | ||
| 145 | (lambda _ | ||
| 146 | ;; This variable is used in setup.py to enable cross compilation | ||
| 147 | ;; specific switches. As it is not set properly by configure | ||
| 148 | ;; script, set it manually. | ||
| 149 | #$@(if (%current-target-system) | ||
| 150 | #~((setenv "_PYTHON_HOST_PLATFORM" "")) | ||
| 151 | #~()) | ||
| 152 | ;; Filter for existing files, since some may not exist in all | ||
| 153 | ;; versions of python that are built with this recipe. | ||
| 154 | (substitute* (filter file-exists? | ||
| 155 | '("Lib/subprocess.py" | ||
| 156 | "Lib/popen2.py" | ||
| 157 | "Lib/distutils/tests/test_spawn.py" | ||
| 158 | "Lib/test/support/__init__.py" | ||
| 159 | "Lib/test/test_subprocess.py")) | ||
| 160 | (("/bin/sh") (which "sh"))))) | ||
| 161 | (add-before 'configure 'do-not-record-configure-flags | ||
| 162 | (lambda* (#:key configure-flags #:allow-other-keys) | ||
| 163 | ;; Remove configure flags from the installed '_sysconfigdata.py' | ||
| 164 | ;; and 'Makefile' so we don't end up keeping references to the | ||
| 165 | ;; build tools. | ||
| 166 | ;; | ||
| 167 | ;; Preserve at least '--with-system-ffi' since otherwise the | ||
| 168 | ;; thing tries to build libffi, fails, and we end up with a | ||
| 169 | ;; Python that lacks ctypes. | ||
| 170 | (substitute* "configure" | ||
| 171 | (("^CONFIG_ARGS=.*$") | ||
| 172 | (format #f "CONFIG_ARGS='~a'\n" | ||
| 173 | (if (member "--with-system-ffi" configure-flags) | ||
| 174 | "--with-system-ffi" | ||
| 175 | "")))))) | ||
| 176 | (add-before 'check 'pre-check | ||
| 177 | (lambda _ | ||
| 178 | ;; 'Lib/test/test_site.py' needs a valid $HOME | ||
| 179 | (setenv "HOME" (getcwd)))) | ||
| 180 | (add-after 'unpack 'set-source-file-times-to-1980 | ||
| 181 | ;; XXX One of the tests uses a ZIP library to pack up some of the | ||
| 182 | ;; source tree, and fails with "ZIP does not support timestamps | ||
| 183 | ;; before 1980". Work around this by setting the file times in the | ||
| 184 | ;; source tree to sometime in early 1980. | ||
| 185 | (lambda _ | ||
| 186 | (let ((circa-1980 (* 10 366 24 60 60))) | ||
| 187 | (ftw "." (lambda (file stat flag) | ||
| 188 | (utime file circa-1980 circa-1980) | ||
| 189 | #t))))) | ||
| 190 | (add-after 'install 'add-libxcrypt-reference-pkgconfig | ||
| 191 | (lambda* (#:key inputs outputs #:allow-other-keys) | ||
| 192 | (define out (assoc-ref outputs "out")) | ||
| 193 | (define libxcrypt | ||
| 194 | (false-if-exception | ||
| 195 | (dirname (search-input-file inputs "lib/libcrypt.so.1")))) | ||
| 196 | (when libxcrypt | ||
| 197 | (substitute* | ||
| 198 | (find-files (string-append out "/lib/pkgconfig") | ||
| 199 | ".*\\.pc") | ||
| 200 | (("-lcrypt") | ||
| 201 | (string-append "-L" libxcrypt " -lcrypt")))))) | ||
| 202 | (add-after 'install 'remove-tests | ||
| 203 | ;; Remove 25 MiB of unneeded unit tests. Keep test_support.* | ||
| 204 | ;; because these files are used by some libraries out there. | ||
| 205 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 206 | (let ((out (assoc-ref outputs "out"))) | ||
| 207 | (match (scandir (string-append out "/lib") | ||
| 208 | (lambda (name) | ||
| 209 | (string-prefix? "python" name))) | ||
| 210 | ((pythonX.Y) | ||
| 211 | (let ((testdir (string-append out "/lib/" pythonX.Y | ||
| 212 | "/test"))) | ||
| 213 | (with-directory-excursion testdir | ||
| 214 | (for-each delete-file-recursively | ||
| 215 | (scandir testdir | ||
| 216 | (match-lambda | ||
| 217 | ((or "." "..") #f) | ||
| 218 | ("support" #f) | ||
| 219 | (file | ||
| 220 | (not | ||
| 221 | (string-prefix? "test_support." | ||
| 222 | file)))))) | ||
| 223 | (call-with-output-file "__init__.py" (const #t)))) | ||
| 224 | (let ((libdir (string-append out "/lib/" pythonX.Y))) | ||
| 225 | (for-each | ||
| 226 | (lambda (directory) | ||
| 227 | (let ((dir (string-append libdir "/" directory))) | ||
| 228 | (when (file-exists? dir) | ||
| 229 | (delete-file-recursively dir)))) | ||
| 230 | '("email/test" "ctypes/test" "unittest/test" "tkinter/test" | ||
| 231 | "sqlite3/test" "bsddb/test" "lib-tk/test" "json/tests" | ||
| 232 | "distutils/tests")))))))) | ||
| 233 | (add-after 'remove-tests 'move-tk-inter | ||
| 234 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 235 | ;; When Tkinter support is built move it to a separate output so | ||
| 236 | ;; that the main output doesn't contain a reference to Tcl/Tk. | ||
| 237 | (let ((out (assoc-ref outputs "out")) | ||
| 238 | (tk (assoc-ref outputs "tk"))) | ||
| 239 | (when tk | ||
| 240 | (match (find-files out "tkinter.*\\.so") | ||
| 241 | ((tkinter.so) | ||
| 242 | ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we | ||
| 243 | ;; want it under TK/lib/pythonX.Y/site-packages. | ||
| 244 | (let* ((len (string-length out)) | ||
| 245 | (target (string-append | ||
| 246 | tk "/" | ||
| 247 | (string-drop | ||
| 248 | (dirname (dirname tkinter.so)) | ||
| 249 | len) | ||
| 250 | "/site-packages"))) | ||
| 251 | (install-file tkinter.so target) | ||
| 252 | (delete-file tkinter.so)))))))) | ||
| 253 | (add-after 'move-tk-inter 'move-idle | ||
| 254 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 255 | ;; when idle is built, move it to a separate output to save some | ||
| 256 | ;; space (5MB) | ||
| 257 | (let ((out (assoc-ref outputs "out")) | ||
| 258 | (idle (assoc-ref outputs "idle"))) | ||
| 259 | (when idle | ||
| 260 | (for-each | ||
| 261 | (lambda (file) | ||
| 262 | (let ((target (string-append idle "/bin/" (basename file)))) | ||
| 263 | (install-file file (dirname target)) | ||
| 264 | (delete-file file))) | ||
| 265 | (find-files (string-append out "/bin") "^idle")) | ||
| 266 | (match (find-files out "^idlelib$" #:directories? #t) | ||
| 267 | ((idlelib) | ||
| 268 | (let* ((len (string-length out)) | ||
| 269 | (target (string-append idle "/" | ||
| 270 | (string-drop idlelib len) | ||
| 271 | "/site-packages"))) | ||
| 272 | (mkdir-p (dirname target)) | ||
| 273 | (rename-file idlelib target)))))))))) | ||
| 274 | |||
| 275 | ;; Modifying this is a world-rebuild! If possible, modify phases in python | ||
| 276 | ;; packages themselves. | ||
| 277 | (define (common-python3-phases-edits) | ||
| 278 | #~(#$@(common-python-phases-edits) | ||
| 279 | #$@(if (system-hurd?) | ||
| 280 | #~((add-after 'unpack 'disable-multi-processing | ||
| 281 | (lambda _ | ||
| 282 | (substitute* "Makefile.pre.in" | ||
| 283 | (("-j0") "-j1"))))) | ||
| 284 | #~()) | ||
| 285 | (add-after 'unpack 'remove-windows-binaries | ||
| 286 | (lambda _ | ||
| 287 | ;; Delete .exe from embedded .whl (zip) files | ||
| 288 | (for-each | ||
| 289 | (lambda (whl) | ||
| 290 | (let ((dir "whl-content") | ||
| 291 | (circa-1980 (* 10 366 24 60 60))) | ||
| 292 | (mkdir-p dir) | ||
| 293 | (with-directory-excursion dir | ||
| 294 | (let ((whl (string-append "../" whl))) | ||
| 295 | (invoke "unzip" whl) | ||
| 296 | (for-each delete-file (find-files "." "\\.exe$")) | ||
| 297 | (delete-file whl) | ||
| 298 | ;; Reset timestamps to prevent them from ending | ||
| 299 | ;; up in the Zip archive. | ||
| 300 | (ftw "." (lambda (file stat flag) | ||
| 301 | (utime file circa-1980 circa-1980))) | ||
| 302 | (apply invoke "zip" "-X" whl | ||
| 303 | (find-files "." #:directories? #t)))) | ||
| 304 | (delete-file-recursively dir))) | ||
| 305 | (find-files "Lib/ensurepip" "\\.whl$")))) | ||
| 306 | (add-after 'move-tk-inter 'move-tk-inter:remove-explicit-store-path | ||
| 307 | (lambda* (#:key outputs inputs #:allow-other-keys) | ||
| 308 | ;; When Tkinter support is built move it to a separate output so | ||
| 309 | ;; that the main output doesn't contain a reference to Tcl/Tk. | ||
| 310 | (let ((out (assoc-ref outputs "out")) | ||
| 311 | (tk (assoc-ref outputs "tk"))) | ||
| 312 | (when tk | ||
| 313 | ;; Remove explicit store path references. | ||
| 314 | (let ((tcl (assoc-ref inputs "tcl")) | ||
| 315 | (tk (assoc-ref inputs "tk"))) | ||
| 316 | (substitute* (find-files (string-append out "/lib") | ||
| 317 | "^(_sysconfigdata_.*\\.py|Makefile)$") | ||
| 318 | (((string-append "-L" tk "/lib")) | ||
| 319 | "") | ||
| 320 | (((string-append "-L" tcl "/lib")) | ||
| 321 | ""))))))) | ||
| 322 | (add-before 'check 'set-TZDIR | ||
| 323 | (lambda* (#:key inputs native-inputs #:allow-other-keys) | ||
| 324 | ;; test_email requires the Olson time zone database. | ||
| 325 | (setenv "TZDIR" | ||
| 326 | (string-append (assoc-ref (or native-inputs | ||
| 327 | inputs) "tzdata") | ||
| 328 | "/share/zoneinfo")))) | ||
| 329 | (add-after 'move-idle 'rebuild-bytecode | ||
| 330 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 331 | ;; Disable hash randomization to ensure the generated .pycs | ||
| 332 | ;; are reproducible. | ||
| 333 | (setenv "PYTHONHASHSEED" "0") | ||
| 334 | |||
| 335 | (for-each (lambda (output) | ||
| 336 | ;; XXX: Delete existing pycs generated by the build | ||
| 337 | ;; system beforehand because the -f argument does | ||
| 338 | ;; not necessarily overwrite all files, leading to | ||
| 339 | ;; indeterministic results. | ||
| 340 | (for-each (lambda (pyc) | ||
| 341 | (delete-file pyc)) | ||
| 342 | (find-files output "\\.pyc$")) | ||
| 343 | |||
| 344 | (apply invoke | ||
| 345 | #$(if (%current-target-system) | ||
| 346 | "python3" | ||
| 347 | #~(string-append #$output "/bin/python3")) | ||
| 348 | `("-m" "compileall" | ||
| 349 | "-o" "0" | ||
| 350 | "-o" "1" | ||
| 351 | "-o" "2" | ||
| 352 | "-f" ;force rebuild | ||
| 353 | "--invalidation-mode=unchecked-hash" | ||
| 354 | ;; Don't build lib2to3, because it's Python | ||
| 355 | ;; 2 code. | ||
| 356 | "-x" "lib2to3/.*" | ||
| 357 | ,output))) | ||
| 358 | (map cdr outputs)))))) | ||
| 359 | |||
| 139 | (define-public python-2.7 | 360 | (define-public python-2.7 |
| 140 | (package | 361 | (package |
| 141 | (name "python2") | 362 | (name "python2") |
| @@ -251,24 +472,7 @@ | |||
| 251 | (guix build gnu-build-system)) | 472 | (guix build gnu-build-system)) |
| 252 | #:phases | 473 | #:phases |
| 253 | #~(modify-phases %standard-phases | 474 | #~(modify-phases %standard-phases |
| 254 | (add-before | 475 | #$@(common-python-phases-edits) |
| 255 | 'configure 'patch-lib-shells | ||
| 256 | (lambda _ | ||
| 257 | ;; This variable is used in setup.py to enable cross compilation | ||
| 258 | ;; specific switches. As it is not set properly by configure | ||
| 259 | ;; script, set it manually. | ||
| 260 | #$@(if (%current-target-system) | ||
| 261 | #~((setenv "_PYTHON_HOST_PLATFORM" "")) | ||
| 262 | #~()) | ||
| 263 | ;; Filter for existing files, since some may not exist in all | ||
| 264 | ;; versions of python that are built with this recipe. | ||
| 265 | (substitute* (filter file-exists? | ||
| 266 | '("Lib/subprocess.py" | ||
| 267 | "Lib/popen2.py" | ||
| 268 | "Lib/distutils/tests/test_spawn.py" | ||
| 269 | "Lib/test/support/__init__.py" | ||
| 270 | "Lib/test/test_subprocess.py")) | ||
| 271 | (("/bin/sh") (which "sh"))))) | ||
| 272 | #$@(if (system-hurd?) | 476 | #$@(if (system-hurd?) |
| 273 | #~((add-before 'build 'patch-regen-for-hurd | 477 | #~((add-before 'build 'patch-regen-for-hurd |
| 274 | (lambda* (#:key inputs #:allow-other-keys) | 478 | (lambda* (#:key inputs #:allow-other-keys) |
| @@ -276,119 +480,6 @@ | |||
| 276 | (substitute* "Lib/plat-generic/regen" | 480 | (substitute* "Lib/plat-generic/regen" |
| 277 | (("/usr/include/") (string-append libc "/include/"))))))) | 481 | (("/usr/include/") (string-append libc "/include/"))))))) |
| 278 | #~()) | 482 | #~()) |
| 279 | (add-before 'configure 'do-not-record-configure-flags | ||
| 280 | (lambda* (#:key configure-flags #:allow-other-keys) | ||
| 281 | ;; Remove configure flags from the installed '_sysconfigdata.py' | ||
| 282 | ;; and 'Makefile' so we don't end up keeping references to the | ||
| 283 | ;; build tools. | ||
| 284 | ;; | ||
| 285 | ;; Preserve at least '--with-system-ffi' since otherwise the | ||
| 286 | ;; thing tries to build libffi, fails, and we end up with a | ||
| 287 | ;; Python that lacks ctypes. | ||
| 288 | (substitute* "configure" | ||
| 289 | (("^CONFIG_ARGS=.*$") | ||
| 290 | (format #f "CONFIG_ARGS='~a'\n" | ||
| 291 | (if (member "--with-system-ffi" configure-flags) | ||
| 292 | "--with-system-ffi" | ||
| 293 | "")))))) | ||
| 294 | (add-before 'check 'pre-check | ||
| 295 | (lambda _ | ||
| 296 | ;; 'Lib/test/test_site.py' needs a valid $HOME | ||
| 297 | (setenv "HOME" (getcwd)))) | ||
| 298 | (add-after 'unpack 'set-source-file-times-to-1980 | ||
| 299 | ;; XXX One of the tests uses a ZIP library to pack up some of the | ||
| 300 | ;; source tree, and fails with "ZIP does not support timestamps | ||
| 301 | ;; before 1980". Work around this by setting the file times in the | ||
| 302 | ;; source tree to sometime in early 1980. | ||
| 303 | (lambda _ | ||
| 304 | (let ((circa-1980 (* 10 366 24 60 60))) | ||
| 305 | (ftw "." (lambda (file stat flag) | ||
| 306 | (utime file circa-1980 circa-1980) | ||
| 307 | #t))))) | ||
| 308 | (add-after 'install 'remove-tests | ||
| 309 | ;; Remove 25 MiB of unneeded unit tests. Keep test_support.* | ||
| 310 | ;; because these files are used by some libraries out there. | ||
| 311 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 312 | (let ((out (assoc-ref outputs "out"))) | ||
| 313 | (match (scandir (string-append out "/lib") | ||
| 314 | (lambda (name) | ||
| 315 | (string-prefix? "python" name))) | ||
| 316 | ((pythonX.Y) | ||
| 317 | (let ((testdir (string-append out "/lib/" pythonX.Y | ||
| 318 | "/test"))) | ||
| 319 | (with-directory-excursion testdir | ||
| 320 | (for-each delete-file-recursively | ||
| 321 | (scandir testdir | ||
| 322 | (match-lambda | ||
| 323 | ((or "." "..") #f) | ||
| 324 | ("support" #f) | ||
| 325 | (file | ||
| 326 | (not | ||
| 327 | (string-prefix? "test_support." | ||
| 328 | file)))))) | ||
| 329 | (call-with-output-file "__init__.py" (const #t)))) | ||
| 330 | (let ((libdir (string-append out "/lib/" pythonX.Y))) | ||
| 331 | (for-each | ||
| 332 | (lambda (directory) | ||
| 333 | (let ((dir (string-append libdir "/" directory))) | ||
| 334 | (when (file-exists? dir) | ||
| 335 | (delete-file-recursively dir)))) | ||
| 336 | '("email/test" "ctypes/test" "unittest/test" "tkinter/test" | ||
| 337 | "sqlite3/test" "bsddb/test" "lib-tk/test" "json/tests" | ||
| 338 | "distutils/tests")))))))) | ||
| 339 | (add-after 'install 'add-libxcrypt-reference-pkgconfig | ||
| 340 | (lambda* (#:key inputs outputs #:allow-other-keys) | ||
| 341 | (define out (assoc-ref outputs "out")) | ||
| 342 | (define libxcrypt | ||
| 343 | (false-if-exception | ||
| 344 | (dirname (search-input-file inputs "lib/libcrypt.so.1")))) | ||
| 345 | (when libxcrypt | ||
| 346 | (substitute* | ||
| 347 | (find-files (string-append out "/lib/pkgconfig") | ||
| 348 | ".*\\.pc") | ||
| 349 | (("-lcrypt") | ||
| 350 | (string-append "-L" libxcrypt " -lcrypt")))))) | ||
| 351 | (add-after 'remove-tests 'move-tk-inter | ||
| 352 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 353 | ;; When Tkinter support is built move it to a separate output so | ||
| 354 | ;; that the main output doesn't contain a reference to Tcl/Tk. | ||
| 355 | (let ((out (assoc-ref outputs "out")) | ||
| 356 | (tk (assoc-ref outputs "tk"))) | ||
| 357 | (when tk | ||
| 358 | (match (find-files out "tkinter.*\\.so") | ||
| 359 | ((tkinter.so) | ||
| 360 | ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we | ||
| 361 | ;; want it under TK/lib/pythonX.Y/site-packages. | ||
| 362 | (let* ((len (string-length out)) | ||
| 363 | (target (string-append | ||
| 364 | tk "/" | ||
| 365 | (string-drop | ||
| 366 | (dirname (dirname tkinter.so)) | ||
| 367 | len) | ||
| 368 | "/site-packages"))) | ||
| 369 | (install-file tkinter.so target) | ||
| 370 | (delete-file tkinter.so)))))))) | ||
| 371 | (add-after 'move-tk-inter 'move-idle | ||
| 372 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 373 | ;; when idle is built, move it to a separate output to save some | ||
| 374 | ;; space (5MB) | ||
| 375 | (let ((out (assoc-ref outputs "out")) | ||
| 376 | (idle (assoc-ref outputs "idle"))) | ||
| 377 | (when idle | ||
| 378 | (for-each | ||
| 379 | (lambda (file) | ||
| 380 | (let ((target (string-append idle "/bin/" (basename file)))) | ||
| 381 | (install-file file (dirname target)) | ||
| 382 | (delete-file file))) | ||
| 383 | (find-files (string-append out "/bin") "^idle")) | ||
| 384 | (match (find-files out "^idlelib$" #:directories? #t) | ||
| 385 | ((idlelib) | ||
| 386 | (let* ((len (string-length out)) | ||
| 387 | (target (string-append idle "/" | ||
| 388 | (string-drop idlelib len) | ||
| 389 | "/site-packages"))) | ||
| 390 | (mkdir-p (dirname target)) | ||
| 391 | (rename-file idlelib target)))))))) | ||
| 392 | (add-after 'move-idle 'rebuild-bytecode | 483 | (add-after 'move-idle 'rebuild-bytecode |
| 393 | (lambda* (#:key outputs #:allow-other-keys) | 484 | (lambda* (#:key outputs #:allow-other-keys) |
| 394 | (let ((out (assoc-ref outputs "out"))) | 485 | (let ((out (assoc-ref outputs "out"))) |
| @@ -492,100 +583,103 @@ data types.") | |||
| 492 | ;; Delete windows binaries | 583 | ;; Delete windows binaries |
| 493 | (for-each delete-file | 584 | (for-each delete-file |
| 494 | (find-files "Lib/distutils/command" "\\.exe$")))))) | 585 | (find-files "Lib/distutils/command" "\\.exe$")))))) |
| 586 | (build-system gnu-build-system) | ||
| 495 | (arguments | 587 | (arguments |
| 496 | (substitute-keyword-arguments arguments | 588 | (list |
| 497 | ((#:configure-flags flags) | 589 | #:configure-flags |
| 498 | #~(append #$flags | 590 | ;; Avoid inheriting phases, but configure-flags is fine, as |
| 591 | ;; it doesn't propagate to later python version. | ||
| 592 | (let-keywords (package-arguments python-2) #t | ||
| 593 | ((configure-flags #~(list))) | ||
| 594 | #~(append #$configure-flags | ||
| 499 | ;; XXX Use quote to avoid world rebuild at this time | 595 | ;; XXX Use quote to avoid world rebuild at this time |
| 500 | '("--without-static-libpython"))) | 596 | '("--without-static-libpython"))) |
| 501 | ((#:make-flags _) | 597 | #:make-flags |
| 502 | #~(list (string-append | 598 | #~(list (string-append |
| 503 | (format #f "TESTOPTS=-j~d" (parallel-job-count)) | 599 | (format #f "TESTOPTS=-j~d" (parallel-job-count)) |
| 504 | ;; test_mmap fails on low-memory systems | 600 | ;; test_mmap fails on low-memory systems |
| 505 | " --exclude test_mmap test_socket" | 601 | " --exclude test_mmap test_socket" |
| 506 | #$@(if (system-hurd?) | 602 | #$@(if (system-hurd?) |
| 507 | #~(" test_posix" ;multiple errors | 603 | #~(" test_posix" ;multiple errors |
| 508 | " test_time" | 604 | " test_time" |
| 509 | " test_pty" | 605 | " test_pty" |
| 510 | " test_shutil" | 606 | " test_shutil" |
| 511 | " test_tempfile" ;chflags: invalid argument: | 607 | " test_tempfile" ;chflags: invalid argument: |
| 512 | ; tbv14c9t/dir0/dir0/dir0/test0.txt | 608 | ; tbv14c9t/dir0/dir0/dir0/test0.txt |
| 513 | " test_asyncio" ;runs over 10min | 609 | " test_asyncio" ;runs over 10min |
| 514 | " test_os" ;stty: 'standard input': | 610 | " test_os" ;stty: 'standard input': |
| 515 | ; Inappropriate ioctl for device | 611 | ; Inappropriate ioctl for device |
| 516 | " test_openpty" ;No such file or directory | 612 | " test_openpty" ;No such file or directory |
| 517 | " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds)) | 613 | " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds)) |
| 518 | ; 32752 != 4 | 614 | ; 32752 != 4 |
| 519 | " test_compileall" ;multiple errors | 615 | " test_compileall" ;multiple errors |
| 520 | " test_poll" ;list index out of range | 616 | " test_poll" ;list index out of range |
| 521 | " test_subprocess" ;runs over 10min | 617 | " test_subprocess" ;runs over 10min |
| 522 | " test_asyncore" ;multiple errors | 618 | " test_asyncore" ;multiple errors |
| 523 | " test_threadsignals" | 619 | " test_threadsignals" |
| 524 | " test_eintr" ;Process return code is -14 | 620 | " test_eintr" ;Process return code is -14 |
| 525 | " test_io" ;multiple errors | 621 | " test_io" ;multiple errors |
| 526 | " test_logging" | 622 | " test_logging" |
| 527 | " test_signal" | 623 | " test_signal" |
| 528 | " test_threading" ;runs over 10min | 624 | " test_threading" ;runs over 10min |
| 529 | " test_flags" ;ERROR | 625 | " test_flags" ;ERROR |
| 530 | " test_bidirectional_pty" | 626 | " test_bidirectional_pty" |
| 531 | " test_create_unix_connection" | 627 | " test_create_unix_connection" |
| 532 | " test_unix_sock_client_ops" | 628 | " test_unix_sock_client_ops" |
| 533 | " test_open_unix_connection" | 629 | " test_open_unix_connection" |
| 534 | " test_open_unix_connection_error" | 630 | " test_open_unix_connection_error" |
| 535 | " test_read_pty_output" | 631 | " test_read_pty_output" |
| 536 | " test_write_pty" | 632 | " test_write_pty" |
| 537 | " test_concurrent_futures" ;freeze | 633 | " test_concurrent_futures" ;freeze |
| 538 | " test_venv" ;freeze | 634 | " test_venv" ;freeze |
| 539 | " test_multiprocessing_forkserver" ;runs over 10min | 635 | " test_multiprocessing_forkserver" ;runs over 10min |
| 540 | " test_multiprocessing_spawn" ;runs over 10min | 636 | " test_multiprocessing_spawn" ;runs over 10min |
| 541 | " test_builtin" | 637 | " test_builtin" |
| 542 | " test_capi" | 638 | " test_capi" |
| 543 | " test_dbm_ndbm" | 639 | " test_dbm_ndbm" |
| 544 | " test_exceptions" | 640 | " test_exceptions" |
| 545 | " test_faulthandler" | 641 | " test_faulthandler" |
| 546 | " test_getopt" | 642 | " test_getopt" |
| 547 | " test_importlib" | 643 | " test_importlib" |
| 548 | " test_json" | 644 | " test_json" |
| 549 | " test_multiprocessing_fork" | 645 | " test_multiprocessing_fork" |
| 550 | " test_multiprocessing_main_handling" | 646 | " test_multiprocessing_main_handling" |
| 551 | " test_pdb " | 647 | " test_pdb " |
| 552 | " test_regrtest" | 648 | " test_regrtest" |
| 553 | " test_sqlite") | 649 | " test_sqlite") |
| 554 | #~())))) | 650 | #~()))) |
| 555 | ((#:phases phases) | 651 | #:modules '((ice-9 ftw) |
| 556 | #~(modify-phases #$phases | 652 | (ice-9 match) |
| 557 | #$@(if (system-hurd?) | 653 | (guix build utils) |
| 558 | #~((delete 'patch-regen-for-hurd) ;regen was removed after 3.5.9 | 654 | (guix build gnu-build-system)) |
| 559 | (add-after 'unpack 'disable-multi-processing | 655 | #:phases |
| 560 | (lambda _ | 656 | #~(modify-phases %standard-phases |
| 561 | (substitute* "Makefile.pre.in" | 657 | #$@(common-python3-phases-edits) |
| 562 | (("-j0") "-j1"))))) | 658 | (replace 'remove-windows-binaries |
| 563 | #~()) | 659 | (lambda _ |
| 564 | (add-after 'unpack 'remove-vendored-wheel-content | 660 | ;; Delete .exe from embedded .whl (zip) files |
| 565 | (lambda _ | 661 | (for-each |
| 566 | ;; Delete .exe from embedded .whl (zip) files | 662 | (lambda (whl) |
| 567 | (for-each | 663 | (let ((dir "whl-content") |
| 568 | (lambda (whl) | 664 | (circa-1980 (* 10 366 24 60 60))) |
| 569 | (let ((dir "whl-content") | 665 | (mkdir-p dir) |
| 570 | (circa-1980 (* 10 366 24 60 60))) | 666 | (with-directory-excursion dir |
| 571 | (mkdir-p dir) | 667 | (let ((whl (string-append "../" whl))) |
| 572 | (with-directory-excursion dir | 668 | (invoke "unzip" whl) |
| 573 | (let ((whl (string-append "../" whl))) | 669 | (for-each delete-file |
| 574 | (invoke "unzip" whl) | 670 | (find-files "." "\\.exe$")) |
| 575 | (for-each delete-file | 671 | (delete-file whl) |
| 576 | (find-files "." "\\.exe$")) | ||
| 577 | (delete-file whl) | ||
| 578 | 672 | ||
| 579 | ;; Search for cacert.pem, delete it, and rewrite the | 673 | ;; Search for cacert.pem, delete it, and rewrite the |
| 580 | ;; file which directs python to look for it. | 674 | ;; file which directs python to look for it. |
| 581 | (let ((cacert (find-files "." "cacert\\.pem"))) | 675 | (let ((cacert (find-files "." "cacert\\.pem"))) |
| 582 | (unless (null? cacert) | 676 | (unless (null? cacert) |
| 583 | (let ((certifi (dirname (car cacert)))) | 677 | (let ((certifi (dirname (car cacert)))) |
| 584 | (delete-file (string-append certifi "/cacert.pem")) | 678 | (delete-file (string-append certifi "/cacert.pem")) |
| 585 | (delete-file (string-append certifi "/core.py")) | 679 | (delete-file (string-append certifi "/core.py")) |
| 586 | (with-output-to-file (string-append certifi "/core.py") | 680 | (with-output-to-file (string-append certifi "/core.py") |
| 587 | (lambda _ | 681 | (lambda _ |
| 588 | (display "\"\"\" | 682 | (display "\"\"\" |
| 589 | certifi.py | 683 | certifi.py |
| 590 | ~~~~~~~~~~ | 684 | ~~~~~~~~~~ |
| 591 | This file is a Guix-specific version of core.py. | 685 | This file is a Guix-specific version of core.py. |
| @@ -609,54 +703,17 @@ def contents() -> str: | |||
| 609 | with open(where(), \"r\", encoding=\"ascii\") as data: | 703 | with open(where(), \"r\", encoding=\"ascii\") as data: |
| 610 | return data.read()")))))) | 704 | return data.read()")))))) |
| 611 | 705 | ||
| 612 | ;; Reset timestamps to prevent them from ending | 706 | ;; Reset timestamps to prevent them from ending |
| 613 | ;; up in the Zip archive. | 707 | ;; up in the Zip archive. |
| 614 | (ftw "." (lambda (file stat flag) | 708 | (ftw "." (lambda (file stat flag) |
| 615 | (utime file circa-1980 circa-1980) | 709 | (utime file circa-1980 circa-1980) |
| 616 | #t)) | 710 | #t)) |
| 617 | (apply invoke "zip" "-X" whl | 711 | (apply invoke "zip" "-X" whl |
| 618 | (find-files "." #:directories? #t)))) | 712 | (find-files "." #:directories? #t)))) |
| 619 | (delete-file-recursively dir))) | 713 | (delete-file-recursively dir))) |
| 620 | (find-files "Lib/ensurepip" "\\.whl$")))) | 714 | (find-files "Lib/ensurepip" "\\.whl$")))) |
| 621 | (add-before 'check 'set-TZDIR | 715 | (add-after 'install 'install-sitecustomize.py |
| 622 | (lambda* (#:key inputs native-inputs #:allow-other-keys) | 716 | #$(customize-site version))))) |
| 623 | ;; test_email requires the Olson time zone database. | ||
| 624 | (setenv "TZDIR" | ||
| 625 | (string-append (assoc-ref | ||
| 626 | (or native-inputs inputs) "tzdata") | ||
| 627 | "/share/zoneinfo")))) | ||
| 628 | (replace 'rebuild-bytecode | ||
| 629 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 630 | (let ((out (assoc-ref outputs "out"))) | ||
| 631 | ;; Disable hash randomization to ensure the generated .pycs | ||
| 632 | ;; are reproducible. | ||
| 633 | (setenv "PYTHONHASHSEED" "0") | ||
| 634 | |||
| 635 | (for-each (lambda (output) | ||
| 636 | ;; XXX: Delete existing pycs generated by the build | ||
| 637 | ;; system beforehand because the -f argument does | ||
| 638 | ;; not necessarily overwrite all files, leading to | ||
| 639 | ;; indeterministic results. | ||
| 640 | (for-each (lambda (pyc) | ||
| 641 | (delete-file pyc)) | ||
| 642 | (find-files output "\\.pyc$")) | ||
| 643 | |||
| 644 | (apply invoke | ||
| 645 | `(,#$(if (%current-target-system) | ||
| 646 | "python3" | ||
| 647 | #~(string-append out | ||
| 648 | "/bin/python3")) | ||
| 649 | "-m" "compileall" | ||
| 650 | "-o" "0" "-o" "1" "-o" "2" | ||
| 651 | "-f" ; force rebuild | ||
| 652 | "--invalidation-mode=unchecked-hash" | ||
| 653 | ;; Don't build lib2to3, because it's | ||
| 654 | ;; Python 2 code. | ||
| 655 | "-x" "lib2to3/.*" | ||
| 656 | ,output))) | ||
| 657 | (map cdr outputs))))) | ||
| 658 | (replace 'install-sitecustomize.py | ||
| 659 | #$(customize-site version)))))) | ||
| 660 | (inputs | 717 | (inputs |
| 661 | (modify-inputs (package-inputs python-2.7) | 718 | (modify-inputs (package-inputs python-2.7) |
| 662 | (replace "openssl" openssl))) | 719 | (replace "openssl" openssl))) |
| @@ -837,228 +894,7 @@ def contents() -> str: | |||
| 837 | 894 | ||
| 838 | #:phases | 895 | #:phases |
| 839 | #~(modify-phases %standard-phases | 896 | #~(modify-phases %standard-phases |
| 840 | #$@(if (system-hurd?) | 897 | #$@(common-python3-phases-edits) |
| 841 | `((add-after 'unpack | ||
| 842 | 'disable-multi-processing | ||
| 843 | (lambda _ | ||
| 844 | (substitute* "Makefile.pre.in" | ||
| 845 | (("-j0") | ||
| 846 | "-j1"))))) | ||
| 847 | '()) | ||
| 848 | (add-before 'configure 'patch-lib-shells | ||
| 849 | (lambda _ | ||
| 850 | ;; This variable is used in setup.py to enable cross compilation | ||
| 851 | ;; specific switches. As it is not set properly by configure | ||
| 852 | ;; script, set it manually. | ||
| 853 | #$@(if (%current-target-system) | ||
| 854 | '((setenv "_PYTHON_HOST_PLATFORM" "")) | ||
| 855 | '()) | ||
| 856 | ;; Filter for existing files, since some may not exist in all | ||
| 857 | ;; versions of python that are built with this recipe. | ||
| 858 | (substitute* (filter file-exists? | ||
| 859 | '("Lib/subprocess.py" | ||
| 860 | "Lib/popen2.py" | ||
| 861 | "Lib/distutils/tests/test_spawn.py" | ||
| 862 | "Lib/test/support/__init__.py" | ||
| 863 | "Lib/test/test_subprocess.py")) | ||
| 864 | (("/bin/sh") | ||
| 865 | (which "sh"))))) | ||
| 866 | (add-before 'configure 'do-not-record-configure-flags | ||
| 867 | (lambda* (#:key configure-flags #:allow-other-keys) | ||
| 868 | ;; Remove configure flags from the installed '_sysconfigdata.py' | ||
| 869 | ;; and 'Makefile' so we don't end up keeping references to the | ||
| 870 | ;; build tools. | ||
| 871 | ;; | ||
| 872 | ;; Preserve at least '--with-system-ffi' since otherwise the | ||
| 873 | ;; thing tries to build libffi, fails, and we end up with a | ||
| 874 | ;; Python that lacks ctypes. | ||
| 875 | (substitute* "configure" | ||
| 876 | (("^CONFIG_ARGS=.*$") | ||
| 877 | (format #f "CONFIG_ARGS='~a'\n" | ||
| 878 | (if (member "--with-system-ffi" | ||
| 879 | configure-flags) | ||
| 880 | "--with-system-ffi" "")))))) | ||
| 881 | (add-before 'check 'pre-check | ||
| 882 | (lambda _ | ||
| 883 | ;; 'Lib/test/test_site.py' needs a valid $HOME | ||
| 884 | (setenv "HOME" | ||
| 885 | (getcwd)))) | ||
| 886 | (add-after 'unpack 'set-source-file-times-to-1980 | ||
| 887 | ;; XXX One of the tests uses a ZIP library to pack up some of the | ||
| 888 | ;; source tree, and fails with "ZIP does not support timestamps | ||
| 889 | ;; before 1980". Work around this by setting the file times in the | ||
| 890 | ;; source tree to sometime in early 1980. | ||
| 891 | (lambda _ | ||
| 892 | (let ((circa-1980 (* 10 366 24 60 60))) | ||
| 893 | (ftw "." | ||
| 894 | (lambda (file stat flag) | ||
| 895 | (utime file circa-1980 circa-1980) #t))))) | ||
| 896 | (add-after 'unpack 'remove-windows-binaries | ||
| 897 | (lambda _ | ||
| 898 | ;; Delete .exe from embedded .whl (zip) files | ||
| 899 | (for-each (lambda (whl) | ||
| 900 | (let ((dir "whl-content") | ||
| 901 | (circa-1980 (* 10 366 24 60 60))) | ||
| 902 | (mkdir-p dir) | ||
| 903 | (with-directory-excursion dir | ||
| 904 | (let ((whl (string-append "../" whl))) | ||
| 905 | (invoke "unzip" whl) | ||
| 906 | (for-each delete-file | ||
| 907 | (find-files "." "\\.exe$")) | ||
| 908 | (delete-file whl) | ||
| 909 | ;; Reset timestamps to prevent them from ending | ||
| 910 | ;; up in the Zip archive. | ||
| 911 | (ftw "." | ||
| 912 | (lambda (file stat flag) | ||
| 913 | (utime file circa-1980 | ||
| 914 | circa-1980) #t)) | ||
| 915 | (apply invoke "zip" "-X" whl | ||
| 916 | (find-files "." | ||
| 917 | #:directories? #t)))) | ||
| 918 | (delete-file-recursively dir))) | ||
| 919 | (find-files "Lib/ensurepip" "\\.whl$")))) | ||
| 920 | (add-after 'install 'remove-tests | ||
| 921 | ;; Remove 25 MiB of unneeded unit tests. Keep test_support.* | ||
| 922 | ;; because these files are used by some libraries out there. | ||
| 923 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 924 | (let ((out (assoc-ref outputs "out"))) | ||
| 925 | (match (scandir (string-append out "/lib") | ||
| 926 | (lambda (name) | ||
| 927 | (string-prefix? "python" name))) | ||
| 928 | ((pythonX.Y) | ||
| 929 | (let ((testdir (string-append out "/lib/" pythonX.Y | ||
| 930 | "/test"))) | ||
| 931 | (with-directory-excursion testdir | ||
| 932 | (for-each delete-file-recursively | ||
| 933 | (scandir testdir | ||
| 934 | (match-lambda | ||
| 935 | ((or "." "..") | ||
| 936 | #f) | ||
| 937 | ("support" #f) | ||
| 938 | (file (not (string-prefix? | ||
| 939 | "test_support." | ||
| 940 | file)))))) | ||
| 941 | (call-with-output-file "__init__.py" | ||
| 942 | (const #t)))) | ||
| 943 | (let ((libdir (string-append out "/lib/" pythonX.Y))) | ||
| 944 | (for-each (lambda (directory) | ||
| 945 | (let ((dir (string-append libdir "/" | ||
| 946 | directory))) | ||
| 947 | (when (file-exists? dir) | ||
| 948 | (delete-file-recursively dir)))) | ||
| 949 | '("email/test" "ctypes/test" | ||
| 950 | "unittest/test" | ||
| 951 | "tkinter/test" | ||
| 952 | "sqlite3/test" | ||
| 953 | "bsddb/test" | ||
| 954 | "lib-tk/test" | ||
| 955 | "json/tests" | ||
| 956 | "distutils/tests")))))))) | ||
| 957 | (add-after 'remove-tests 'move-tk-inter | ||
| 958 | (lambda* (#:key outputs inputs #:allow-other-keys) | ||
| 959 | ;; When Tkinter support is built move it to a separate output so | ||
| 960 | ;; that the main output doesn't contain a reference to Tcl/Tk. | ||
| 961 | (let ((out (assoc-ref outputs "out")) | ||
| 962 | (tk (assoc-ref outputs "tk"))) | ||
| 963 | (when tk | ||
| 964 | (match (find-files out "tkinter.*\\.so") | ||
| 965 | ((tkinter.so) | ||
| 966 | ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we | ||
| 967 | ;; want it under TK/lib/pythonX.Y/site-packages. | ||
| 968 | (let* ((len (string-length out)) | ||
| 969 | (target (string-append tk "/" | ||
| 970 | (string-drop (dirname | ||
| 971 | (dirname | ||
| 972 | tkinter.so)) | ||
| 973 | len) | ||
| 974 | "/site-packages"))) | ||
| 975 | (install-file tkinter.so target) | ||
| 976 | (delete-file tkinter.so)))) | ||
| 977 | ;; Remove explicit store path references. | ||
| 978 | (let ((tcl (assoc-ref inputs "tcl")) | ||
| 979 | (tk (assoc-ref inputs "tk"))) | ||
| 980 | (substitute* (find-files (string-append out "/lib") | ||
| 981 | "^(_sysconfigdata_.*\\.py|Makefile)$") | ||
| 982 | (((string-append "-L" tk "/lib")) | ||
| 983 | "") | ||
| 984 | (((string-append "-L" tcl "/lib")) | ||
| 985 | ""))))))) | ||
| 986 | (add-after 'move-tk-inter 'move-idle | ||
| 987 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 988 | ;; when idle is built, move it to a separate output to save some | ||
| 989 | ;; space (5MB) | ||
| 990 | (let ((out (assoc-ref outputs "out")) | ||
| 991 | (idle (assoc-ref outputs "idle"))) | ||
| 992 | (when idle | ||
| 993 | (for-each (lambda (file) | ||
| 994 | (let ((target (string-append idle | ||
| 995 | "/bin/" | ||
| 996 | (basename | ||
| 997 | file)))) | ||
| 998 | (install-file file | ||
| 999 | (dirname target)) | ||
| 1000 | (delete-file file))) | ||
| 1001 | (find-files (string-append out "/bin") | ||
| 1002 | "^idle")) | ||
| 1003 | (match (find-files out "^idlelib$" | ||
| 1004 | #:directories? #t) | ||
| 1005 | ((idlelib) | ||
| 1006 | (let* ((len (string-length out)) | ||
| 1007 | (target (string-append idle "/" | ||
| 1008 | (string-drop | ||
| 1009 | idlelib len) | ||
| 1010 | "/site-packages"))) | ||
| 1011 | (mkdir-p (dirname target)) | ||
| 1012 | (rename-file idlelib target)))))))) | ||
| 1013 | (add-after 'move-idle 'rebuild-bytecode | ||
| 1014 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 1015 | ;; Disable hash randomization to ensure the generated .pycs | ||
| 1016 | ;; are reproducible. | ||
| 1017 | (setenv "PYTHONHASHSEED" "0") | ||
| 1018 | |||
| 1019 | (for-each (lambda (output) | ||
| 1020 | ;; XXX: Delete existing pycs generated by the build | ||
| 1021 | ;; system beforehand because the -f argument does | ||
| 1022 | ;; not necessarily overwrite all files, leading to | ||
| 1023 | ;; indeterministic results. | ||
| 1024 | (for-each (lambda (pyc) | ||
| 1025 | (delete-file pyc)) | ||
| 1026 | (find-files output "\\.pyc$")) | ||
| 1027 | |||
| 1028 | (apply invoke | ||
| 1029 | #$(if (%current-target-system) | ||
| 1030 | "python3" | ||
| 1031 | #~(string-append #$output "/bin/python3")) | ||
| 1032 | `("-m" "compileall" | ||
| 1033 | "-o" "0" | ||
| 1034 | "-o" "1" | ||
| 1035 | "-o" "2" | ||
| 1036 | "-f" ;force rebuild | ||
| 1037 | "--invalidation-mode=unchecked-hash" | ||
| 1038 | ;; Don't build lib2to3, because it's Python | ||
| 1039 | ;; 2 code. | ||
| 1040 | "-x" "lib2to3/.*" | ||
| 1041 | ,output))) | ||
| 1042 | (map cdr outputs)))) | ||
| 1043 | (add-before 'check 'set-TZDIR | ||
| 1044 | (lambda* (#:key inputs native-inputs #:allow-other-keys) | ||
| 1045 | ;; test_email requires the Olson time zone database. | ||
| 1046 | (setenv "TZDIR" | ||
| 1047 | (string-append (assoc-ref (or native-inputs | ||
| 1048 | inputs) "tzdata") | ||
| 1049 | "/share/zoneinfo")))) | ||
| 1050 | (add-after 'install 'add-libxcrypt-reference-pkgconfig | ||
| 1051 | (lambda* (#:key inputs #:allow-other-keys) | ||
| 1052 | (let ((libxcrypt | ||
| 1053 | (false-if-exception | ||
| 1054 | (dirname | ||
| 1055 | (search-input-file inputs "lib/libcrypt.so.1"))))) | ||
| 1056 | (when libxcrypt | ||
| 1057 | (substitute* | ||
| 1058 | (find-files (string-append #$output "/lib/pkgconfig") | ||
| 1059 | ".*\\.pc") | ||
| 1060 | (("Libs:") | ||
| 1061 | (string-append "Libs: " "-L" libxcrypt " -lcrypt"))))))) | ||
| 1062 | (add-after 'install 'install-sitecustomize.py | 898 | (add-after 'install 'install-sitecustomize.py |
| 1063 | #$(customize-site version))))) | 899 | #$(customize-site version))))) |
| 1064 | (inputs (list bzip2 | 900 | (inputs (list bzip2 |
| @@ -1223,223 +1059,7 @@ def contents() -> str: | |||
| 1223 | 1059 | ||
| 1224 | #:phases | 1060 | #:phases |
| 1225 | #~(modify-phases %standard-phases | 1061 | #~(modify-phases %standard-phases |
| 1226 | #$@(if (system-hurd?) | 1062 | #$@(common-python3-phases-edits) |
| 1227 | #~((add-after 'unpack | ||
| 1228 | 'disable-multi-processing | ||
| 1229 | (lambda _ | ||
| 1230 | (substitute* "Makefile.pre.in" | ||
| 1231 | (("-j0") | ||
| 1232 | "-j1"))))) | ||
| 1233 | #~()) | ||
| 1234 | (add-before 'configure 'patch-lib-shells | ||
| 1235 | (lambda _ | ||
| 1236 | ;; This variable is used in setup.py to enable cross compilation | ||
| 1237 | ;; specific switches. As it is not set properly by configure | ||
| 1238 | ;; script, set it manually. | ||
| 1239 | #$@(if (%current-target-system) | ||
| 1240 | #~((setenv "_PYTHON_HOST_PLATFORM" "")) | ||
| 1241 | #~()) | ||
| 1242 | ;; Filter for existing files, since some may not exist in all | ||
| 1243 | ;; versions of python that are built with this recipe. | ||
| 1244 | (substitute* (filter file-exists? | ||
| 1245 | '("Lib/subprocess.py" | ||
| 1246 | "Lib/popen2.py" | ||
| 1247 | "Lib/distutils/tests/test_spawn.py" | ||
| 1248 | "Lib/test/support/__init__.py" | ||
| 1249 | "Lib/test/test_subprocess.py")) | ||
| 1250 | (("/bin/sh") | ||
| 1251 | (which "sh"))))) | ||
| 1252 | (add-before 'configure 'do-not-record-configure-flags | ||
| 1253 | (lambda* (#:key configure-flags #:allow-other-keys) | ||
| 1254 | ;; Remove configure flags from the installed '_sysconfigdata.py' | ||
| 1255 | ;; and 'Makefile' so we don't end up keeping references to the | ||
| 1256 | ;; build tools. | ||
| 1257 | ;; | ||
| 1258 | ;; Preserve at least '--with-system-ffi' since otherwise the | ||
| 1259 | ;; thing tries to build libffi, fails, and we end up with a | ||
| 1260 | ;; Python that lacks ctypes. | ||
| 1261 | (substitute* "configure" | ||
| 1262 | (("^CONFIG_ARGS=.*$") | ||
| 1263 | (format #f "CONFIG_ARGS='~a'\n" | ||
| 1264 | (if (member "--with-system-ffi" | ||
| 1265 | configure-flags) | ||
| 1266 | "--with-system-ffi" "")))))) | ||
| 1267 | (add-before 'check 'pre-check | ||
| 1268 | (lambda _ | ||
| 1269 | ;; 'Lib/test/test_site.py' needs a valid $HOME | ||
| 1270 | (setenv "HOME" | ||
| 1271 | (getcwd)))) | ||
| 1272 | (add-after 'unpack 'set-source-file-times-to-1980 | ||
| 1273 | ;; XXX One of the tests uses a ZIP library to pack up some of the | ||
| 1274 | ;; source tree, and fails with "ZIP does not support timestamps | ||
| 1275 | ;; before 1980". Work around this by setting the file times in the | ||
| 1276 | ;; source tree to sometime in early 1980. | ||
| 1277 | (lambda _ | ||
| 1278 | (let ((circa-1980 (* 10 366 24 60 60))) | ||
| 1279 | (ftw "." | ||
| 1280 | (lambda (file stat flag) | ||
| 1281 | (utime file circa-1980 circa-1980) #t))))) | ||
| 1282 | (add-after 'unpack 'remove-windows-binaries | ||
| 1283 | (lambda _ | ||
| 1284 | ;; Delete .exe from embedded .whl (zip) files | ||
| 1285 | (for-each (lambda (whl) | ||
| 1286 | (let ((dir "whl-content") | ||
| 1287 | (circa-1980 (* 10 366 24 60 60))) | ||
| 1288 | (mkdir-p dir) | ||
| 1289 | (with-directory-excursion dir | ||
| 1290 | (let ((whl (string-append "../" whl))) | ||
| 1291 | (invoke "unzip" whl) | ||
| 1292 | (for-each delete-file | ||
| 1293 | (find-files "." "\\.exe$")) | ||
| 1294 | (delete-file whl) | ||
| 1295 | ;; Reset timestamps to prevent them from ending | ||
| 1296 | ;; up in the Zip archive. | ||
| 1297 | (ftw "." | ||
| 1298 | (lambda (file stat flag) | ||
| 1299 | (utime file circa-1980 | ||
| 1300 | circa-1980) #t)) | ||
| 1301 | (apply invoke "zip" "-X" whl | ||
| 1302 | (find-files "." | ||
| 1303 | #:directories? #t)))) | ||
| 1304 | (delete-file-recursively dir))) | ||
| 1305 | (find-files "Lib/ensurepip" "\\.whl$")))) | ||
| 1306 | (add-after 'install 'remove-tests | ||
| 1307 | ;; Remove 25 MiB of unneeded unit tests. Keep test_support.* | ||
| 1308 | ;; because these files are used by some libraries out there. | ||
| 1309 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 1310 | (let ((out (assoc-ref outputs "out"))) | ||
| 1311 | (match (scandir (string-append out "/lib") | ||
| 1312 | (lambda (name) | ||
| 1313 | (string-prefix? "python" name))) | ||
| 1314 | ((pythonX.Y) | ||
| 1315 | (let ((testdir (string-append out "/lib/" pythonX.Y | ||
| 1316 | "/test"))) | ||
| 1317 | (with-directory-excursion testdir | ||
| 1318 | (for-each delete-file-recursively | ||
| 1319 | (scandir testdir | ||
| 1320 | (match-lambda | ||
| 1321 | ((or "." "..") | ||
| 1322 | #f) | ||
| 1323 | ("support" #f) | ||
| 1324 | (file (not (string-prefix? | ||
| 1325 | "test_support." | ||
| 1326 | file)))))) | ||
| 1327 | (call-with-output-file "__init__.py" | ||
| 1328 | (const #t)))) | ||
| 1329 | (let ((libdir (string-append out "/lib/" pythonX.Y))) | ||
| 1330 | (for-each (lambda (directory) | ||
| 1331 | (let ((dir (string-append libdir "/" | ||
| 1332 | directory))) | ||
| 1333 | (when (file-exists? dir) | ||
| 1334 | (delete-file-recursively dir)))) | ||
| 1335 | '("email/test" "ctypes/test" | ||
| 1336 | "unittest/test" | ||
| 1337 | "tkinter/test" | ||
| 1338 | "sqlite3/test" | ||
| 1339 | "bsddb/test" | ||
| 1340 | "lib-tk/test" | ||
| 1341 | "json/tests" | ||
| 1342 | "distutils/tests")))))))) | ||
| 1343 | (add-after 'remove-tests 'move-tk-inter | ||
| 1344 | (lambda* (#:key outputs inputs #:allow-other-keys) | ||
| 1345 | ;; When Tkinter support is built move it to a separate output so | ||
| 1346 | ;; that the main output doesn't contain a reference to Tcl/Tk. | ||
| 1347 | (let ((out (assoc-ref outputs "out")) | ||
| 1348 | (tk (assoc-ref outputs "tk"))) | ||
| 1349 | (when tk | ||
| 1350 | (match (find-files out "tkinter.*\\.so") | ||
| 1351 | ((tkinter.so) | ||
| 1352 | ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we | ||
| 1353 | ;; want it under TK/lib/pythonX.Y/site-packages. | ||
| 1354 | (let* ((len (string-length out)) | ||
| 1355 | (target (string-append tk "/" | ||
| 1356 | (string-drop (dirname | ||
| 1357 | (dirname | ||
| 1358 | tkinter.so)) | ||
| 1359 | len) | ||
| 1360 | "/site-packages"))) | ||
| 1361 | (install-file tkinter.so target) | ||
| 1362 | (delete-file tkinter.so)))) | ||
| 1363 | ;; Remove explicit store path references. | ||
| 1364 | (let ((tcl (assoc-ref inputs "tcl")) | ||
| 1365 | (tk (assoc-ref inputs "tk"))) | ||
| 1366 | (substitute* (find-files (string-append out "/lib") | ||
| 1367 | "^(_sysconfigdata_.*\\.py|Makefile)$") | ||
| 1368 | (((string-append "-L" tk "/lib")) | ||
| 1369 | "") | ||
| 1370 | (((string-append "-L" tcl "/lib")) | ||
| 1371 | ""))))))) | ||
| 1372 | (add-after 'move-tk-inter 'move-idle | ||
| 1373 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 1374 | ;; when idle is built, move it to a separate output to save some | ||
| 1375 | ;; space (5MB) | ||
| 1376 | (let ((out (assoc-ref outputs "out")) | ||
| 1377 | (idle (assoc-ref outputs "idle"))) | ||
| 1378 | (when idle | ||
| 1379 | (for-each (lambda (file) | ||
| 1380 | (let ((target (string-append idle | ||
| 1381 | "/bin/" | ||
| 1382 | (basename | ||
| 1383 | file)))) | ||
| 1384 | (install-file file | ||
| 1385 | (dirname target)) | ||
| 1386 | (delete-file file))) | ||
| 1387 | (find-files (string-append out "/bin") | ||
| 1388 | "^idle")) | ||
| 1389 | (match (find-files out "^idlelib$" | ||
| 1390 | #:directories? #t) | ||
| 1391 | ((idlelib) | ||
| 1392 | (let* ((len (string-length out)) | ||
| 1393 | (target (string-append idle "/" | ||
| 1394 | (string-drop | ||
| 1395 | idlelib len) | ||
| 1396 | "/site-packages"))) | ||
| 1397 | (mkdir-p (dirname target)) | ||
| 1398 | (rename-file idlelib target)))))))) | ||
| 1399 | (add-after 'move-idle 'rebuild-bytecode | ||
| 1400 | (lambda* (#:key outputs #:allow-other-keys) | ||
| 1401 | (let ((out (assoc-ref outputs "out"))) | ||
| 1402 | ;; Disable hash randomization to ensure the generated .pycs | ||
| 1403 | ;; are reproducible. | ||
| 1404 | (setenv "PYTHONHASHSEED" "0") | ||
| 1405 | |||
| 1406 | (for-each (lambda (output) | ||
| 1407 | ;; XXX: Delete existing pycs generated by the build | ||
| 1408 | ;; system beforehand because the -f argument does | ||
| 1409 | ;; not necessarily overwrite all files, leading to | ||
| 1410 | ;; indeterministic results. | ||
| 1411 | (for-each (lambda (pyc) | ||
| 1412 | (delete-file pyc)) | ||
| 1413 | (find-files output "\\.pyc$")) | ||
| 1414 | |||
| 1415 | (apply invoke | ||
| 1416 | `(,#$(if (%current-target-system) | ||
| 1417 | "python3" | ||
| 1418 | #~(string-append | ||
| 1419 | out | ||
| 1420 | "/bin/python3")) "-m" | ||
| 1421 | "compileall" | ||
| 1422 | "-o" | ||
| 1423 | "0" | ||
| 1424 | "-o" | ||
| 1425 | "1" | ||
| 1426 | "-o" | ||
| 1427 | "2" | ||
| 1428 | "-f" ;force rebuild | ||
| 1429 | "--invalidation-mode=unchecked-hash" | ||
| 1430 | ;; Don't build lib2to3, because it's | ||
| 1431 | ;; Python 2 code. | ||
| 1432 | "-x" | ||
| 1433 | "lib2to3/.*" | ||
| 1434 | ,output))) | ||
| 1435 | (map cdr outputs))))) | ||
| 1436 | (add-before 'check 'set-TZDIR | ||
| 1437 | (lambda* (#:key inputs native-inputs #:allow-other-keys) | ||
| 1438 | ;; test_email requires the Olson time zone database. | ||
| 1439 | (setenv "TZDIR" | ||
| 1440 | (string-append (assoc-ref (or native-inputs | ||
| 1441 | inputs) "tzdata") | ||
| 1442 | "/share/zoneinfo")))) | ||
| 1443 | (add-after 'install 'install-sitecustomize.py | 1063 | (add-after 'install 'install-sitecustomize.py |
| 1444 | #$(customize-site version))))) | 1064 | #$(customize-site version))))) |
| 1445 | (inputs (list bzip2 | 1065 | (inputs (list bzip2 |
