projects/guix·blob graal · refs

1689 lines · 83.7 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
825 #:modules
826 '((ice-9 ftw)
827 (ice-9 match)
828 (guix build utils)
829 (guix build gnu-build-system))
830
831 #:phases
832 #~(modify-phases %standard-phases
833 #$@(if (system-hurd?)
834 `((add-after 'unpack
835 'disable-multi-processing
836 (lambda _
837 (substitute* "Makefile.pre.in"
838 (("-j0")
839 "-j1")))))
840 '())
841 (add-before 'configure 'patch-lib-shells
842 (lambda _
843 ;; This variable is used in setup.py to enable cross compilation
844 ;; specific switches. As it is not set properly by configure
845 ;; script, set it manually.
846 #$@(if (%current-target-system)
847 '((setenv "_PYTHON_HOST_PLATFORM" ""))
848 '())
849 ;; Filter for existing files, since some may not exist in all
850 ;; versions of python that are built with this recipe.
851 (substitute* (filter file-exists?
852 '("Lib/subprocess.py"
853 "Lib/popen2.py"
854 "Lib/distutils/tests/test_spawn.py"
855 "Lib/test/support/__init__.py"
856 "Lib/test/test_subprocess.py"))
857 (("/bin/sh")
858 (which "sh")))))
859 (add-before 'configure 'do-not-record-configure-flags
860 (lambda* (#:key configure-flags #:allow-other-keys)
861 ;; Remove configure flags from the installed '_sysconfigdata.py'
862 ;; and 'Makefile' so we don't end up keeping references to the
863 ;; build tools.
864 ;;
865 ;; Preserve at least '--with-system-ffi' since otherwise the
866 ;; thing tries to build libffi, fails, and we end up with a
867 ;; Python that lacks ctypes.
868 (substitute* "configure"
869 (("^CONFIG_ARGS=.*$")
870 (format #f "CONFIG_ARGS='~a'\n"
871 (if (member "--with-system-ffi"
872 configure-flags)
873 "--with-system-ffi" ""))))))
874 (add-before 'check 'pre-check
875 (lambda _
876 ;; 'Lib/test/test_site.py' needs a valid $HOME
877 (setenv "HOME"
878 (getcwd))))
879 (add-after 'unpack 'set-source-file-times-to-1980
880 ;; XXX One of the tests uses a ZIP library to pack up some of the
881 ;; source tree, and fails with "ZIP does not support timestamps
882 ;; before 1980". Work around this by setting the file times in the
883 ;; source tree to sometime in early 1980.
884 (lambda _
885 (let ((circa-1980 (* 10 366 24 60 60)))
886 (ftw "."
887 (lambda (file stat flag)
888 (utime file circa-1980 circa-1980) #t)))))
889 (add-after 'unpack 'remove-windows-binaries
890 (lambda _
891 ;; Delete .exe from embedded .whl (zip) files
892 (for-each (lambda (whl)
893 (let ((dir "whl-content")
894 (circa-1980 (* 10 366 24 60 60)))
895 (mkdir-p dir)
896 (with-directory-excursion dir
897 (let ((whl (string-append "../" whl)))
898 (invoke "unzip" whl)
899 (for-each delete-file
900 (find-files "." "\\.exe$"))
901 (delete-file whl)
902 ;; Reset timestamps to prevent them from ending
903 ;; up in the Zip archive.
904 (ftw "."
905 (lambda (file stat flag)
906 (utime file circa-1980
907 circa-1980) #t))
908 (apply invoke "zip" "-X" whl
909 (find-files "."
910 #:directories? #t))))
911 (delete-file-recursively dir)))
912 (find-files "Lib/ensurepip" "\\.whl$"))))
913 (add-after 'install 'remove-tests
914 ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
915 ;; because these files are used by some libraries out there.
916 (lambda* (#:key outputs #:allow-other-keys)
917 (let ((out (assoc-ref outputs "out")))
918 (match (scandir (string-append out "/lib")
919 (lambda (name)
920 (string-prefix? "python" name)))
921 ((pythonX.Y)
922 (let ((testdir (string-append out "/lib/" pythonX.Y
923 "/test")))
924 (with-directory-excursion testdir
925 (for-each delete-file-recursively
926 (scandir testdir
927 (match-lambda
928 ((or "." "..")
929 #f)
930 ("support" #f)
931 (file (not (string-prefix?
932 "test_support."
933 file))))))
934 (call-with-output-file "__init__.py"
935 (const #t))))
936 (let ((libdir (string-append out "/lib/" pythonX.Y)))
937 (for-each (lambda (directory)
938 (let ((dir (string-append libdir "/"
939 directory)))
940 (when (file-exists? dir)
941 (delete-file-recursively dir))))
942 '("email/test" "ctypes/test"
943 "unittest/test"
944 "tkinter/test"
945 "sqlite3/test"
946 "bsddb/test"
947 "lib-tk/test"
948 "json/tests"
949 "distutils/tests"))))))))
950 (add-after 'remove-tests 'move-tk-inter
951 (lambda* (#:key outputs inputs #:allow-other-keys)
952 ;; When Tkinter support is built move it to a separate output so
953 ;; that the main output doesn't contain a reference to Tcl/Tk.
954 (let ((out (assoc-ref outputs "out"))
955 (tk (assoc-ref outputs "tk")))
956 (when tk
957 (match (find-files out "tkinter.*\\.so")
958 ((tkinter.so)
959 ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
960 ;; want it under TK/lib/pythonX.Y/site-packages.
961 (let* ((len (string-length out))
962 (target (string-append tk "/"
963 (string-drop (dirname
964 (dirname
965 tkinter.so))
966 len)
967 "/site-packages")))
968 (install-file tkinter.so target)
969 (delete-file tkinter.so))))
970 ;; Remove explicit store path references.
971 (let ((tcl (assoc-ref inputs "tcl"))
972 (tk (assoc-ref inputs "tk")))
973 (substitute* (find-files (string-append out "/lib")
974 "^(_sysconfigdata_.*\\.py|Makefile)$")
975 (((string-append "-L" tk "/lib"))
976 "")
977 (((string-append "-L" tcl "/lib"))
978 "")))))))
979 (add-after 'move-tk-inter 'move-idle
980 (lambda* (#:key outputs #:allow-other-keys)
981 ;; when idle is built, move it to a separate output to save some
982 ;; space (5MB)
983 (let ((out (assoc-ref outputs "out"))
984 (idle (assoc-ref outputs "idle")))
985 (when idle
986 (for-each (lambda (file)
987 (let ((target (string-append idle
988 "/bin/"
989 (basename
990 file))))
991 (install-file file
992 (dirname target))
993 (delete-file file)))
994 (find-files (string-append out "/bin")
995 "^idle"))
996 (match (find-files out "^idlelib$"
997 #:directories? #t)
998 ((idlelib)
999 (let* ((len (string-length out))
1000 (target (string-append idle "/"
1001 (string-drop
1002 idlelib len)
1003 "/site-packages")))
1004 (mkdir-p (dirname target))
1005 (rename-file idlelib target))))))))
1006 (add-after 'move-idle 'rebuild-bytecode
1007 (lambda* (#:key outputs #:allow-other-keys)
1008 ;; Disable hash randomization to ensure the generated .pycs
1009 ;; are reproducible.
1010 (setenv "PYTHONHASHSEED" "0")
1011
1012 (for-each (lambda (output)
1013 ;; XXX: Delete existing pycs generated by the build
1014 ;; system beforehand because the -f argument does
1015 ;; not necessarily overwrite all files, leading to
1016 ;; indeterministic results.
1017 (for-each (lambda (pyc)
1018 (delete-file pyc))
1019 (find-files output "\\.pyc$"))
1020
1021 (apply invoke
1022 #$(if (%current-target-system)
1023 "python3"
1024 #~(string-append #$output "/bin/python3"))
1025 `("-m" "compileall"
1026 "-o" "0"
1027 "-o" "1"
1028 "-o" "2"
1029 "-f" ;force rebuild
1030 "--invalidation-mode=unchecked-hash"
1031 ;; Don't build lib2to3, because it's Python
1032 ;; 2 code.
1033 "-x" "lib2to3/.*"
1034 ,output)))
1035 (map cdr outputs))))
1036 (add-before 'check 'set-TZDIR
1037 (lambda* (#:key inputs native-inputs #:allow-other-keys)
1038 ;; test_email requires the Olson time zone database.
1039 (setenv "TZDIR"
1040 (string-append (assoc-ref (or native-inputs
1041 inputs) "tzdata")
1042 "/share/zoneinfo"))))
1043 (add-after 'install 'add-libxcrypt-reference-pkgconfig
1044 (lambda* (#:key inputs #:allow-other-keys)
1045 (let ((libxcrypt
1046 (false-if-exception
1047 (dirname
1048 (search-input-file inputs "lib/libcrypt.so.1")))))
1049 (when libxcrypt
1050 (substitute*
1051 (find-files (string-append #$output "/lib/pkgconfig")
1052 ".*\\.pc")
1053 (("Libs:")
1054 (string-append "Libs: " "-L" libxcrypt " -lcrypt")))))))
1055 (add-after 'install 'install-sitecustomize.py
1056 #$(customize-site version)))))
1057 (inputs (list bzip2
1058 expat
1059 gdbm
1060 libffi ;for ctypes
1061 libxcrypt ;crypto module slated for removal in 3.13
1062 sqlite ;for sqlite extension
1063 openssl
1064 readline
1065 zlib
1066 tcl
1067 tk)) ;for tkinter
1068 (native-inputs `(("tzdata" ,tzdata-for-tests)
1069 ("unzip" ,unzip)
1070 ("zip" ,(@ (gnu packages compression) zip))
1071 ("pkg-config" ,pkg-config)
1072 ("sitecustomize.py" ,(local-file (search-auxiliary-file
1073 "python/sitecustomize.py")))
1074 ;; When cross-compiling, a native version of Python itself is needed.
1075 ,@(if (%current-target-system)
1076 `(("python" ,this-package)
1077 ("which" ,which))
1078 '())))
1079 (native-search-paths
1080 (list (guix-pythonpath-search-path version)
1081 ;; Used to locate tzdata by the zoneinfo module introduced in
1082 ;; Python 3.9.
1083 (search-path-specification
1084 (variable "PYTHONTZPATH")
1085 (files (list "share/zoneinfo")))))))
1086
1087(define-public python-3.12
1088 (package
1089 (name "python-next")
1090 (version "3.12.12")
1091 (source
1092 (origin
1093 (method url-fetch)
1094 (uri (string-append "https://www.python.org/ftp/python/" version
1095 "/Python-" version ".tar.xz"))
1096 (sha256
1097 (base32 "1i2nqvnm2b7aakj2rf8qdfsk0nh55ly55gcbl6dw8a5h2hsa31gv"))
1098 (patches (search-patches "python-3-deterministic-build-info.patch"
1099 "python-3.12-fix-tests.patch"
1100 "python-3-hurd-configure.patch"))
1101 (modules '((guix build utils)))
1102 (snippet '(begin
1103 ;; Delete the bundled copy of libexpat.
1104 (delete-file-recursively "Modules/expat")
1105 (substitute* "Modules/Setup"
1106 ;; Link Expat instead of embedding the bundled one.
1107 (("^#pyexpat.*")
1108 "pyexpat pyexpat.c -lexpat\n"))
1109 ;; Delete windows binaries
1110 (for-each delete-file
1111 (find-files "Lib/distutils/command" "\\.exe$"))))))
1112 (outputs '("out" "tk" ;tkinter; adds 50 MiB to the closure
1113 "idle")) ;programming environment; weighs 5MB
1114 (build-system gnu-build-system)
1115 (arguments
1116 (list
1117 #:test-target "test"
1118 #:configure-flags
1119 #~(list "--enable-shared" ;allow embedding
1120 "--with-system-expat" ;for XML support
1121 "--with-system-ffi" ;build ctypes
1122 "--with-ensurepip=install" ;install pip and setuptools
1123 "--with-computed-gotos" ;main interpreter loop optimization
1124 "--enable-unicode=ucs4"
1125 "--without-static-libpython"
1126 "--enable-loadable-sqlite-extensions"
1127
1128 ;; FIXME: These flags makes Python significantly faster,
1129 ;; but leads to non-reproducible binaries.
1130 ;; "--with-lto" ;increase size by 20MB, but 15% speedup
1131 ;; "--enable-optimizations"
1132
1133 ;; Prevent the installed _sysconfigdata.py from retaining
1134 ;; a reference to coreutils.
1135 "INSTALL=install -c"
1136 "MKDIR_P=mkdir -p"
1137
1138 ;; Disable runtime check failing if cross-compiling, see:
1139 ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
1140 #$@(if (%current-target-system)
1141 #~("ac_cv_buggy_getaddrinfo=no"
1142 "ac_cv_file__dev_ptmx=no"
1143 "ac_cv_file__dev_ptc=no")
1144 #~())
1145 ;; -fno-semantic-interposition reinstates some
1146 ;; optimizations by gcc leading to around 15% speedup.
1147 ;; This is the default starting from python 3.10.
1148 "CFLAGS=-fno-semantic-interposition"
1149 (string-append "LDFLAGS=-Wl,-rpath="
1150 (assoc-ref %outputs "out")
1151 "/lib"
1152 " -fno-semantic-interposition"))
1153 ;; With no -j argument tests use all available cpus, so provide one.
1154 #:make-flags
1155 #~(list (string-append (format #f "TESTOPTS=-j~d"
1156 (parallel-job-count))
1157 ;; those tests fail on low-memory systems
1158 " --exclude"
1159 " test_mmap"
1160 " test_socket"
1161 " test_threading"
1162 " test_asyncio"
1163 " test_shutdown"
1164 #$@(if (system-hurd?)
1165 #~(" test_posix" ;multiple errors
1166 " test_time"
1167 " test_pty"
1168 " test_shutil"
1169 " test_tempfile" ;chflags: invalid argument:
1170 ;; tbv14c9t/dir0/dir0/dir0/test0.txt
1171 " test_os" ;stty: 'standard input':
1172 ;; Inappropriate ioctl for device
1173 " test_openpty" ;No such file or directory
1174 " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
1175 ;; 32752 != 4
1176 " test_compileall" ;multiple errors
1177 " test_poll" ;list index out of range
1178 " test_subprocess" ;runs over 10min
1179 " test_asyncore" ;multiple errors
1180 " test_threadsignals"
1181 " test_eintr" ;Process return code is -14
1182 " test_io" ;multiple errors
1183 " test_logging"
1184 " test_signal"
1185 " test_flags" ;ERROR
1186 " test_bidirectional_pty"
1187 " test_create_unix_connection"
1188 " test_unix_sock_client_ops"
1189 " test_open_unix_connection"
1190 " test_open_unix_connection_error"
1191 " test_read_pty_output"
1192 " test_write_pty"
1193 " test_concurrent_futures" ;freeze
1194 " test_venv" ;freeze
1195 " test_multiprocessing_forkserver" ;runs over 10min
1196 " test_multiprocessing_spawn" ;runs over 10min
1197 " test_builtin"
1198 " test_capi"
1199 " test_dbm_ndbm"
1200 " test_exceptions"
1201 " test_faulthandler"
1202 " test_getopt"
1203 " test_importlib"
1204 " test_json"
1205 " test_multiprocessing_fork"
1206 " test_multiprocessing_main_handling"
1207 " test_pdb "
1208 " test_regrtest"
1209 " test_sqlite")
1210 #~())))
1211
1212 #:modules '((ice-9 ftw)
1213 (ice-9 match)
1214 (guix build utils)
1215 (guix build gnu-build-system))
1216
1217 #:phases
1218 #~(modify-phases %standard-phases
1219 #$@(if (system-hurd?)
1220 #~((add-after 'unpack
1221 'disable-multi-processing
1222 (lambda _
1223 (substitute* "Makefile.pre.in"
1224 (("-j0")
1225 "-j1")))))
1226 #~())
1227 (add-before 'configure 'patch-lib-shells
1228 (lambda _
1229 ;; This variable is used in setup.py to enable cross compilation
1230 ;; specific switches. As it is not set properly by configure
1231 ;; script, set it manually.
1232 #$@(if (%current-target-system)
1233 #~((setenv "_PYTHON_HOST_PLATFORM" ""))
1234 #~())
1235 ;; Filter for existing files, since some may not exist in all
1236 ;; versions of python that are built with this recipe.
1237 (substitute* (filter file-exists?
1238 '("Lib/subprocess.py"
1239 "Lib/popen2.py"
1240 "Lib/distutils/tests/test_spawn.py"
1241 "Lib/test/support/__init__.py"
1242 "Lib/test/test_subprocess.py"))
1243 (("/bin/sh")
1244 (which "sh")))))
1245 (add-before 'configure 'do-not-record-configure-flags
1246 (lambda* (#:key configure-flags #:allow-other-keys)
1247 ;; Remove configure flags from the installed '_sysconfigdata.py'
1248 ;; and 'Makefile' so we don't end up keeping references to the
1249 ;; build tools.
1250 ;;
1251 ;; Preserve at least '--with-system-ffi' since otherwise the
1252 ;; thing tries to build libffi, fails, and we end up with a
1253 ;; Python that lacks ctypes.
1254 (substitute* "configure"
1255 (("^CONFIG_ARGS=.*$")
1256 (format #f "CONFIG_ARGS='~a'\n"
1257 (if (member "--with-system-ffi"
1258 configure-flags)
1259 "--with-system-ffi" ""))))))
1260 (add-before 'check 'pre-check
1261 (lambda _
1262 ;; 'Lib/test/test_site.py' needs a valid $HOME
1263 (setenv "HOME"
1264 (getcwd))))
1265 (add-after 'unpack 'set-source-file-times-to-1980
1266 ;; XXX One of the tests uses a ZIP library to pack up some of the
1267 ;; source tree, and fails with "ZIP does not support timestamps
1268 ;; before 1980". Work around this by setting the file times in the
1269 ;; source tree to sometime in early 1980.
1270 (lambda _
1271 (let ((circa-1980 (* 10 366 24 60 60)))
1272 (ftw "."
1273 (lambda (file stat flag)
1274 (utime file circa-1980 circa-1980) #t)))))
1275 (add-after 'unpack 'remove-windows-binaries
1276 (lambda _
1277 ;; Delete .exe from embedded .whl (zip) files
1278 (for-each (lambda (whl)
1279 (let ((dir "whl-content")
1280 (circa-1980 (* 10 366 24 60 60)))
1281 (mkdir-p dir)
1282 (with-directory-excursion dir
1283 (let ((whl (string-append "../" whl)))
1284 (invoke "unzip" whl)
1285 (for-each delete-file
1286 (find-files "." "\\.exe$"))
1287 (delete-file whl)
1288 ;; Reset timestamps to prevent them from ending
1289 ;; up in the Zip archive.
1290 (ftw "."
1291 (lambda (file stat flag)
1292 (utime file circa-1980
1293 circa-1980) #t))
1294 (apply invoke "zip" "-X" whl
1295 (find-files "."
1296 #:directories? #t))))
1297 (delete-file-recursively dir)))
1298 (find-files "Lib/ensurepip" "\\.whl$"))))
1299 (add-after 'install 'remove-tests
1300 ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
1301 ;; because these files are used by some libraries out there.
1302 (lambda* (#:key outputs #:allow-other-keys)
1303 (let ((out (assoc-ref outputs "out")))
1304 (match (scandir (string-append out "/lib")
1305 (lambda (name)
1306 (string-prefix? "python" name)))
1307 ((pythonX.Y)
1308 (let ((testdir (string-append out "/lib/" pythonX.Y
1309 "/test")))
1310 (with-directory-excursion testdir
1311 (for-each delete-file-recursively
1312 (scandir testdir
1313 (match-lambda
1314 ((or "." "..")
1315 #f)
1316 ("support" #f)
1317 (file (not (string-prefix?
1318 "test_support."
1319 file))))))
1320 (call-with-output-file "__init__.py"
1321 (const #t))))
1322 (let ((libdir (string-append out "/lib/" pythonX.Y)))
1323 (for-each (lambda (directory)
1324 (let ((dir (string-append libdir "/"
1325 directory)))
1326 (when (file-exists? dir)
1327 (delete-file-recursively dir))))
1328 '("email/test" "ctypes/test"
1329 "unittest/test"
1330 "tkinter/test"
1331 "sqlite3/test"
1332 "bsddb/test"
1333 "lib-tk/test"
1334 "json/tests"
1335 "distutils/tests"))))))))
1336 (add-after 'remove-tests 'move-tk-inter
1337 (lambda* (#:key outputs inputs #:allow-other-keys)
1338 ;; When Tkinter support is built move it to a separate output so
1339 ;; that the main output doesn't contain a reference to Tcl/Tk.
1340 (let ((out (assoc-ref outputs "out"))
1341 (tk (assoc-ref outputs "tk")))
1342 (when tk
1343 (match (find-files out "tkinter.*\\.so")
1344 ((tkinter.so)
1345 ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
1346 ;; want it under TK/lib/pythonX.Y/site-packages.
1347 (let* ((len (string-length out))
1348 (target (string-append tk "/"
1349 (string-drop (dirname
1350 (dirname
1351 tkinter.so))
1352 len)
1353 "/site-packages")))
1354 (install-file tkinter.so target)
1355 (delete-file tkinter.so))))
1356 ;; Remove explicit store path references.
1357 (let ((tcl (assoc-ref inputs "tcl"))
1358 (tk (assoc-ref inputs "tk")))
1359 (substitute* (find-files (string-append out "/lib")
1360 "^(_sysconfigdata_.*\\.py|Makefile)$")
1361 (((string-append "-L" tk "/lib"))
1362 "")
1363 (((string-append "-L" tcl "/lib"))
1364 "")))))))
1365 (add-after 'move-tk-inter 'move-idle
1366 (lambda* (#:key outputs #:allow-other-keys)
1367 ;; when idle is built, move it to a separate output to save some
1368 ;; space (5MB)
1369 (let ((out (assoc-ref outputs "out"))
1370 (idle (assoc-ref outputs "idle")))
1371 (when idle
1372 (for-each (lambda (file)
1373 (let ((target (string-append idle
1374 "/bin/"
1375 (basename
1376 file))))
1377 (install-file file
1378 (dirname target))
1379 (delete-file file)))
1380 (find-files (string-append out "/bin")
1381 "^idle"))
1382 (match (find-files out "^idlelib$"
1383 #:directories? #t)
1384 ((idlelib)
1385 (let* ((len (string-length out))
1386 (target (string-append idle "/"
1387 (string-drop
1388 idlelib len)
1389 "/site-packages")))
1390 (mkdir-p (dirname target))
1391 (rename-file idlelib target))))))))
1392 (add-after 'move-idle 'rebuild-bytecode
1393 (lambda* (#:key outputs #:allow-other-keys)
1394 (let ((out (assoc-ref outputs "out")))
1395 ;; Disable hash randomization to ensure the generated .pycs
1396 ;; are reproducible.
1397 (setenv "PYTHONHASHSEED" "0")
1398
1399 (for-each (lambda (output)
1400 ;; XXX: Delete existing pycs generated by the build
1401 ;; system beforehand because the -f argument does
1402 ;; not necessarily overwrite all files, leading to
1403 ;; indeterministic results.
1404 (for-each (lambda (pyc)
1405 (delete-file pyc))
1406 (find-files output "\\.pyc$"))
1407
1408 (apply invoke
1409 `(,#$(if (%current-target-system)
1410 "python3"
1411 #~(string-append
1412 out
1413 "/bin/python3")) "-m"
1414 "compileall"
1415 "-o"
1416 "0"
1417 "-o"
1418 "1"
1419 "-o"
1420 "2"
1421 "-f" ;force rebuild
1422 "--invalidation-mode=unchecked-hash"
1423 ;; Don't build lib2to3, because it's
1424 ;; Python 2 code.
1425 "-x"
1426 "lib2to3/.*"
1427 ,output)))
1428 (map cdr outputs)))))
1429 (add-before 'check 'set-TZDIR
1430 (lambda* (#:key inputs native-inputs #:allow-other-keys)
1431 ;; test_email requires the Olson time zone database.
1432 (setenv "TZDIR"
1433 (string-append (assoc-ref (or native-inputs
1434 inputs) "tzdata")
1435 "/share/zoneinfo"))))
1436 (add-after 'install 'install-sitecustomize.py
1437 #$(customize-site version)))))
1438 (inputs (list bzip2
1439 expat
1440 gdbm
1441 libffi ;for ctypes
1442 sqlite ;for sqlite extension
1443 openssl
1444 readline
1445 zlib
1446 tcl
1447 tk)) ;for tkinter
1448 (native-inputs `(("tzdata" ,tzdata-for-tests)
1449 ("unzip" ,unzip)
1450 ("zip" ,(@ (gnu packages compression) zip))
1451 ("pkg-config" ,pkg-config)
1452 ("sitecustomize.py" ,(local-file (search-auxiliary-file
1453 "python/sitecustomize.py")))
1454 ;; When cross-compiling, a native version of Python itself is needed.
1455 ,@(if (%current-target-system)
1456 `(("python" ,this-package)
1457 ("which" ,which))
1458 '())))
1459 (native-search-paths
1460 (list (guix-pythonpath-search-path version)
1461 ;; Used to locate tzdata by the zoneinfo module introduced in
1462 ;; Python 3.9.
1463 (search-path-specification
1464 (variable "PYTHONTZPATH")
1465 (files (list "share/zoneinfo")))))
1466 (home-page "https://www.python.org")
1467 (synopsis "High-level, dynamically-typed programming language")
1468 (description
1469 "Python is a remarkably powerful dynamic programming language that
1470is used in a wide variety of application domains. Some of its key
1471distinguishing features include: clear, readable syntax; strong
1472introspection capabilities; intuitive object orientation; natural
1473expression of procedural code; full modularity, supporting hierarchical
1474packages; exception-based error handling; and very high level dynamic
1475data types.")
1476 (properties '((cpe-name . "python")
1477 (cpe-vendor . "python")))
1478 (license license:psfl)))
1479
1480;; Next 3.x version.
1481(define-public python-next python-3.12)
1482
1483;; Current 3.x version.
1484(define-public python-3 python-3.11)
1485
1486;; Current major version.
1487(define-public python python-3)
1488
1489;; Minimal variant of Python, mostly used to break the cycle between Tk and
1490;; Python (Tk -> libxcb -> Python.)
1491
1492(define-public python-minimal
1493 (package/inherit python
1494 (name "python-minimal")
1495 (outputs '("out"))
1496
1497 ;; Build fails due to missing ctypes without libffi.
1498 ;; OpenSSL is a mandatory dependency of Python 3.x, for urllib;
1499 ;; zlib is required by 'zipimport', used by pip. Expat is needed
1500 ;; for XML support, which is generally expected to be available.
1501 (inputs (list expat libffi openssl zlib))))
1502
1503(define-public python-debug
1504 (package/inherit python
1505 (name "python-debug")
1506 (outputs '("out" "debug"))
1507 (build-system gnu-build-system)
1508 (arguments
1509 (substitute-keyword-arguments (package-arguments python)
1510 ((#:configure-flags configure-flags)
1511 #~(append #$configure-flags
1512 (list "--with-pydebug")))))
1513 (synopsis "Python with the debug hooks enabled")
1514 (description
1515 "This variant of Python provides an interpreter built with
1516@code{--with-pydebug} to help develop and debug extensions. See
1517@url{https://pythonextensionpatterns.readthedocs.io/en/latest/debugging/debug.html},
1518for more information.")))
1519
1520(define* (wrap-python3 python
1521 #:optional
1522 (name (string-append (package-name python) "-wrapper")))
1523 (package/inherit python
1524 (name name)
1525 (source #f)
1526 (build-system trivial-build-system)
1527 (outputs '("out"))
1528 (inputs `(("bash" ,bash)))
1529 (propagated-inputs `(("python" ,python)))
1530 (arguments
1531 (list #:modules '((guix build utils))
1532 #:builder
1533 #~(begin
1534 (use-modules (guix build utils))
1535 (let ((bin (string-append #$output "/bin"))
1536 (python (string-append
1537 ;; XXX: '%build-inputs' contains the native
1538 ;; Python when cross-compiling.
1539 #$(if (%current-target-system)
1540 (this-package-input "python")
1541 #~(assoc-ref %build-inputs "python"))
1542 "/bin/")))
1543 (mkdir-p bin)
1544 (for-each
1545 (lambda (old new)
1546 (symlink (string-append python old)
1547 (string-append bin "/" new)))
1548 `("python3" ,"pydoc3" ,"pip3")
1549 `("python" ,"pydoc" ,"pip"))
1550 ;; python-config outputs search paths based upon its location,
1551 ;; use a bash wrapper to avoid changing its outputs.
1552 (let ((bash (string-append (assoc-ref %build-inputs "bash")
1553 "/bin/bash"))
1554 (old (string-append python "python3-config"))
1555 (new (string-append bin "/python-config")))
1556 (with-output-to-file new
1557 (lambda ()
1558 (format #t "#!~a~%" bash)
1559 (format #t "exec \"~a\" \"$@\"~%" old)
1560 (chmod new #o755))))))))
1561 (synopsis "Wrapper for the Python 3 commands")
1562 (description
1563 "This package provides wrappers for the commands of Python@tie{}3.x such
1564that they can also be invoked under their usual names---e.g., @command{python}
1565instead of @command{python3} or @command{pip} instead of @command{pip3}.
1566
1567To function properly, this package should not be installed together with the
1568@code{python} package: this package uses the @code{python} package as a
1569propagated input, so installing this package already makes both the versioned
1570and the unversioned commands available.")))
1571
1572(define-public python-wrapper (wrap-python3 python))
1573(define-public python-minimal-wrapper (wrap-python3 python-minimal))
1574
1575;; The Python used in pyproject-build-system.
1576(define-public python-sans-pip
1577 (hidden-package
1578 (package/inherit python
1579 (arguments
1580 (substitute-keyword-arguments (package-arguments python)
1581 ((#:configure-flags flags #~())
1582 #~(append '("--with-ensurepip=no")
1583 (delete "--with-ensurepip=install" #$flags))))))))
1584
1585(define-public python-sans-pip-wrapper
1586 (wrap-python3 python-sans-pip))
1587
1588(define-public python-toolchain
1589 (let ((base (package/inherit python-sans-pip-wrapper)))
1590 (package
1591 (inherit base)
1592 (properties '())
1593 (name "python-toolchain")
1594 (propagated-inputs
1595 (modify-inputs (package-propagated-inputs base)
1596 (append python-pip
1597 python-pypa-build
1598 python-setuptools
1599 python-wheel)))
1600 (synopsis "Python toolchain")
1601 (description
1602 "Python toolchain including Python itself, setuptools and pip.
1603Use this package if you need a minimal Python toolchain instead of just
1604the interpreter."))))
1605
1606(define-public pythoncapi-compat
1607 ;; No release nor tags: use the latest commit.
1608 (let ((commit "ab72af8b1a9adfccb3578eea8e9b6d5c6449f409")
1609 (revision "1"))
1610 (package
1611 (name "pythoncapi-compat")
1612 (version (git-version "0.0.0" revision commit))
1613 (source (origin
1614 (method git-fetch)
1615 (uri (git-reference
1616 (url "https://github.com/python/pythoncapi-compat")
1617 (commit commit)))
1618 (file-name (git-file-name name version))
1619 (sha256
1620 (base32
1621 "0dfzfs399ik10125kvs5s8rid93lm50wray8s7b8bv90a61zjxiv"))))
1622 (build-system copy-build-system)
1623 (arguments (list #:install-plan
1624 #~'(("pythoncapi_compat.h" "include/"))))
1625 (home-page "https://github.com/python/pythoncapi-compat")
1626 (synopsis "Python C API compatibility")
1627 (description "The pythoncapi-compat project can be used to write a C or
1628C++ extension supporting a wide range of Python versions with a single code
1629base, via the @file{pythoncapi_compat.h} header file.")
1630 (license license:bsd-0))))
1631
1632(define-public micropython
1633 (package
1634 (name "micropython")
1635 (version "1.26.1")
1636 (source
1637 (origin
1638 (method url-fetch)
1639 (uri (string-append "https://github.com/micropython/micropython/"
1640 "releases/download/v" version
1641 "/micropython-" version ".tar.xz"))
1642 (sha256
1643 (base32 "165c8g60f5zf82gw2d94snyjmcgn999jn4i8ngyc0wk2vwa6bghj"))
1644 (modules '((guix build utils)))
1645 (snippet
1646 '(begin
1647 (delete-file-recursively "ports/cc3200/FreeRTOS")
1648 (with-directory-excursion "lib"
1649 ;; TODO: Unbundle axtls and berkley-db-1.xx
1650 (for-each delete-file-recursively
1651 '("libffi" "lwip" "stm32lib" "nrfx")))))))
1652 (build-system gnu-build-system)
1653 (arguments
1654 (list #:phases
1655 #~(modify-phases %standard-phases
1656 (add-before 'build 'build-mpy-cross
1657 (lambda* (#:key make-flags #:allow-other-keys)
1658 (with-directory-excursion "mpy-cross"
1659 (apply invoke "make" make-flags))))
1660 (add-after 'build-mpy-cross 'prepare-build
1661 (lambda _
1662 (chdir "ports/unix")
1663 ;; see: https://github.com/micropython/micropython/pull/4246
1664 (substitute* "Makefile"
1665 (("-Os") "-Os -ffp-contract=off"))))
1666 (add-before 'install-license-files 'chdir-back
1667 ;; We don't build in the root directory so the file isn't found.
1668 (lambda _
1669 (chdir "../..")))
1670 (delete 'configure)) ; no configure
1671 #:make-flags
1672 #~(list (string-append "PREFIX=" #$output)
1673 "V=1")
1674 #:test-target "test"))
1675 (native-inputs (list pkg-config python-wrapper))
1676 (inputs
1677 (list libffi))
1678 (home-page "https://micropython.org/")
1679 (synopsis "Python implementation for microcontrollers and constrained systems")
1680 (description "MicroPython is a lean and efficient implementation of the
1681Python 3 programming language that includes a small subset of the Python
1682standard library and is optimised to run on microcontrollers and in constrained
1683environments. MicroPython is packed full of advanced features such as an
1684interactive prompt, arbitrary precision integers, closures, list comprehension,
1685generators, exception handling and more. Still it is compact enough to fit and
1686run within just 256k of code space and 16k of RAM. MicroPython aims to be as
1687compatible with normal Python as possible to allow you to transfer code with
1688ease from the desktop to a microcontroller or embedded system.")
1689 (license license:expat)))