projects/guix·blob librewolf-updates · refs

1674 lines · 83.2 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2013 Nikita Karetnikov <[email protected]>
3;;; Copyright © 2013-2018, 2021, 2023, 2025 Ludovic Courtès <[email protected]>
4;;; Copyright © 2013, 2014, 2015, 2016 Andreas Enge <[email protected]>
5;;; Copyright © 2014, 2015 Mark H Weaver <[email protected]>
6;;; Copyright © 2014, 2017, 2019 Eric Bavier <[email protected]>
7;;; Copyright © 2014, 2015 Federico Beffa <[email protected]>
8;;; Copyright © 2015 Omar Radwan <[email protected]>
9;;; Copyright © 2015 Pierre-Antoine Rault <[email protected]>
10;;; Copyright © 2015, 2016, 2017, 2018, 2019 Ricardo Wurmus <[email protected]>
11;;; Copyright © 2015, 2016 Christine Lemmer-Webber <[email protected]>
12;;; Copyright © 2015 Eric Dvorsak <[email protected]>
13;;; Copyright © 2015, 2016 David Thompson <[email protected]>
14;;; Copyright © 2015, 2016, 2017, 2021 Leo Famulari <[email protected]>
15;;; Copyright © 2015, 2017 Ben Woodcroft <[email protected]>
16;;; Copyright © 2015, 2016 Erik Edrosa <[email protected]>
17;;; Copyright © 2015-2020, 2023 Efraim Flashner <[email protected]>
18;;; Copyright © 2015, 2017 Kyle Meyer <[email protected]>
19;;; Copyright © 2015, 2016 Chris Marusich <[email protected]>
20;;; Copyright © 2016 Danny Milosavljevic <[email protected]>
21;;; Copyright © 2016 Lukas Gradl <[email protected]>
22;;; Copyright © 2016, 2018, 2025 Hartmut Goebel <[email protected]>
23;;; Copyright © 2016 Daniel Pimentel <[email protected]>
24;;; Copyright © 2016 Sou Bunnbu <[email protected]>
25;;; Copyright © 2016, 2017 Troy Sankey <[email protected]>
26;;; Copyright © 2016, 2017 Nikita <[email protected]>
27;;; Copyright © 2016 Dylan Jeffers <sapientech@[email protected]>
28;;; Copyright © 2016 David Craven <[email protected]>
29;;; Copyright © 2016-2022 Marius Bakke <[email protected]>
30;;; Copyright © 2016, 2017 Stefan Reichör <[email protected]>
31;;; Copyright © 2016, 2017 Alex Vong <[email protected]>
32;;; Copyright © 2016, 2017, 2018 Arun Isaac <[email protected]>
33;;; Copyright © 2016–2018, 2021, 2022 Tobias Geerinckx-Rice <[email protected]>
34;;; Copyright © 2016, 2017, 2018, 2021 Julien Lepiller <[email protected]>
35;;; Copyright © 2016, 2017 Thomas Danckaert <[email protected]>
36;;; Copyright © 2017 Carlo Zancanaro <[email protected]>
37;;; Copyright © 2017 Frederick M. Muriithi <[email protected]>
38;;; Copyright © 2017, 2018 Adriano Peluso <[email protected]>
39;;; Copyright © 2017 Ben Sturmfels <[email protected]>
40;;; Copyright © 2017, 2018, 2019 Mathieu Othacehe <[email protected]>
41;;; Copyright © 2017 José Miguel Sánchez García <[email protected]>
42;;; Copyright © 2017 Roel Janssen <[email protected]>
43;;; Copyright © 2017, 2018 Kei Kebreau <[email protected]>
44;;; Copyright © 2017 Rutger Helling <[email protected]>
45;;; Copyright © 2017 Brendan Tildesley <[email protected]>
46;;; Copyright © 2018 Ethan R. Jones <[email protected]
47;;; Copyright © 2018 Fis Trivial <[email protected]>
48;;; Copyright © 2018 Vijayalakshmi Vedantham <[email protected]>
49;;; Copyright © 2018 Mathieu Lirzin <[email protected]>
50;;; Copyright © 2018 Adam Massmann <[email protected]>
51;;; Copyright © 2016, 2018 Tomáš Čech <[email protected]>
52;;; Copyright © 2018 Nicolas Goaziou <[email protected]>
53;;; Copyright © 2018 Oleg Pykhalov <[email protected]>
54;;; Copyright © 2018 Clément Lassieur <[email protected]>
55;;; Copyright © 2018, 2019, 2020, 2021, 2025 Maxim Cournoyer <[email protected]>
56;;; Copyright © 2018 Luther Thompson <[email protected]>
57;;; Copyright © 2018 Vagrant Cascadian <[email protected]>
58;;; Copyright © 2019, 2024 Tanguy Le Carrour <[email protected]>
59;;; Copyright © 2020, 2023, 2025 Janneke Nieuwenhuizen <[email protected]>
60;;; Copyright © 2020, 2021 Greg Hogan <[email protected]>
61;;; Copyright © 2022 Philip McGrath <[email protected]>
62;;; Copyright © 2022 jgart <[email protected]>
63;;; Copyright © 2021 Lars-Dominik Braun <[email protected]>
64;;; Copyright © 2025 Hugo Buddelmeijer <[email protected]>
65;;; Copyright © 2025 Sharlatan Hellseher <[email protected]>
66;;;
67;;; This file is part of GNU Guix.
68;;;
69;;; GNU Guix is free software; you can redistribute it and/or modify it
70;;; under the terms of the GNU General Public License as published by
71;;; the Free Software Foundation; either version 3 of the License, or (at
72;;; your option) any later version.
73;;;
74;;; GNU Guix is distributed in the hope that it will be useful, but
75;;; WITHOUT ANY WARRANTY; without even the implied warranty of
76;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
77;;; GNU General Public License for more details.
78;;;
79;;; You should have received a copy of the GNU General Public License
80;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
81
82(define-module (gnu packages python)
83 #:use-module ((guix licenses) #:prefix license:)
84 #:use-module (gnu packages)
85 #:use-module (gnu packages base)
86 #:use-module (gnu packages bash)
87 #:use-module (gnu packages check)
88 #:use-module (gnu packages compression)
89 #:use-module (gnu packages crypto)
90 #:use-module (gnu packages dbm)
91 #:use-module (gnu packages libffi)
92 #:use-module (gnu packages pkg-config)
93 #:use-module (gnu packages python-build)
94 #:use-module (gnu packages readline)
95 #:use-module (gnu packages sqlite)
96 #:use-module (gnu packages tcl)
97 #:use-module (gnu packages tls)
98 #:use-module (gnu packages xml)
99 #:use-module (guix gexp)
100 #:use-module (guix git-download)
101 #:use-module (guix packages)
102 #:use-module (guix download)
103 #:use-module (guix search-paths)
104 #:use-module (guix utils)
105 #:use-module (guix build-system copy)
106 #:use-module (guix build-system gnu)
107 #:use-module (guix build-system trivial)
108 #:use-module (srfi srfi-1)
109 #:use-module (srfi srfi-26)
110
111 #:export (customize-site
112 guix-pythonpath-search-path))
113
114(define* (customize-site version)
115 "Generate a install-sitecustomize.py phase, using VERSION."
116 `(lambda* (#:key native-inputs inputs outputs #:allow-other-keys)
117 (let* ((out (assoc-ref outputs "out"))
118 (site-packages (string-append
119 out "/lib/python"
120 ,(version-major+minor version)
121 "/site-packages"))
122 (sitecustomize.py (assoc-ref (or native-inputs inputs)
123 "sitecustomize.py"))
124 (dest (string-append site-packages "/sitecustomize.py")))
125 (mkdir-p site-packages)
126 (copy-file sitecustomize.py dest)
127 ;; Set the correct permissions on the installed file, else the byte
128 ;; compilation phase fails with a permission denied error.
129 (chmod dest #o644))))
130
131(define (guix-pythonpath-search-path version)
132 "Generate a GUIX_PYTHONPATH search path specification, using VERSION."
133 (search-path-specification (variable "GUIX_PYTHONPATH")
134 (files (list (string-append
135 "lib/python"
136 (version-major+minor version)
137 "/site-packages")))))
138
139(define-public python-2.7
140 (package
141 (name "python2")
142 (version "2.7.18")
143 (source
144 (origin
145 (method url-fetch)
146 (uri (string-append "https://www.python.org/ftp/python/"
147 version "/Python-" version ".tar.xz"))
148 (sha256
149 (base32
150 "0hzgxl94hnflis0d6m4szjx0b52gah7wpmcg5g00q7am6xwhwb5n"))
151 (patches (search-patches "python-2.7-search-paths.patch"
152 "python-2-deterministic-build-info.patch"
153 "python-2.7-site-prefixes.patch"
154 "python-2.7-source-date-epoch.patch"
155 "python-2.7-adjust-tests.patch"
156 "python-cross-compile.patch"
157 "python-2.7-CVE-2021-3177.patch"
158 "python-2.7-expat-compat.patch"
159 "python-2.7-no-static-lib.patch"))
160 (modules '((guix build utils)))
161 (snippet
162 '(begin
163 ;; Ensure the bundled copies of these libraries are not used.
164 (for-each delete-file-recursively
165 '("Modules/_ctypes/libffi" "Modules/expat" "Modules/zlib"))
166
167 (substitute* "Modules/Setup.dist"
168 ;; Link Expat instead of embedding the bundled one.
169 (("^#pyexpat.*") "pyexpat pyexpat.c -lexpat\n"))
170
171 ;; Suboptimal to delete failing tests here, but if we delete them in
172 ;; the arguments then we need to make sure to strip out that phase
173 ;; when it gets inherited by python and python-minimal.
174 (for-each delete-file
175 '("Lib/test/test_compileall.py"
176 "Lib/test/test_ctypes.py" ; fails on mips64el
177 "Lib/test/test_distutils.py"
178 "Lib/test/test_import.py"
179 "Lib/test/test_shutil.py"
180 "Lib/test/test_socket.py"
181 "Lib/test/test_subprocess.py"))))))
182 (outputs '("out"
183 "tk" ;tkinter; adds 50 MiB to the closure
184 "idle")) ;programming environment; weighs 5MB
185 (build-system gnu-build-system)
186 (arguments
187 (list
188 #:test-target "test"
189 #:configure-flags
190 #~(list ;; -fno-semantic-interposition reinstates some optimizations by gcc
191 ;; leading to around 15% speedup. This is the default starting from
192 ;; python 3.10.
193 ;; XXX FIXME: How to add "-Wno-error=implicit-function-declaration"
194 ;; *only* for *this* python-2 package? It's not needed for any
195 ;; package inheriting from us.
196 "CFLAGS=-Wno-error=incompatible-pointer-types -fno-semantic-interposition"
197 "--enable-shared" ;allow embedding
198 "--with-system-expat" ;for XML support
199 "--with-system-ffi" ;build ctypes
200 "--with-ensurepip=install" ;install pip and setuptools
201 "--with-computed-gotos" ;main interpreter loop optimization
202 "--enable-unicode=ucs4"
203
204 ;; FIXME: These flags makes Python significantly faster, but
205 ;; leads to non-reproducible binaries.
206 ;; "--with-lto" ;increase size by 20MB, but 15% speedup
207 ;; "--enable-optimizations"
208
209 ;; Prevent the installed _sysconfigdata.py from retaining a reference
210 ;; to coreutils.
211 "INSTALL=install -c"
212 "MKDIR_P=mkdir -p"
213
214 ;; Disable runtime check failing if cross-compiling, see:
215 ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
216 #$@(if (%current-target-system)
217 #~("ac_cv_buggy_getaddrinfo=no"
218 "ac_cv_file__dev_ptmx=no"
219 "ac_cv_file__dev_ptc=no")
220 #~())
221 (string-append "LDFLAGS=-Wl,-rpath="
222 (assoc-ref %outputs "out") "/lib"
223 " -fno-semantic-interposition")
224 ;; Add a reference to libxcrypt in LIBS so that the sysconfigdata
225 ;; file records it and propagates it to programs linking against
226 ;; Python.
227 (let ((libxcrypt
228 (false-if-exception
229 (dirname
230 (search-input-file %build-inputs
231 "lib/libcrypt.so.1")))))
232 (string-append
233 "LIBS="
234 (if libxcrypt
235 (string-append "-L" libxcrypt)
236 ""))))
237 ;; With no -j argument tests use all available cpus, so provide one.
238 #:make-flags
239 #~(list (string-append
240 (format #f "TESTOPTS=-j~d" (parallel-job-count))
241 ;; Exclude the following tests as they fail
242 ;; non-deterministically with "error: [Errno 104] Connection
243 ;; reset by peer." Python 3 seems unaffected. A potential fix,
244 ;; yet to be backported to Python 2, is available at:
245 ;; https://github.com/python/cpython/commit/529525fb5a8fd9b96ab4021311a598c77588b918.
246 " --exclude test_urllib2_localnet test_httplib"))
247
248 #:modules '((ice-9 ftw)
249 (ice-9 match)
250 (guix build utils)
251 (guix build gnu-build-system))
252 #:phases
253 #~(modify-phases %standard-phases
254 (add-before
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?)
273 #~((add-before 'build 'patch-regen-for-hurd
274 (lambda* (#:key inputs #:allow-other-keys)
275 (let ((libc (assoc-ref inputs "libc")))
276 (substitute* "Lib/plat-generic/regen"
277 (("/usr/include/") (string-append libc "/include/")))))))
278 #~())
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
393 (lambda* (#:key outputs #:allow-other-keys)
394 (let ((out (assoc-ref outputs "out")))
395 ;; Disable hash randomization to ensure the generated .pycs
396 ;; are reproducible.
397 (setenv "PYTHONHASHSEED" "0")
398 (for-each
399 (lambda (output)
400 (for-each (lambda (opt)
401 (format #t "Compiling with optimization level: ~a\n"
402 (if (null? opt) "none" (car opt)))
403 (apply invoke
404 `(,#$(if (%current-target-system)
405 "python2"
406 #~(string-append out "/bin/python"))
407 ,@opt
408 "-m" "compileall"
409 "-f" ; force rebuild
410 ;; Don't build lib2to3, because it contains
411 ;; Python 3 code.
412 "-x" "lib2to3/.*"
413 ,output)))
414 ;; Python 2 has a single file extension (.pyo) for the
415 ;; chosen level of optimization, so it doesn't make
416 ;; sense to byte compile with more than one level.
417 (list '() '("-OO"))))
418 (map cdr outputs)))))
419 (add-after 'install 'install-sitecustomize.py
420 #$(customize-site version)))))
421 (inputs
422 (list bzip2
423 expat
424 gdbm
425 libffi ; for ctypes
426 libxcrypt ; crypto module slated for removal in 3.13, re-enable
427 ; python tests of libxcrypt when that happens
428 sqlite ; for sqlite extension
429 openssl-1.1
430 readline
431 zlib
432 tcl
433 tk)) ; for tkinter
434 (native-inputs
435 `(("pkg-config" ,pkg-config)
436 ("sitecustomize.py" ,(local-file (search-auxiliary-file
437 "python/sitecustomize.py")))
438 ;; When cross-compiling, a native version of Python itself is needed.
439 ,@(if (%current-target-system)
440 `(("python2" ,this-package)
441 ("which" ,which))
442 '())))
443 (native-search-paths
444 (list (guix-pythonpath-search-path version)))
445 (home-page "https://www.python.org")
446 (synopsis "High-level, dynamically-typed programming language")
447 (description
448 "Python is a remarkably powerful dynamic programming language that
449is used in a wide variety of application domains. Some of its key
450distinguishing features include: clear, readable syntax; strong
451introspection capabilities; intuitive object orientation; natural
452expression of procedural code; full modularity, supporting hierarchical
453packages; exception-based error handling; and very high level dynamic
454data types.")
455 (properties '((cpe-name . "python")
456 (cpe-vendor . "python")
457 ;; CVE-2023-36632 is not a bug according to
458 ;; https://github.com/python/cpython/issues/103800
459 (lint-hidden-cve . ("CVE-2023-36632"))))
460 (license license:psfl)))
461
462;; Current 2.x version.
463(define-public python-2 python-2.7)
464
465(define-public python-3.10
466 (package
467 (inherit python-2)
468 (name "python")
469 (version "3.10.19")
470 (source (origin
471 (method url-fetch)
472 (uri (string-append "https://www.python.org/ftp/python/"
473 version "/Python-" version ".tar.xz"))
474 (patches (search-patches
475 "python-3-arm-alignment.patch"
476 "python-3-deterministic-build-info.patch"
477 "python-3-fix-tests.patch"
478 "python-3-hurd-configure.patch"
479 "python-3-reproducible-build.patch"
480 "python-3-search-paths.patch"))
481 (sha256
482 (base32
483 "0xn0jydg5fsz9fsni6a83l7sf6by2w7gg4fzswfxh092aybabx68"))
484 (modules '((guix build utils)))
485 (snippet
486 '(begin
487 ;; Delete the bundled copy of libexpat.
488 (delete-file-recursively "Modules/expat")
489 (substitute* "Modules/Setup"
490 ;; Link Expat instead of embedding the bundled one.
491 (("^#pyexpat.*") "pyexpat pyexpat.c -lexpat\n"))
492 ;; Delete windows binaries
493 (for-each delete-file
494 (find-files "Lib/distutils/command" "\\.exe$"))))))
495 (arguments
496 (substitute-keyword-arguments (package-arguments python-2)
497 ((#:configure-flags flags)
498 #~(append #$flags
499 ;; XXX Use quote to avoid world rebuild at this time
500 '("--without-static-libpython")))
501 ((#:make-flags _)
502 #~(list (string-append
503 (format #f "TESTOPTS=-j~d" (parallel-job-count))
504 ;; test_mmap fails on low-memory systems
505 " --exclude test_mmap test_socket"
506 #$@(if (system-hurd?)
507 #~(" test_posix" ;multiple errors
508 " test_time"
509 " test_pty"
510 " test_shutil"
511 " test_tempfile" ;chflags: invalid argument:
512 ; tbv14c9t/dir0/dir0/dir0/test0.txt
513 " test_asyncio" ;runs over 10min
514 " test_os" ;stty: 'standard input':
515 ; Inappropriate ioctl for device
516 " test_openpty" ;No such file or directory
517 " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
518 ; 32752 != 4
519 " test_compileall" ;multiple errors
520 " test_poll" ;list index out of range
521 " test_subprocess" ;runs over 10min
522 " test_asyncore" ;multiple errors
523 " test_threadsignals"
524 " test_eintr" ;Process return code is -14
525 " test_io" ;multiple errors
526 " test_logging"
527 " test_signal"
528 " test_threading" ;runs over 10min
529 " test_flags" ;ERROR
530 " test_bidirectional_pty"
531 " test_create_unix_connection"
532 " test_unix_sock_client_ops"
533 " test_open_unix_connection"
534 " test_open_unix_connection_error"
535 " test_read_pty_output"
536 " test_write_pty"
537 " test_concurrent_futures" ;freeze
538 " test_venv" ;freeze
539 " test_multiprocessing_forkserver" ;runs over 10min
540 " test_multiprocessing_spawn" ;runs over 10min
541 " test_builtin"
542 " test_capi"
543 " test_dbm_ndbm"
544 " test_exceptions"
545 " test_faulthandler"
546 " test_getopt"
547 " test_importlib"
548 " test_json"
549 " test_multiprocessing_fork"
550 " test_multiprocessing_main_handling"
551 " test_pdb "
552 " test_regrtest"
553 " test_sqlite")
554 #~()))))
555 ((#:phases phases)
556 #~(modify-phases #$phases
557 #$@(if (system-hurd?)
558 #~((delete 'patch-regen-for-hurd) ;regen was removed after 3.5.9
559 (add-after 'unpack 'disable-multi-processing
560 (lambda _
561 (substitute* "Makefile.pre.in"
562 (("-j0") "-j1")))))
563 #~())
564 (add-after 'unpack 'remove-vendored-wheel-content
565 (lambda _
566 ;; Delete .exe from embedded .whl (zip) files
567 (for-each
568 (lambda (whl)
569 (let ((dir "whl-content")
570 (circa-1980 (* 10 366 24 60 60)))
571 (mkdir-p dir)
572 (with-directory-excursion dir
573 (let ((whl (string-append "../" whl)))
574 (invoke "unzip" whl)
575 (for-each delete-file
576 (find-files "." "\\.exe$"))
577 (delete-file whl)
578
579 ;; Search for cacert.pem, delete it, and rewrite the
580 ;; file which directs python to look for it.
581 (let ((cacert (find-files "." "cacert\\.pem")))
582 (unless (null? cacert)
583 (let ((certifi (dirname (car cacert))))
584 (delete-file (string-append certifi "/cacert.pem"))
585 (delete-file (string-append certifi "/core.py"))
586 (with-output-to-file (string-append certifi "/core.py")
587 (lambda _
588 (display "\"\"\"
589certifi.py
590~~~~~~~~~~
591This file is a Guix-specific version of core.py.
592
593This module returns the installation location of SSL_CERT_FILE or
594/etc/ssl/certs/ca-certificates.crt, or its contents.
595\"\"\"
596import os
597
598_CA_CERTS = None
599
600try:
601 _CA_CERTS = os.environ [\"SSL_CERT_FILE\"]
602except:
603 _CA_CERTS = os.path.join(\"/etc\", \"ssl\", \"certs\", \"ca-certificates.crt\")
604
605def where() -> str:
606 return _CA_CERTS
607
608def contents() -> str:
609 with open(where(), \"r\", encoding=\"ascii\") as data:
610 return data.read()"))))))
611
612 ;; Reset timestamps to prevent them from ending
613 ;; up in the Zip archive.
614 (ftw "." (lambda (file stat flag)
615 (utime file circa-1980 circa-1980)
616 #t))
617 (apply invoke "zip" "-X" whl
618 (find-files "." #:directories? #t))))
619 (delete-file-recursively dir)))
620 (find-files "Lib/ensurepip" "\\.whl$"))))
621 (add-before 'check 'set-TZDIR
622 (lambda* (#:key inputs native-inputs #:allow-other-keys)
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
661 (modify-inputs (package-inputs python-2.7)
662 (replace "openssl" openssl)))
663 (native-inputs
664 (let ((inputs (modify-inputs (package-native-inputs python-2)
665 (prepend tzdata-for-tests
666 unzip
667 (@ (gnu packages compression) zip)))))
668 (if (%current-target-system)
669 (modify-inputs inputs (prepend this-package))
670 inputs)))
671 (native-search-paths
672 (list (guix-pythonpath-search-path version)
673 ;; Used to locate tzdata by the zoneinfo module introduced in
674 ;; Python 3.9.
675 (search-path-specification
676 (variable "PYTHONTZPATH")
677 (files (list "share/zoneinfo")))))))
678
679(define-public python-3.11
680 (package
681 (inherit python-3.10)
682 (name "python")
683 (version "3.11.14")
684 (source (origin
685 (method url-fetch)
686 (uri (string-append "https://www.python.org/ftp/python/"
687 version "/Python-" version ".tar.xz"))
688 (patches (search-patches
689 "python-3-deterministic-build-info.patch"
690 "python-3.11-fix-tests.patch"
691 "python-3-hurd-configure.patch"
692 "python-3-search-paths.patch"))
693 (sha256
694 (base32
695 "0y4v42qm66nvizjxbnixh59283a54nki51jmbrgwkhc8bkndhgld"))
696 (modules '((guix build utils)))
697 (snippet
698 '(begin
699 ;; Delete the bundled copy of libexpat.
700 (delete-file-recursively "Modules/expat")
701 (substitute* "Modules/Setup"
702 ;; Link Expat instead of embedding the bundled one.
703 (("^#pyexpat.*") "pyexpat pyexpat.c -lexpat\n"))
704 ;; Delete windows binaries
705 (for-each delete-file
706 (find-files "Lib/distutils/command" "\\.exe$"))))))
707 (arguments
708 (list
709 #:test-target "test"
710 #:configure-flags
711 #~(list "--enable-shared" ;allow embedding
712 "--with-system-expat" ;for XML support
713 "--with-system-ffi" ;build ctypes
714 "--with-ensurepip=install" ;install pip and setuptools
715 "--with-computed-gotos" ;main interpreter loop optimization
716 "--enable-unicode=ucs4"
717 "--without-static-libpython"
718 "--enable-loadable-sqlite-extensions"
719
720 ;; FIXME: These flags makes Python significantly faster,
721 ;; but leads to non-reproducible binaries.
722 ;; "--with-lto" ;increase size by 20MB, but 15% speedup
723 ;; "--enable-optimizations"
724
725 ;; Prevent the installed _sysconfigdata.py from retaining
726 ;; a reference to coreutils.
727 "INSTALL=install -c"
728 "MKDIR_P=mkdir -p"
729
730 ;; Add a reference to libxcrypt in LIBS so that the
731 ;; sysconfigdata file records it and propagates it to programs
732 ;; linking against Python.
733 (let ((libxcrypt
734 (false-if-exception
735 (dirname
736 (search-input-file %build-inputs
737 "lib/libcrypt.so.1")))))
738 (string-append
739 "LIBS="
740 (if libxcrypt
741 (string-append "-L" libxcrypt)
742 "")))
743
744 ;; Disable runtime check failing if cross-compiling, see:
745 ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
746 #$@(if (%current-target-system)
747 #~("ac_cv_buggy_getaddrinfo=no"
748 "ac_cv_file__dev_ptmx=no"
749 "ac_cv_file__dev_ptc=no"
750 (string-append "--with-build-python="
751 #+(this-package-native-input "python")
752 "/bin/python3"))
753 '())
754 ;; -fno-semantic-interposition reinstates some
755 ;; optimizations by gcc leading to around 15% speedup.
756 ;; This is the default starting from python 3.10.
757 "CFLAGS=-fno-semantic-interposition"
758 (string-append "LDFLAGS=-Wl,-rpath=" #$output "/lib"
759 " -fno-semantic-interposition"))
760 ;; With no -j argument tests use all available cpus, so provide one.
761 #:make-flags
762 `(list (string-append (format #f "TESTOPTS=-j~d"
763 (parallel-job-count))
764 ;; those tests fail on low-memory systems
765 " --exclude"
766 " test_mmap"
767 " test_socket"
768 " test_threading"
769 " test_asyncio"
770 " test_shutdown"
771 ,@(if (system-hurd?)
772 '(" test_posix" ;multiple errors
773 " test_time"
774 " test_pty"
775 " test_shutil"
776 " test_tempfile" ;chflags: invalid argument:
777 ;; tbv14c9t/dir0/dir0/dir0/test0.txt
778 " test_os" ;stty: 'standard input':
779 ;; Inappropriate ioctl for device
780 " test_openpty" ;No such file or directory
781 " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
782 ;; 32752 != 4
783 " test_compileall" ;multiple errors
784 " test_poll" ;list index out of range
785 " test_subprocess" ;runs over 10min
786 " test_asyncore" ;multiple errors
787 " test_threadsignals"
788 " test_eintr" ;Process return code is -14
789 " test_io" ;multiple errors
790 " test_logging"
791 " test_signal"
792 " test_flags" ;ERROR
793 " test_bidirectional_pty"
794 " test_create_unix_connection"
795 " test_unix_sock_client_ops"
796 " test_open_unix_connection"
797 " test_open_unix_connection_error"
798 " test_read_pty_output"
799 " test_write_pty"
800 " test_concurrent_futures" ;freeze
801 " test_venv" ;freeze
802 " test_multiprocessing_forkserver" ;runs over 10min
803 " test_multiprocessing_spawn" ;runs over 10min
804 " test_glob" ;did not finish in 10h
805 " test_site" ;Invalid argument
806 " test_termios" ;os.openpty() Operation not permitted
807 " test_tty" ;os.openpty() Operation not permitted
808 " test_sqlite3" ;; sqlite3.OperationalError: database is locked
809 " test_tarfile" ;; ELOOP vs ENAMETOOLONG
810 " test_builtin"
811 " test_capi"
812 " test_dbm_ndbm"
813 " test_exceptions"
814 " test_faulthandler"
815 " test_getopt"
816 " test_importlib"
817 " test_json"
818 " test_multiprocessing_fork"
819 " test_multiprocessing_main_handling"
820 " test_pdb "
821 " test_regrtest"
822 " test_sqlite")
823 '())
824 ,@(if (system-hurd64?)
825 '(" test_largefile") ;; hangs
826 '())))
827
828 #:modules
829 '((ice-9 ftw)
830 (ice-9 match)
831 (guix build utils)
832 (guix build gnu-build-system))
833
834 #:phases
835 #~(modify-phases %standard-phases
836 #$@(if (system-hurd?)
837 `((add-after 'unpack
838 'disable-multi-processing
839 (lambda _
840 (substitute* "Makefile.pre.in"
841 (("-j0")
842 "-j1")))))
843 '())
844 (add-before 'configure 'patch-lib-shells
845 (lambda _
846 ;; This variable is used in setup.py to enable cross compilation
847 ;; specific switches. As it is not set properly by configure
848 ;; script, set it manually.
849 #$@(if (%current-target-system)
850 '((setenv "_PYTHON_HOST_PLATFORM" ""))
851 '())
852 ;; Filter for existing files, since some may not exist in all
853 ;; versions of python that are built with this recipe.
854 (substitute* (filter file-exists?
855 '("Lib/subprocess.py"
856 "Lib/popen2.py"
857 "Lib/distutils/tests/test_spawn.py"
858 "Lib/test/support/__init__.py"
859 "Lib/test/test_subprocess.py"))
860 (("/bin/sh")
861 (which "sh")))))
862 (add-before 'configure 'do-not-record-configure-flags
863 (lambda* (#:key configure-flags #:allow-other-keys)
864 ;; Remove configure flags from the installed '_sysconfigdata.py'
865 ;; and 'Makefile' so we don't end up keeping references to the
866 ;; build tools.
867 ;;
868 ;; Preserve at least '--with-system-ffi' since otherwise the
869 ;; thing tries to build libffi, fails, and we end up with a
870 ;; Python that lacks ctypes.
871 (substitute* "configure"
872 (("^CONFIG_ARGS=.*$")
873 (format #f "CONFIG_ARGS='~a'\n"
874 (if (member "--with-system-ffi"
875 configure-flags)
876 "--with-system-ffi" ""))))))
877 (add-before 'check 'pre-check
878 (lambda _
879 ;; 'Lib/test/test_site.py' needs a valid $HOME
880 (setenv "HOME"
881 (getcwd))))
882 (add-after 'unpack 'set-source-file-times-to-1980
883 ;; XXX One of the tests uses a ZIP library to pack up some of the
884 ;; source tree, and fails with "ZIP does not support timestamps
885 ;; before 1980". Work around this by setting the file times in the
886 ;; source tree to sometime in early 1980.
887 (lambda _
888 (let ((circa-1980 (* 10 366 24 60 60)))
889 (ftw "."
890 (lambda (file stat flag)
891 (utime file circa-1980 circa-1980) #t)))))
892 (add-after 'unpack 'remove-windows-binaries
893 (lambda _
894 ;; Delete .exe from embedded .whl (zip) files
895 (for-each (lambda (whl)
896 (let ((dir "whl-content")
897 (circa-1980 (* 10 366 24 60 60)))
898 (mkdir-p dir)
899 (with-directory-excursion dir
900 (let ((whl (string-append "../" whl)))
901 (invoke "unzip" whl)
902 (for-each delete-file
903 (find-files "." "\\.exe$"))
904 (delete-file whl)
905 ;; Reset timestamps to prevent them from ending
906 ;; up in the Zip archive.
907 (ftw "."
908 (lambda (file stat flag)
909 (utime file circa-1980
910 circa-1980) #t))
911 (apply invoke "zip" "-X" whl
912 (find-files "."
913 #:directories? #t))))
914 (delete-file-recursively dir)))
915 (find-files "Lib/ensurepip" "\\.whl$"))))
916 (add-after 'install 'remove-tests
917 ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
918 ;; because these files are used by some libraries out there.
919 (lambda* (#:key outputs #:allow-other-keys)
920 (let ((out (assoc-ref outputs "out")))
921 (match (scandir (string-append out "/lib")
922 (lambda (name)
923 (string-prefix? "python" name)))
924 ((pythonX.Y)
925 (let ((testdir (string-append out "/lib/" pythonX.Y
926 "/test")))
927 (with-directory-excursion testdir
928 (for-each delete-file-recursively
929 (scandir testdir
930 (match-lambda
931 ((or "." "..")
932 #f)
933 ("support" #f)
934 (file (not (string-prefix?
935 "test_support."
936 file))))))
937 (call-with-output-file "__init__.py"
938 (const #t))))
939 (let ((libdir (string-append out "/lib/" pythonX.Y)))
940 (for-each (lambda (directory)
941 (let ((dir (string-append libdir "/"
942 directory)))
943 (when (file-exists? dir)
944 (delete-file-recursively dir))))
945 '("email/test" "ctypes/test"
946 "unittest/test"
947 "tkinter/test"
948 "sqlite3/test"
949 "bsddb/test"
950 "lib-tk/test"
951 "json/tests"
952 "distutils/tests"))))))))
953 (add-after 'remove-tests 'move-tk-inter
954 (lambda* (#:key outputs inputs #:allow-other-keys)
955 ;; When Tkinter support is built move it to a separate output so
956 ;; that the main output doesn't contain a reference to Tcl/Tk.
957 (let ((out (assoc-ref outputs "out"))
958 (tk (assoc-ref outputs "tk")))
959 (when tk
960 (match (find-files out "tkinter.*\\.so")
961 ((tkinter.so)
962 ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
963 ;; want it under TK/lib/pythonX.Y/site-packages.
964 (let* ((len (string-length out))
965 (target (string-append tk "/"
966 (string-drop (dirname
967 (dirname
968 tkinter.so))
969 len)
970 "/site-packages")))
971 (install-file tkinter.so target)
972 (delete-file tkinter.so))))
973 ;; Remove explicit store path references.
974 (let ((tcl (assoc-ref inputs "tcl"))
975 (tk (assoc-ref inputs "tk")))
976 (substitute* (find-files (string-append out "/lib")
977 "^(_sysconfigdata_.*\\.py|Makefile)$")
978 (((string-append "-L" tk "/lib"))
979 "")
980 (((string-append "-L" tcl "/lib"))
981 "")))))))
982 (add-after 'move-tk-inter 'move-idle
983 (lambda* (#:key outputs #:allow-other-keys)
984 ;; when idle is built, move it to a separate output to save some
985 ;; space (5MB)
986 (let ((out (assoc-ref outputs "out"))
987 (idle (assoc-ref outputs "idle")))
988 (when idle
989 (for-each (lambda (file)
990 (let ((target (string-append idle
991 "/bin/"
992 (basename
993 file))))
994 (install-file file
995 (dirname target))
996 (delete-file file)))
997 (find-files (string-append out "/bin")
998 "^idle"))
999 (match (find-files out "^idlelib$"
1000 #:directories? #t)
1001 ((idlelib)
1002 (let* ((len (string-length out))
1003 (target (string-append idle "/"
1004 (string-drop
1005 idlelib len)
1006 "/site-packages")))
1007 (mkdir-p (dirname target))
1008 (rename-file idlelib target))))))))
1009 (add-after 'move-idle 'rebuild-bytecode
1010 (lambda* (#:key outputs #:allow-other-keys)
1011 ;; Disable hash randomization to ensure the generated .pycs
1012 ;; are reproducible.
1013 (setenv "PYTHONHASHSEED" "0")
1014
1015 (for-each (lambda (output)
1016 ;; XXX: Delete existing pycs generated by the build
1017 ;; system beforehand because the -f argument does
1018 ;; not necessarily overwrite all files, leading to
1019 ;; indeterministic results.
1020 (for-each (lambda (pyc)
1021 (delete-file pyc))
1022 (find-files output "\\.pyc$"))
1023
1024 (apply invoke
1025 #$(if (%current-target-system)
1026 "python3"
1027 #~(string-append #$output "/bin/python3"))
1028 `("-m" "compileall"
1029 "-o" "0"
1030 "-o" "1"
1031 "-o" "2"
1032 "-f" ;force rebuild
1033 "--invalidation-mode=unchecked-hash"
1034 ;; Don't build lib2to3, because it's Python
1035 ;; 2 code.
1036 "-x" "lib2to3/.*"
1037 ,output)))
1038 (map cdr outputs))))
1039 (add-before 'check 'set-TZDIR
1040 (lambda* (#:key inputs native-inputs #:allow-other-keys)
1041 ;; test_email requires the Olson time zone database.
1042 (setenv "TZDIR"
1043 (string-append (assoc-ref (or native-inputs
1044 inputs) "tzdata")
1045 "/share/zoneinfo"))))
1046 (add-after 'install 'add-libxcrypt-reference-pkgconfig
1047 (lambda* (#:key inputs #:allow-other-keys)
1048 (let ((libxcrypt
1049 (false-if-exception
1050 (dirname
1051 (search-input-file inputs "lib/libcrypt.so.1")))))
1052 (when libxcrypt
1053 (substitute*
1054 (find-files (string-append #$output "/lib/pkgconfig")
1055 ".*\\.pc")
1056 (("Libs:")
1057 (string-append "Libs: " "-L" libxcrypt " -lcrypt")))))))
1058 (add-after 'install 'install-sitecustomize.py
1059 #$(customize-site version)))))
1060 (inputs (list bzip2
1061 expat
1062 gdbm
1063 libffi ;for ctypes
1064 libxcrypt ;crypto module slated for removal in 3.13
1065 sqlite ;for sqlite extension
1066 openssl
1067 readline
1068 zlib
1069 tcl
1070 tk)) ;for tkinter
1071 (native-inputs `(("tzdata" ,tzdata-for-tests)
1072 ("unzip" ,unzip)
1073 ("zip" ,(@ (gnu packages compression) zip))
1074 ("pkg-config" ,pkg-config)
1075 ("sitecustomize.py" ,(local-file (search-auxiliary-file
1076 "python/sitecustomize.py")))
1077 ;; When cross-compiling, a native version of Python itself is needed.
1078 ,@(if (%current-target-system)
1079 `(("python" ,this-package)
1080 ("which" ,which))
1081 '())))
1082 (native-search-paths
1083 (list (guix-pythonpath-search-path version)
1084 ;; Used to locate tzdata by the zoneinfo module introduced in
1085 ;; Python 3.9.
1086 (search-path-specification
1087 (variable "PYTHONTZPATH")
1088 (files (list "share/zoneinfo")))))))
1089
1090(define-public python-3.12
1091 (package
1092 (name "python-next")
1093 (version "3.12.12")
1094 (source
1095 (origin
1096 (method url-fetch)
1097 (uri (string-append "https://www.python.org/ftp/python/" version
1098 "/Python-" version ".tar.xz"))
1099 (sha256
1100 (base32 "1i2nqvnm2b7aakj2rf8qdfsk0nh55ly55gcbl6dw8a5h2hsa31gv"))
1101 (patches (search-patches "python-3-deterministic-build-info.patch"
1102 "python-3.12-fix-tests.patch"
1103 "python-3-hurd-configure.patch"))
1104 (modules '((guix build utils)))
1105 (snippet '(begin
1106 ;; Delete the bundled copy of libexpat.
1107 (delete-file-recursively "Modules/expat")
1108 (substitute* "Modules/Setup"
1109 ;; Link Expat instead of embedding the bundled one.
1110 (("^#pyexpat.*")
1111 "pyexpat pyexpat.c -lexpat\n"))
1112 ;; Delete windows binaries
1113 (for-each delete-file
1114 (find-files "Lib/distutils/command" "\\.exe$"))))))
1115 (outputs '("out" "tk" ;tkinter; adds 50 MiB to the closure
1116 "idle")) ;programming environment; weighs 5MB
1117 (build-system gnu-build-system)
1118 (arguments
1119 (list
1120 #:test-target "test"
1121 #:configure-flags
1122 #~(list "--enable-shared" ;allow embedding
1123 "--with-system-expat" ;for XML support
1124 "--with-system-ffi" ;build ctypes
1125 "--with-ensurepip=install" ;install pip and setuptools
1126 "--with-computed-gotos" ;main interpreter loop optimization
1127 "--enable-unicode=ucs4"
1128 "--without-static-libpython"
1129 "--enable-loadable-sqlite-extensions"
1130
1131 ;; FIXME: These flags makes Python significantly faster,
1132 ;; but leads to non-reproducible binaries.
1133 ;; "--with-lto" ;increase size by 20MB, but 15% speedup
1134 ;; "--enable-optimizations"
1135
1136 ;; Prevent the installed _sysconfigdata.py from retaining
1137 ;; a reference to coreutils.
1138 "INSTALL=install -c"
1139 "MKDIR_P=mkdir -p"
1140
1141 ;; Disable runtime check failing if cross-compiling, see:
1142 ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
1143 #$@(if (%current-target-system)
1144 #~("ac_cv_buggy_getaddrinfo=no"
1145 "ac_cv_file__dev_ptmx=no"
1146 "ac_cv_file__dev_ptc=no")
1147 #~())
1148 ;; -fno-semantic-interposition reinstates some
1149 ;; optimizations by gcc leading to around 15% speedup.
1150 ;; This is the default starting from python 3.10.
1151 "CFLAGS=-fno-semantic-interposition"
1152 (string-append "LDFLAGS=-Wl,-rpath="
1153 (assoc-ref %outputs "out")
1154 "/lib"
1155 " -fno-semantic-interposition"))
1156 ;; With no -j argument tests use all available cpus, so provide one.
1157 #:make-flags
1158 #~(list (string-append (format #f "TESTOPTS=-j~d"
1159 (parallel-job-count))
1160 ;; those tests fail on low-memory systems
1161 " --exclude"
1162 " test_mmap"
1163 " test_socket"
1164 " test_threading"
1165 " test_asyncio"
1166 " test_shutdown"
1167 #$@(if (system-hurd?)
1168 #~(" test_posix" ;multiple errors
1169 " test_time"
1170 " test_pty"
1171 " test_shutil"
1172 " test_tempfile" ;chflags: invalid argument:
1173 ;; tbv14c9t/dir0/dir0/dir0/test0.txt
1174 " test_os" ;stty: 'standard input':
1175 ;; Inappropriate ioctl for device
1176 " test_openpty" ;No such file or directory
1177 " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
1178 ;; 32752 != 4
1179 " test_compileall" ;multiple errors
1180 " test_poll" ;list index out of range
1181 " test_subprocess" ;runs over 10min
1182 " test_asyncore" ;multiple errors
1183 " test_threadsignals"
1184 " test_eintr" ;Process return code is -14
1185 " test_io" ;multiple errors
1186 " test_logging"
1187 " test_signal"
1188 " test_flags" ;ERROR
1189 " test_bidirectional_pty"
1190 " test_create_unix_connection"
1191 " test_unix_sock_client_ops"
1192 " test_open_unix_connection"
1193 " test_open_unix_connection_error"
1194 " test_read_pty_output"
1195 " test_write_pty"
1196 " test_concurrent_futures" ;freeze
1197 " test_venv" ;freeze
1198 " test_multiprocessing_forkserver" ;runs over 10min
1199 " test_multiprocessing_spawn" ;runs over 10min
1200 " test_builtin"
1201 " test_capi"
1202 " test_dbm_ndbm"
1203 " test_exceptions"
1204 " test_faulthandler"
1205 " test_getopt"
1206 " test_importlib"
1207 " test_json"
1208 " test_multiprocessing_fork"
1209 " test_multiprocessing_main_handling"
1210 " test_pdb "
1211 " test_regrtest"
1212 " test_sqlite")
1213 #~())))
1214
1215 #:modules '((ice-9 ftw)
1216 (ice-9 match)
1217 (guix build utils)
1218 (guix build gnu-build-system))
1219
1220 #:phases
1221 #~(modify-phases %standard-phases
1222 #$@(if (system-hurd?)
1223 #~((add-after 'unpack
1224 'disable-multi-processing
1225 (lambda _
1226 (substitute* "Makefile.pre.in"
1227 (("-j0")
1228 "-j1")))))
1229 #~())
1230 (add-before 'configure 'patch-lib-shells
1231 (lambda _
1232 ;; This variable is used in setup.py to enable cross compilation
1233 ;; specific switches. As it is not set properly by configure
1234 ;; script, set it manually.
1235 #$@(if (%current-target-system)
1236 #~((setenv "_PYTHON_HOST_PLATFORM" ""))
1237 #~())
1238 ;; Filter for existing files, since some may not exist in all
1239 ;; versions of python that are built with this recipe.
1240 (substitute* (filter file-exists?
1241 '("Lib/subprocess.py"
1242 "Lib/popen2.py"
1243 "Lib/distutils/tests/test_spawn.py"
1244 "Lib/test/support/__init__.py"
1245 "Lib/test/test_subprocess.py"))
1246 (("/bin/sh")
1247 (which "sh")))))
1248 (add-before 'configure 'do-not-record-configure-flags
1249 (lambda* (#:key configure-flags #:allow-other-keys)
1250 ;; Remove configure flags from the installed '_sysconfigdata.py'
1251 ;; and 'Makefile' so we don't end up keeping references to the
1252 ;; build tools.
1253 ;;
1254 ;; Preserve at least '--with-system-ffi' since otherwise the
1255 ;; thing tries to build libffi, fails, and we end up with a
1256 ;; Python that lacks ctypes.
1257 (substitute* "configure"
1258 (("^CONFIG_ARGS=.*$")
1259 (format #f "CONFIG_ARGS='~a'\n"
1260 (if (member "--with-system-ffi"
1261 configure-flags)
1262 "--with-system-ffi" ""))))))
1263 (add-before 'check 'pre-check
1264 (lambda _
1265 ;; 'Lib/test/test_site.py' needs a valid $HOME
1266 (setenv "HOME"
1267 (getcwd))))
1268 (add-after 'unpack 'set-source-file-times-to-1980
1269 ;; XXX One of the tests uses a ZIP library to pack up some of the
1270 ;; source tree, and fails with "ZIP does not support timestamps
1271 ;; before 1980". Work around this by setting the file times in the
1272 ;; source tree to sometime in early 1980.
1273 (lambda _
1274 (let ((circa-1980 (* 10 366 24 60 60)))
1275 (ftw "."
1276 (lambda (file stat flag)
1277 (utime file circa-1980 circa-1980) #t)))))
1278 (add-after 'unpack 'remove-windows-binaries
1279 (lambda _
1280 ;; Delete .exe from embedded .whl (zip) files
1281 (for-each (lambda (whl)
1282 (let ((dir "whl-content")
1283 (circa-1980 (* 10 366 24 60 60)))
1284 (mkdir-p dir)
1285 (with-directory-excursion dir
1286 (let ((whl (string-append "../" whl)))
1287 (invoke "unzip" whl)
1288 (for-each delete-file
1289 (find-files "." "\\.exe$"))
1290 (delete-file whl)
1291 ;; Reset timestamps to prevent them from ending
1292 ;; up in the Zip archive.
1293 (ftw "."
1294 (lambda (file stat flag)
1295 (utime file circa-1980
1296 circa-1980) #t))
1297 (apply invoke "zip" "-X" whl
1298 (find-files "."
1299 #:directories? #t))))
1300 (delete-file-recursively dir)))
1301 (find-files "Lib/ensurepip" "\\.whl$"))))
1302 (add-after 'install 'remove-tests
1303 ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
1304 ;; because these files are used by some libraries out there.
1305 (lambda* (#:key outputs #:allow-other-keys)
1306 (let ((out (assoc-ref outputs "out")))
1307 (match (scandir (string-append out "/lib")
1308 (lambda (name)
1309 (string-prefix? "python" name)))
1310 ((pythonX.Y)
1311 (let ((testdir (string-append out "/lib/" pythonX.Y
1312 "/test")))
1313 (with-directory-excursion testdir
1314 (for-each delete-file-recursively
1315 (scandir testdir
1316 (match-lambda
1317 ((or "." "..")
1318 #f)
1319 ("support" #f)
1320 (file (not (string-prefix?
1321 "test_support."
1322 file))))))
1323 (call-with-output-file "__init__.py"
1324 (const #t))))
1325 (let ((libdir (string-append out "/lib/" pythonX.Y)))
1326 (for-each (lambda (directory)
1327 (let ((dir (string-append libdir "/"
1328 directory)))
1329 (when (file-exists? dir)
1330 (delete-file-recursively dir))))
1331 '("email/test" "ctypes/test"
1332 "unittest/test"
1333 "tkinter/test"
1334 "sqlite3/test"
1335 "bsddb/test"
1336 "lib-tk/test"
1337 "json/tests"
1338 "distutils/tests"))))))))
1339 (add-after 'remove-tests 'move-tk-inter
1340 (lambda* (#:key outputs inputs #:allow-other-keys)
1341 ;; When Tkinter support is built move it to a separate output so
1342 ;; that the main output doesn't contain a reference to Tcl/Tk.
1343 (let ((out (assoc-ref outputs "out"))
1344 (tk (assoc-ref outputs "tk")))
1345 (when tk
1346 (match (find-files out "tkinter.*\\.so")
1347 ((tkinter.so)
1348 ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
1349 ;; want it under TK/lib/pythonX.Y/site-packages.
1350 (let* ((len (string-length out))
1351 (target (string-append tk "/"
1352 (string-drop (dirname
1353 (dirname
1354 tkinter.so))
1355 len)
1356 "/site-packages")))
1357 (install-file tkinter.so target)
1358 (delete-file tkinter.so))))
1359 ;; Remove explicit store path references.
1360 (let ((tcl (assoc-ref inputs "tcl"))
1361 (tk (assoc-ref inputs "tk")))
1362 (substitute* (find-files (string-append out "/lib")
1363 "^(_sysconfigdata_.*\\.py|Makefile)$")
1364 (((string-append "-L" tk "/lib"))
1365 "")
1366 (((string-append "-L" tcl "/lib"))
1367 "")))))))
1368 (add-after 'move-tk-inter 'move-idle
1369 (lambda* (#:key outputs #:allow-other-keys)
1370 ;; when idle is built, move it to a separate output to save some
1371 ;; space (5MB)
1372 (let ((out (assoc-ref outputs "out"))
1373 (idle (assoc-ref outputs "idle")))
1374 (when idle
1375 (for-each (lambda (file)
1376 (let ((target (string-append idle
1377 "/bin/"
1378 (basename
1379 file))))
1380 (install-file file
1381 (dirname target))
1382 (delete-file file)))
1383 (find-files (string-append out "/bin")
1384 "^idle"))
1385 (match (find-files out "^idlelib$"
1386 #:directories? #t)
1387 ((idlelib)
1388 (let* ((len (string-length out))
1389 (target (string-append idle "/"
1390 (string-drop
1391 idlelib len)
1392 "/site-packages")))
1393 (mkdir-p (dirname target))
1394 (rename-file idlelib target))))))))
1395 (add-after 'move-idle 'rebuild-bytecode
1396 (lambda* (#:key outputs #:allow-other-keys)
1397 (let ((out (assoc-ref outputs "out")))
1398 ;; Disable hash randomization to ensure the generated .pycs
1399 ;; are reproducible.
1400 (setenv "PYTHONHASHSEED" "0")
1401
1402 (for-each (lambda (output)
1403 ;; XXX: Delete existing pycs generated by the build
1404 ;; system beforehand because the -f argument does
1405 ;; not necessarily overwrite all files, leading to
1406 ;; indeterministic results.
1407 (for-each (lambda (pyc)
1408 (delete-file pyc))
1409 (find-files output "\\.pyc$"))
1410
1411 (apply invoke
1412 `(,#$(if (%current-target-system)
1413 "python3"
1414 #~(string-append
1415 out
1416 "/bin/python3")) "-m"
1417 "compileall"
1418 "-o"
1419 "0"
1420 "-o"
1421 "1"
1422 "-o"
1423 "2"
1424 "-f" ;force rebuild
1425 "--invalidation-mode=unchecked-hash"
1426 ;; Don't build lib2to3, because it's
1427 ;; Python 2 code.
1428 "-x"
1429 "lib2to3/.*"
1430 ,output)))
1431 (map cdr outputs)))))
1432 (add-before 'check 'set-TZDIR
1433 (lambda* (#:key inputs native-inputs #:allow-other-keys)
1434 ;; test_email requires the Olson time zone database.
1435 (setenv "TZDIR"
1436 (string-append (assoc-ref (or native-inputs
1437 inputs) "tzdata")
1438 "/share/zoneinfo"))))
1439 (add-after 'install 'install-sitecustomize.py
1440 #$(customize-site version)))))
1441 (inputs (list bzip2
1442 expat
1443 gdbm
1444 libffi ;for ctypes
1445 sqlite ;for sqlite extension
1446 openssl
1447 readline
1448 zlib
1449 tcl
1450 tk)) ;for tkinter
1451 (native-inputs `(("tzdata" ,tzdata-for-tests)
1452 ("unzip" ,unzip)
1453 ("zip" ,(@ (gnu packages compression) zip))
1454 ("pkg-config" ,pkg-config)
1455 ("sitecustomize.py" ,(local-file (search-auxiliary-file
1456 "python/sitecustomize.py")))
1457 ;; When cross-compiling, a native version of Python itself is needed.
1458 ,@(if (%current-target-system)
1459 `(("python" ,this-package)
1460 ("which" ,which))
1461 '())))
1462 (native-search-paths
1463 (list (guix-pythonpath-search-path version)
1464 ;; Used to locate tzdata by the zoneinfo module introduced in
1465 ;; Python 3.9.
1466 (search-path-specification
1467 (variable "PYTHONTZPATH")
1468 (files (list "share/zoneinfo")))))
1469 (home-page "https://www.python.org")
1470 (synopsis "High-level, dynamically-typed programming language")
1471 (description
1472 "Python is a remarkably powerful dynamic programming language that
1473is used in a wide variety of application domains. Some of its key
1474distinguishing features include: clear, readable syntax; strong
1475introspection capabilities; intuitive object orientation; natural
1476expression of procedural code; full modularity, supporting hierarchical
1477packages; exception-based error handling; and very high level dynamic
1478data types.")
1479 (properties '((cpe-name . "python")
1480 (cpe-vendor . "python")))
1481 (license license:psfl)))
1482
1483;; Next 3.x version.
1484(define-public python-next python-3.12)
1485
1486;; Current 3.x version.
1487(define-public python-3 python-3.11)
1488
1489;; Current major version.
1490(define-public python python-3)
1491
1492;; Minimal variant of Python, mostly used to break the cycle between Tk and
1493;; Python (Tk -> libxcb -> Python.)
1494
1495(define-public python-minimal
1496 (package/inherit python
1497 (name "python-minimal")
1498 (outputs '("out"))
1499
1500 ;; Build fails due to missing ctypes without libffi.
1501 ;; OpenSSL is a mandatory dependency of Python 3.x, for urllib;
1502 ;; zlib is required by 'zipimport', used by pip. Expat is needed
1503 ;; for XML support, which is generally expected to be available.
1504 (inputs (list expat libffi openssl zlib))))
1505
1506(define-public python-debug
1507 (package/inherit python
1508 (name "python-debug")
1509 (outputs '("out" "debug"))
1510 (build-system gnu-build-system)
1511 (arguments
1512 (substitute-keyword-arguments (package-arguments python)
1513 ((#:configure-flags configure-flags)
1514 #~(append #$configure-flags
1515 (list "--with-pydebug")))))
1516 (synopsis "Python with the debug hooks enabled")
1517 (description
1518 "This variant of Python provides an interpreter built with
1519@code{--with-pydebug} to help develop and debug extensions. See
1520@url{https://pythonextensionpatterns.readthedocs.io/en/latest/debugging/debug.html},
1521for more information.")))
1522
1523(define* (wrap-python3 python
1524 #:optional
1525 (name (string-append (package-name python) "-wrapper")))
1526 (package/inherit python
1527 (name name)
1528 (source #f)
1529 (build-system trivial-build-system)
1530 (outputs '("out"))
1531 (inputs `(("bash" ,bash)))
1532 (propagated-inputs `(("python" ,python)))
1533 (arguments
1534 (list #:modules '((guix build utils))
1535 #:builder
1536 #~(begin
1537 (use-modules (guix build utils))
1538 (let ((bin (string-append #$output "/bin"))
1539 (python (string-append
1540 ;; XXX: '%build-inputs' contains the native
1541 ;; Python when cross-compiling.
1542 #$(if (%current-target-system)
1543 (this-package-input "python")
1544 #~(assoc-ref %build-inputs "python"))
1545 "/bin/")))
1546 (mkdir-p bin)
1547 (for-each
1548 (lambda (old new)
1549 (symlink (string-append python old)
1550 (string-append bin "/" new)))
1551 `("python3" ,"pydoc3" ,"pip3")
1552 `("python" ,"pydoc" ,"pip"))
1553 ;; python-config outputs search paths based upon its location,
1554 ;; use a bash wrapper to avoid changing its outputs.
1555 (let ((bash (string-append (assoc-ref %build-inputs "bash")
1556 "/bin/bash"))
1557 (old (string-append python "python3-config"))
1558 (new (string-append bin "/python-config")))
1559 (with-output-to-file new
1560 (lambda ()
1561 (format #t "#!~a~%" bash)
1562 (format #t "exec \"~a\" \"$@\"~%" old)
1563 (chmod new #o755))))))))
1564 (synopsis "Wrapper for the Python 3 commands")
1565 (description
1566 "This package provides wrappers for the commands of Python@tie{}3.x such
1567that they can also be invoked under their usual names---e.g., @command{python}
1568instead of @command{python3} or @command{pip} instead of @command{pip3}.
1569
1570To function properly, this package should not be installed together with the
1571@code{python} package: this package uses the @code{python} package as a
1572propagated input, so installing this package already makes both the versioned
1573and the unversioned commands available.")))
1574
1575(define-public python-wrapper (wrap-python3 python))
1576(define-public python-minimal-wrapper (wrap-python3 python-minimal))
1577
1578;; The Python used in pyproject-build-system.
1579(define-public python-sans-pip
1580 (hidden-package
1581 (package/inherit python
1582 (arguments
1583 (substitute-keyword-arguments (package-arguments python)
1584 ((#:configure-flags flags #~())
1585 #~(append '("--with-ensurepip=no")
1586 (delete "--with-ensurepip=install" #$flags))))))))
1587
1588(define-public python-sans-pip-wrapper
1589 (wrap-python3 python-sans-pip))
1590
1591(define-public pythoncapi-compat
1592 ;; No release nor tags: use the latest commit.
1593 (let ((commit "ab72af8b1a9adfccb3578eea8e9b6d5c6449f409")
1594 (revision "1"))
1595 (package
1596 (name "pythoncapi-compat")
1597 (version (git-version "0.0.0" revision commit))
1598 (source (origin
1599 (method git-fetch)
1600 (uri (git-reference
1601 (url "https://github.com/python/pythoncapi-compat")
1602 (commit commit)))
1603 (file-name (git-file-name name version))
1604 (sha256
1605 (base32
1606 "0dfzfs399ik10125kvs5s8rid93lm50wray8s7b8bv90a61zjxiv"))))
1607 (build-system copy-build-system)
1608 (arguments (list #:install-plan
1609 #~'(("pythoncapi_compat.h" "include/"))))
1610 (home-page "https://github.com/python/pythoncapi-compat")
1611 (synopsis "Python C API compatibility")
1612 (description "The pythoncapi-compat project can be used to write a C or
1613C++ extension supporting a wide range of Python versions with a single code
1614base, via the @file{pythoncapi_compat.h} header file.")
1615 (license license:bsd-0))))
1616
1617(define-public micropython
1618 (package
1619 (name "micropython")
1620 (version "1.26.1")
1621 (source
1622 (origin
1623 (method url-fetch)
1624 (uri (string-append "https://github.com/micropython/micropython/"
1625 "releases/download/v" version
1626 "/micropython-" version ".tar.xz"))
1627 (sha256
1628 (base32 "165c8g60f5zf82gw2d94snyjmcgn999jn4i8ngyc0wk2vwa6bghj"))
1629 (modules '((guix build utils)))
1630 (snippet
1631 '(begin
1632 (delete-file-recursively "ports/cc3200/FreeRTOS")
1633 (with-directory-excursion "lib"
1634 ;; TODO: Unbundle axtls and berkley-db-1.xx
1635 (for-each delete-file-recursively
1636 '("libffi" "lwip" "stm32lib" "nrfx")))))))
1637 (build-system gnu-build-system)
1638 (arguments
1639 (list #:phases
1640 #~(modify-phases %standard-phases
1641 (add-before 'build 'build-mpy-cross
1642 (lambda* (#:key make-flags #:allow-other-keys)
1643 (with-directory-excursion "mpy-cross"
1644 (apply invoke "make" make-flags))))
1645 (add-after 'build-mpy-cross 'prepare-build
1646 (lambda _
1647 (chdir "ports/unix")
1648 ;; see: https://github.com/micropython/micropython/pull/4246
1649 (substitute* "Makefile"
1650 (("-Os") "-Os -ffp-contract=off"))))
1651 (add-before 'install-license-files 'chdir-back
1652 ;; We don't build in the root directory so the file isn't found.
1653 (lambda _
1654 (chdir "../..")))
1655 (delete 'configure)) ; no configure
1656 #:make-flags
1657 #~(list (string-append "PREFIX=" #$output)
1658 "V=1")
1659 #:test-target "test"))
1660 (native-inputs (list pkg-config python-wrapper))
1661 (inputs
1662 (list libffi))
1663 (home-page "https://micropython.org/")
1664 (synopsis "Python implementation for microcontrollers and constrained systems")
1665 (description "MicroPython is a lean and efficient implementation of the
1666Python 3 programming language that includes a small subset of the Python
1667standard library and is optimised to run on microcontrollers and in constrained
1668environments. MicroPython is packed full of advanced features such as an
1669interactive prompt, arbitrary precision integers, closures, list comprehension,
1670generators, exception handling and more. Still it is compact enough to fit and
1671run within just 256k of code space and 16k of RAM. MicroPython aims to be as
1672compatible with normal Python as possible to allow you to transfer code with
1673ease from the desktop to a microcontroller or embedded system.")
1674 (license license:expat)))