projects/guix·blob hurd-team · refs

1678 lines · 83.4 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 arguments
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 native-inputs
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 (target-ppc32?)
772 '(" test_ssl")
773 '())
774 ,@(if (system-hurd?)
775 '(" test_posix" ;multiple errors
776 " test_time"
777 " test_pty"
778 " test_shutil"
779 " test_tempfile" ;chflags: invalid argument:
780 ;; tbv14c9t/dir0/dir0/dir0/test0.txt
781 " test_os" ;stty: 'standard input':
782 ;; Inappropriate ioctl for device
783 " test_openpty" ;No such file or directory
784 " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
785 ;; 32752 != 4
786 " test_compileall" ;multiple errors
787 " test_poll" ;list index out of range
788 " test_subprocess" ;runs over 10min
789 " test_asyncore" ;multiple errors
790 " test_threadsignals"
791 " test_eintr" ;Process return code is -14
792 " test_io" ;multiple errors
793 " test_logging"
794 " test_signal"
795 " test_flags" ;ERROR
796 " test_bidirectional_pty"
797 " test_create_unix_connection"
798 " test_unix_sock_client_ops"
799 " test_open_unix_connection"
800 " test_open_unix_connection_error"
801 " test_read_pty_output"
802 " test_write_pty"
803 " test_concurrent_futures" ;freeze
804 " test_venv" ;freeze
805 " test_multiprocessing_forkserver" ;runs over 10min
806 " test_multiprocessing_spawn" ;runs over 10min
807 " test_glob" ;did not finish in 10h
808 " test_site" ;Invalid argument
809 " test_termios" ;os.openpty() Operation not permitted
810 " test_tty" ;os.openpty() Operation not permitted
811 " test_sqlite3" ;; sqlite3.OperationalError: database is locked
812 " test_tarfile" ;; ELOOP vs ENAMETOOLONG
813 " test_builtin"
814 " test_capi"
815 " test_dbm_ndbm"
816 " test_exceptions"
817 " test_faulthandler"
818 " test_getopt"
819 " test_importlib"
820 " test_json"
821 " test_multiprocessing_fork"
822 " test_multiprocessing_main_handling"
823 " test_pdb "
824 " test_regrtest"
825 " test_ssl" ;; Fails with openssl 3.5
826 " test_sqlite")
827 '())
828 ,@(if (system-hurd64?)
829 '(" test_largefile") ;; hangs
830 '())))
831
832 #:modules
833 '((ice-9 ftw)
834 (ice-9 match)
835 (guix build utils)
836 (guix build gnu-build-system))
837
838 #:phases
839 #~(modify-phases %standard-phases
840 #$@(if (system-hurd?)
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
1063 #$(customize-site version)))))
1064 (inputs (list bzip2
1065 expat
1066 gdbm
1067 libffi ;for ctypes
1068 libxcrypt ;crypto module slated for removal in 3.13
1069 sqlite ;for sqlite extension
1070 openssl
1071 readline
1072 zlib
1073 tcl
1074 tk)) ;for tkinter
1075 (native-inputs `(("tzdata" ,tzdata-for-tests)
1076 ("unzip" ,unzip)
1077 ("zip" ,(@ (gnu packages compression) zip))
1078 ("pkg-config" ,pkg-config)
1079 ("sitecustomize.py" ,(local-file (search-auxiliary-file
1080 "python/sitecustomize.py")))
1081 ;; When cross-compiling, a native version of Python itself is needed.
1082 ,@(if (%current-target-system)
1083 `(("python" ,this-package)
1084 ("which" ,which))
1085 '())))
1086 (native-search-paths
1087 (list (guix-pythonpath-search-path version)
1088 ;; Used to locate tzdata by the zoneinfo module introduced in
1089 ;; Python 3.9.
1090 (search-path-specification
1091 (variable "PYTHONTZPATH")
1092 (files (list "share/zoneinfo")))))))
1093
1094(define-public python-3.12
1095 (package
1096 (name "python-next")
1097 (version "3.12.12")
1098 (source
1099 (origin
1100 (method url-fetch)
1101 (uri (string-append "https://www.python.org/ftp/python/" version
1102 "/Python-" version ".tar.xz"))
1103 (sha256
1104 (base32 "1i2nqvnm2b7aakj2rf8qdfsk0nh55ly55gcbl6dw8a5h2hsa31gv"))
1105 (patches (search-patches "python-3-deterministic-build-info.patch"
1106 "python-3.12-fix-tests.patch"
1107 "python-3-hurd-configure.patch"))
1108 (modules '((guix build utils)))
1109 (snippet '(begin
1110 ;; Delete the bundled copy of libexpat.
1111 (delete-file-recursively "Modules/expat")
1112 (substitute* "Modules/Setup"
1113 ;; Link Expat instead of embedding the bundled one.
1114 (("^#pyexpat.*")
1115 "pyexpat pyexpat.c -lexpat\n"))
1116 ;; Delete windows binaries
1117 (for-each delete-file
1118 (find-files "Lib/distutils/command" "\\.exe$"))))))
1119 (outputs '("out" "tk" ;tkinter; adds 50 MiB to the closure
1120 "idle")) ;programming environment; weighs 5MB
1121 (build-system gnu-build-system)
1122 (arguments
1123 (list
1124 #:test-target "test"
1125 #:configure-flags
1126 #~(list "--enable-shared" ;allow embedding
1127 "--with-system-expat" ;for XML support
1128 "--with-system-ffi" ;build ctypes
1129 "--with-ensurepip=install" ;install pip and setuptools
1130 "--with-computed-gotos" ;main interpreter loop optimization
1131 "--enable-unicode=ucs4"
1132 "--without-static-libpython"
1133 "--enable-loadable-sqlite-extensions"
1134
1135 ;; FIXME: These flags makes Python significantly faster,
1136 ;; but leads to non-reproducible binaries.
1137 ;; "--with-lto" ;increase size by 20MB, but 15% speedup
1138 ;; "--enable-optimizations"
1139
1140 ;; Prevent the installed _sysconfigdata.py from retaining
1141 ;; a reference to coreutils.
1142 "INSTALL=install -c"
1143 "MKDIR_P=mkdir -p"
1144
1145 ;; Disable runtime check failing if cross-compiling, see:
1146 ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
1147 #$@(if (%current-target-system)
1148 #~("ac_cv_buggy_getaddrinfo=no"
1149 "ac_cv_file__dev_ptmx=no"
1150 "ac_cv_file__dev_ptc=no")
1151 #~())
1152 ;; -fno-semantic-interposition reinstates some
1153 ;; optimizations by gcc leading to around 15% speedup.
1154 ;; This is the default starting from python 3.10.
1155 "CFLAGS=-fno-semantic-interposition"
1156 (string-append "LDFLAGS=-Wl,-rpath="
1157 (assoc-ref %outputs "out")
1158 "/lib"
1159 " -fno-semantic-interposition"))
1160 ;; With no -j argument tests use all available cpus, so provide one.
1161 #:make-flags
1162 #~(list (string-append (format #f "TESTOPTS=-j~d"
1163 (parallel-job-count))
1164 ;; those tests fail on low-memory systems
1165 " --exclude"
1166 " test_mmap"
1167 " test_socket"
1168 " test_threading"
1169 " test_asyncio"
1170 " test_shutdown"
1171 #$@(if (system-hurd?)
1172 #~(" test_posix" ;multiple errors
1173 " test_time"
1174 " test_pty"
1175 " test_shutil"
1176 " test_tempfile" ;chflags: invalid argument:
1177 ;; tbv14c9t/dir0/dir0/dir0/test0.txt
1178 " test_os" ;stty: 'standard input':
1179 ;; Inappropriate ioctl for device
1180 " test_openpty" ;No such file or directory
1181 " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
1182 ;; 32752 != 4
1183 " test_compileall" ;multiple errors
1184 " test_poll" ;list index out of range
1185 " test_subprocess" ;runs over 10min
1186 " test_asyncore" ;multiple errors
1187 " test_threadsignals"
1188 " test_eintr" ;Process return code is -14
1189 " test_io" ;multiple errors
1190 " test_logging"
1191 " test_signal"
1192 " test_flags" ;ERROR
1193 " test_bidirectional_pty"
1194 " test_create_unix_connection"
1195 " test_unix_sock_client_ops"
1196 " test_open_unix_connection"
1197 " test_open_unix_connection_error"
1198 " test_read_pty_output"
1199 " test_write_pty"
1200 " test_concurrent_futures" ;freeze
1201 " test_venv" ;freeze
1202 " test_multiprocessing_forkserver" ;runs over 10min
1203 " test_multiprocessing_spawn" ;runs over 10min
1204 " test_builtin"
1205 " test_capi"
1206 " test_dbm_ndbm"
1207 " test_exceptions"
1208 " test_faulthandler"
1209 " test_getopt"
1210 " test_importlib"
1211 " test_json"
1212 " test_multiprocessing_fork"
1213 " test_multiprocessing_main_handling"
1214 " test_pdb "
1215 " test_regrtest"
1216 " test_sqlite")
1217 #~())))
1218
1219 #:modules '((ice-9 ftw)
1220 (ice-9 match)
1221 (guix build utils)
1222 (guix build gnu-build-system))
1223
1224 #:phases
1225 #~(modify-phases %standard-phases
1226 #$@(if (system-hurd?)
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
1444 #$(customize-site version)))))
1445 (inputs (list bzip2
1446 expat
1447 gdbm
1448 libffi ;for ctypes
1449 sqlite ;for sqlite extension
1450 openssl
1451 readline
1452 zlib
1453 tcl
1454 tk)) ;for tkinter
1455 (native-inputs `(("tzdata" ,tzdata-for-tests)
1456 ("unzip" ,unzip)
1457 ("zip" ,(@ (gnu packages compression) zip))
1458 ("pkg-config" ,pkg-config)
1459 ("sitecustomize.py" ,(local-file (search-auxiliary-file
1460 "python/sitecustomize.py")))
1461 ;; When cross-compiling, a native version of Python itself is needed.
1462 ,@(if (%current-target-system)
1463 `(("python" ,this-package)
1464 ("which" ,which))
1465 '())))
1466 (native-search-paths
1467 (list (guix-pythonpath-search-path version)
1468 ;; Used to locate tzdata by the zoneinfo module introduced in
1469 ;; Python 3.9.
1470 (search-path-specification
1471 (variable "PYTHONTZPATH")
1472 (files (list "share/zoneinfo")))))
1473 (home-page "https://www.python.org")
1474 (synopsis "High-level, dynamically-typed programming language")
1475 (description
1476 "Python is a remarkably powerful dynamic programming language that
1477is used in a wide variety of application domains. Some of its key
1478distinguishing features include: clear, readable syntax; strong
1479introspection capabilities; intuitive object orientation; natural
1480expression of procedural code; full modularity, supporting hierarchical
1481packages; exception-based error handling; and very high level dynamic
1482data types.")
1483 (properties '((cpe-name . "python")
1484 (cpe-vendor . "python")))
1485 (license license:psfl)))
1486
1487;; Next 3.x version.
1488(define-public python-next python-3.12)
1489
1490;; Current 3.x version.
1491(define-public python-3 python-3.11)
1492
1493;; Current major version.
1494(define-public python python-3)
1495
1496;; Minimal variant of Python, mostly used to break the cycle between Tk and
1497;; Python (Tk -> libxcb -> Python.)
1498
1499(define-public python-minimal
1500 (package/inherit python
1501 (name "python-minimal")
1502 (outputs '("out"))
1503
1504 ;; Build fails due to missing ctypes without libffi.
1505 ;; OpenSSL is a mandatory dependency of Python 3.x, for urllib;
1506 ;; zlib is required by 'zipimport', used by pip. Expat is needed
1507 ;; for XML support, which is generally expected to be available.
1508 (inputs (list expat libffi openssl zlib))))
1509
1510(define-public python-debug
1511 (package/inherit python
1512 (name "python-debug")
1513 (outputs '("out" "debug"))
1514 (build-system gnu-build-system)
1515 (arguments
1516 (substitute-keyword-arguments arguments
1517 ((#:configure-flags configure-flags)
1518 #~(append #$configure-flags
1519 (list "--with-pydebug")))))
1520 (synopsis "Python with the debug hooks enabled")
1521 (description
1522 "This variant of Python provides an interpreter built with
1523@code{--with-pydebug} to help develop and debug extensions. See
1524@url{https://pythonextensionpatterns.readthedocs.io/en/latest/debugging/debug.html},
1525for more information.")))
1526
1527(define* (wrap-python3 python
1528 #:optional
1529 (name (string-append (package-name python) "-wrapper")))
1530 (package/inherit python
1531 (name name)
1532 (source #f)
1533 (build-system trivial-build-system)
1534 (outputs '("out"))
1535 (inputs `(("bash" ,bash)))
1536 (propagated-inputs `(("python" ,python)))
1537 (arguments
1538 (list #:modules '((guix build utils))
1539 #:builder
1540 #~(begin
1541 (use-modules (guix build utils))
1542 (let ((bin (string-append #$output "/bin"))
1543 (python (string-append
1544 ;; XXX: '%build-inputs' contains the native
1545 ;; Python when cross-compiling.
1546 #$(if (%current-target-system)
1547 (this-package-input "python")
1548 #~(assoc-ref %build-inputs "python"))
1549 "/bin/")))
1550 (mkdir-p bin)
1551 (for-each
1552 (lambda (old new)
1553 (symlink (string-append python old)
1554 (string-append bin "/" new)))
1555 `("python3" ,"pydoc3" ,"pip3")
1556 `("python" ,"pydoc" ,"pip"))
1557 ;; python-config outputs search paths based upon its location,
1558 ;; use a bash wrapper to avoid changing its outputs.
1559 (let ((bash (string-append (assoc-ref %build-inputs "bash")
1560 "/bin/bash"))
1561 (old (string-append python "python3-config"))
1562 (new (string-append bin "/python-config")))
1563 (with-output-to-file new
1564 (lambda ()
1565 (format #t "#!~a~%" bash)
1566 (format #t "exec \"~a\" \"$@\"~%" old)
1567 (chmod new #o755))))))))
1568 (synopsis "Wrapper for the Python 3 commands")
1569 (description
1570 "This package provides wrappers for the commands of Python@tie{}3.x such
1571that they can also be invoked under their usual names---e.g., @command{python}
1572instead of @command{python3} or @command{pip} instead of @command{pip3}.
1573
1574To function properly, this package should not be installed together with the
1575@code{python} package: this package uses the @code{python} package as a
1576propagated input, so installing this package already makes both the versioned
1577and the unversioned commands available.")))
1578
1579(define-public python-wrapper (wrap-python3 python))
1580(define-public python-minimal-wrapper (wrap-python3 python-minimal))
1581
1582;; The Python used in pyproject-build-system.
1583(define-public python-sans-pip
1584 (hidden-package
1585 (package/inherit python
1586 (arguments
1587 (substitute-keyword-arguments arguments
1588 ((#:configure-flags flags #~())
1589 #~(append '("--with-ensurepip=no")
1590 (delete "--with-ensurepip=install" #$flags))))))))
1591
1592(define-public python-sans-pip-wrapper
1593 (wrap-python3 python-sans-pip))
1594
1595(define-public pythoncapi-compat
1596 ;; No release nor tags: use the latest commit.
1597 (let ((commit "ab72af8b1a9adfccb3578eea8e9b6d5c6449f409")
1598 (revision "1"))
1599 (package
1600 (name "pythoncapi-compat")
1601 (version (git-version "0.0.0" revision commit))
1602 (source (origin
1603 (method git-fetch)
1604 (uri (git-reference
1605 (url "https://github.com/python/pythoncapi-compat")
1606 (commit commit)))
1607 (file-name (git-file-name name version))
1608 (sha256
1609 (base32
1610 "0dfzfs399ik10125kvs5s8rid93lm50wray8s7b8bv90a61zjxiv"))))
1611 (build-system copy-build-system)
1612 (arguments (list #:install-plan
1613 #~'(("pythoncapi_compat.h" "include/"))))
1614 (home-page "https://github.com/python/pythoncapi-compat")
1615 (synopsis "Python C API compatibility")
1616 (description "The pythoncapi-compat project can be used to write a C or
1617C++ extension supporting a wide range of Python versions with a single code
1618base, via the @file{pythoncapi_compat.h} header file.")
1619 (license license:bsd-0))))
1620
1621(define-public micropython
1622 (package
1623 (name "micropython")
1624 (version "1.26.1")
1625 (source
1626 (origin
1627 (method url-fetch)
1628 (uri (string-append "https://github.com/micropython/micropython/"
1629 "releases/download/v" version
1630 "/micropython-" version ".tar.xz"))
1631 (sha256
1632 (base32 "165c8g60f5zf82gw2d94snyjmcgn999jn4i8ngyc0wk2vwa6bghj"))
1633 (modules '((guix build utils)))
1634 (snippet
1635 '(begin
1636 (delete-file-recursively "ports/cc3200/FreeRTOS")
1637 (with-directory-excursion "lib"
1638 ;; TODO: Unbundle axtls and berkley-db-1.xx
1639 (for-each delete-file-recursively
1640 '("libffi" "lwip" "stm32lib" "nrfx")))))))
1641 (build-system gnu-build-system)
1642 (arguments
1643 (list #:phases
1644 #~(modify-phases %standard-phases
1645 (add-before 'build 'build-mpy-cross
1646 (lambda* (#:key make-flags #:allow-other-keys)
1647 (with-directory-excursion "mpy-cross"
1648 (apply invoke "make" make-flags))))
1649 (add-after 'build-mpy-cross 'prepare-build
1650 (lambda _
1651 (chdir "ports/unix")
1652 ;; see: https://github.com/micropython/micropython/pull/4246
1653 (substitute* "Makefile"
1654 (("-Os") "-Os -ffp-contract=off"))))
1655 (add-before 'install-license-files 'chdir-back
1656 ;; We don't build in the root directory so the file isn't found.
1657 (lambda _
1658 (chdir "../..")))
1659 (delete 'configure)) ; no configure
1660 #:make-flags
1661 #~(list (string-append "PREFIX=" #$output)
1662 "V=1")
1663 #:test-target "test"))
1664 (native-inputs (list pkg-config python-wrapper))
1665 (inputs
1666 (list libffi))
1667 (home-page "https://micropython.org/")
1668 (synopsis "Python implementation for microcontrollers and constrained systems")
1669 (description "MicroPython is a lean and efficient implementation of the
1670Python 3 programming language that includes a small subset of the Python
1671standard library and is optimised to run on microcontrollers and in constrained
1672environments. MicroPython is packed full of advanced features such as an
1673interactive prompt, arbitrary precision integers, closures, list comprehension,
1674generators, exception handling and more. Still it is compact enough to fit and
1675run within just 256k of code space and 16k of RAM. MicroPython aims to be as
1676compatible with normal Python as possible to allow you to transfer code with
1677ease from the desktop to a microcontroller or embedded system.")
1678 (license license:expat)))