projects/guix·blob mpd-fix-groups · refs

1696 lines · 83.9 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 (license license:psfl)))
458
459;; Current 2.x version.
460(define-public python-2 python-2.7)
461
462(define-public python-3.10
463 (package
464 (inherit python-2)
465 (name "python")
466 (version "3.10.19")
467 (source (origin
468 (method url-fetch)
469 (uri (string-append "https://www.python.org/ftp/python/"
470 version "/Python-" version ".tar.xz"))
471 (patches (search-patches
472 "python-3-arm-alignment.patch"
473 "python-3-deterministic-build-info.patch"
474 "python-3-fix-tests.patch"
475 "python-3-hurd-configure.patch"
476 "python-3-reproducible-build.patch"
477 "python-3-search-paths.patch"))
478 (sha256
479 (base32
480 "0xn0jydg5fsz9fsni6a83l7sf6by2w7gg4fzswfxh092aybabx68"))
481 (modules '((guix build utils)))
482 (snippet
483 '(begin
484 ;; Delete the bundled copy of libexpat.
485 (delete-file-recursively "Modules/expat")
486 (substitute* "Modules/Setup"
487 ;; Link Expat instead of embedding the bundled one.
488 (("^#pyexpat.*") "pyexpat pyexpat.c -lexpat\n"))
489 ;; Delete windows binaries
490 (for-each delete-file
491 (find-files "Lib/distutils/command" "\\.exe$"))))))
492 (arguments
493 (substitute-keyword-arguments (package-arguments python-2)
494 ((#:configure-flags flags)
495 #~(append #$flags
496 ;; XXX Use quote to avoid world rebuild at this time
497 '("--without-static-libpython")))
498 ((#:make-flags _)
499 #~(list (string-append
500 (format #f "TESTOPTS=-j~d" (parallel-job-count))
501 ;; test_mmap fails on low-memory systems
502 " --exclude test_mmap test_socket"
503 #$@(if (system-hurd?)
504 #~(" test_posix" ;multiple errors
505 " test_time"
506 " test_pty"
507 " test_shutil"
508 " test_tempfile" ;chflags: invalid argument:
509 ; tbv14c9t/dir0/dir0/dir0/test0.txt
510 " test_asyncio" ;runs over 10min
511 " test_os" ;stty: 'standard input':
512 ; Inappropriate ioctl for device
513 " test_openpty" ;No such file or directory
514 " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
515 ; 32752 != 4
516 " test_compileall" ;multiple errors
517 " test_poll" ;list index out of range
518 " test_subprocess" ;runs over 10min
519 " test_asyncore" ;multiple errors
520 " test_threadsignals"
521 " test_eintr" ;Process return code is -14
522 " test_io" ;multiple errors
523 " test_logging"
524 " test_signal"
525 " test_threading" ;runs over 10min
526 " test_flags" ;ERROR
527 " test_bidirectional_pty"
528 " test_create_unix_connection"
529 " test_unix_sock_client_ops"
530 " test_open_unix_connection"
531 " test_open_unix_connection_error"
532 " test_read_pty_output"
533 " test_write_pty"
534 " test_concurrent_futures" ;freeze
535 " test_venv" ;freeze
536 " test_multiprocessing_forkserver" ;runs over 10min
537 " test_multiprocessing_spawn" ;runs over 10min
538 " test_builtin"
539 " test_capi"
540 " test_dbm_ndbm"
541 " test_exceptions"
542 " test_faulthandler"
543 " test_getopt"
544 " test_importlib"
545 " test_json"
546 " test_multiprocessing_fork"
547 " test_multiprocessing_main_handling"
548 " test_pdb "
549 " test_regrtest"
550 " test_sqlite")
551 #~()))))
552 ((#:phases phases)
553 #~(modify-phases #$phases
554 #$@(if (system-hurd?)
555 #~((delete 'patch-regen-for-hurd) ;regen was removed after 3.5.9
556 (add-after 'unpack 'disable-multi-processing
557 (lambda _
558 (substitute* "Makefile.pre.in"
559 (("-j0") "-j1")))))
560 #~())
561 (add-after 'unpack 'remove-vendored-wheel-content
562 (lambda _
563 ;; Delete .exe from embedded .whl (zip) files
564 (for-each
565 (lambda (whl)
566 (let ((dir "whl-content")
567 (circa-1980 (* 10 366 24 60 60)))
568 (mkdir-p dir)
569 (with-directory-excursion dir
570 (let ((whl (string-append "../" whl)))
571 (invoke "unzip" whl)
572 (for-each delete-file
573 (find-files "." "\\.exe$"))
574 (delete-file whl)
575
576 ;; Search for cacert.pem, delete it, and rewrite the
577 ;; file which directs python to look for it.
578 (let ((cacert (find-files "." "cacert\\.pem")))
579 (unless (null? cacert)
580 (let ((certifi (dirname (car cacert))))
581 (delete-file (string-append certifi "/cacert.pem"))
582 (delete-file (string-append certifi "/core.py"))
583 (with-output-to-file (string-append certifi "/core.py")
584 (lambda _
585 (display "\"\"\"
586certifi.py
587~~~~~~~~~~
588This file is a Guix-specific version of core.py.
589
590This module returns the installation location of SSL_CERT_FILE or
591/etc/ssl/certs/ca-certificates.crt, or its contents.
592\"\"\"
593import os
594
595_CA_CERTS = None
596
597try:
598 _CA_CERTS = os.environ [\"SSL_CERT_FILE\"]
599except:
600 _CA_CERTS = os.path.join(\"/etc\", \"ssl\", \"certs\", \"ca-certificates.crt\")
601
602def where() -> str:
603 return _CA_CERTS
604
605def contents() -> str:
606 with open(where(), \"r\", encoding=\"ascii\") as data:
607 return data.read()"))))))
608
609 ;; Reset timestamps to prevent them from ending
610 ;; up in the Zip archive.
611 (ftw "." (lambda (file stat flag)
612 (utime file circa-1980 circa-1980)
613 #t))
614 (apply invoke "zip" "-X" whl
615 (find-files "." #:directories? #t))))
616 (delete-file-recursively dir)))
617 (find-files "Lib/ensurepip" "\\.whl$"))))
618 (add-before 'check 'set-TZDIR
619 (lambda* (#:key inputs native-inputs #:allow-other-keys)
620 ;; test_email requires the Olson time zone database.
621 (setenv "TZDIR"
622 (string-append (assoc-ref
623 (or native-inputs inputs) "tzdata")
624 "/share/zoneinfo"))))
625 (replace 'rebuild-bytecode
626 (lambda* (#:key outputs #:allow-other-keys)
627 (let ((out (assoc-ref outputs "out")))
628 ;; Disable hash randomization to ensure the generated .pycs
629 ;; are reproducible.
630 (setenv "PYTHONHASHSEED" "0")
631
632 (for-each (lambda (output)
633 ;; XXX: Delete existing pycs generated by the build
634 ;; system beforehand because the -f argument does
635 ;; not necessarily overwrite all files, leading to
636 ;; indeterministic results.
637 (for-each (lambda (pyc)
638 (delete-file pyc))
639 (find-files output "\\.pyc$"))
640
641 (apply invoke
642 `(,#$(if (%current-target-system)
643 "python3"
644 #~(string-append out
645 "/bin/python3"))
646 "-m" "compileall"
647 "-o" "0" "-o" "1" "-o" "2"
648 "-f" ; force rebuild
649 "--invalidation-mode=unchecked-hash"
650 ;; Don't build lib2to3, because it's
651 ;; Python 2 code.
652 "-x" "lib2to3/.*"
653 ,output)))
654 (map cdr outputs)))))
655 (replace 'install-sitecustomize.py
656 #$(customize-site version))))))
657 (inputs
658 (modify-inputs (package-inputs python-2.7)
659 (replace "openssl" openssl)))
660 (native-inputs
661 (let ((inputs (modify-inputs (package-native-inputs python-2)
662 (prepend tzdata-for-tests
663 unzip
664 (@ (gnu packages compression) zip)))))
665 (if (%current-target-system)
666 (modify-inputs inputs (prepend this-package))
667 inputs)))
668 (native-search-paths
669 (list (guix-pythonpath-search-path version)
670 ;; Used to locate tzdata by the zoneinfo module introduced in
671 ;; Python 3.9.
672 (search-path-specification
673 (variable "PYTHONTZPATH")
674 (files (list "share/zoneinfo")))))))
675
676(define-public python-3.11
677 (package
678 (inherit python-3.10)
679 (name "python")
680 (version "3.11.11")
681 (replacement python-3.11/fixed)
682 (source (origin
683 (method url-fetch)
684 (uri (string-append "https://www.python.org/ftp/python/"
685 version "/Python-" version ".tar.xz"))
686 (patches (search-patches
687 "python-3-deterministic-build-info.patch"
688 "python-3.11-fix-tests.patch"
689 "python-3-hurd-configure.patch"
690 "python-3-search-paths.patch"))
691 (sha256
692 (base32
693 "1qrvsxg5g0b0pgz2iigxic2j3g6b2c59iva46vins8ydl33j169a"))
694 (modules '((guix build utils)))
695 (snippet
696 '(begin
697 ;; Delete the bundled copy of libexpat.
698 (delete-file-recursively "Modules/expat")
699 (substitute* "Modules/Setup"
700 ;; Link Expat instead of embedding the bundled one.
701 (("^#pyexpat.*") "pyexpat pyexpat.c -lexpat\n"))
702 ;; Delete windows binaries
703 (for-each delete-file
704 (find-files "Lib/distutils/command" "\\.exe$"))))))
705 (arguments
706 (list
707 #:test-target "test"
708 #:configure-flags
709 #~(list "--enable-shared" ;allow embedding
710 "--with-system-expat" ;for XML support
711 "--with-system-ffi" ;build ctypes
712 "--with-ensurepip=install" ;install pip and setuptools
713 "--with-computed-gotos" ;main interpreter loop optimization
714 "--enable-unicode=ucs4"
715 "--without-static-libpython"
716 "--enable-loadable-sqlite-extensions"
717
718 ;; FIXME: These flags makes Python significantly faster,
719 ;; but leads to non-reproducible binaries.
720 ;; "--with-lto" ;increase size by 20MB, but 15% speedup
721 ;; "--enable-optimizations"
722
723 ;; Prevent the installed _sysconfigdata.py from retaining
724 ;; a reference to coreutils.
725 "INSTALL=install -c"
726 "MKDIR_P=mkdir -p"
727
728 ;; Add a reference to libxcrypt in LIBS so that the
729 ;; sysconfigdata file records it and propagates it to programs
730 ;; linking against Python.
731 (let ((libxcrypt
732 (false-if-exception
733 (dirname
734 (search-input-file %build-inputs
735 "lib/libcrypt.so.1")))))
736 (string-append
737 "LIBS="
738 (if libxcrypt
739 (string-append "-L" libxcrypt)
740 "")))
741
742 ;; Disable runtime check failing if cross-compiling, see:
743 ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
744 #$@(if (%current-target-system)
745 #~("ac_cv_buggy_getaddrinfo=no"
746 "ac_cv_file__dev_ptmx=no"
747 "ac_cv_file__dev_ptc=no"
748 (string-append "--with-build-python="
749 #+(this-package-native-input "python")
750 "/bin/python3"))
751 '())
752 ;; -fno-semantic-interposition reinstates some
753 ;; optimizations by gcc leading to around 15% speedup.
754 ;; This is the default starting from python 3.10.
755 "CFLAGS=-fno-semantic-interposition"
756 (string-append "LDFLAGS=-Wl,-rpath=" #$output "/lib"
757 " -fno-semantic-interposition"))
758 ;; With no -j argument tests use all available cpus, so provide one.
759 #:make-flags
760 `(list (string-append (format #f "TESTOPTS=-j~d"
761 (parallel-job-count))
762 ;; those tests fail on low-memory systems
763 " --exclude"
764 " test_mmap"
765 " test_socket"
766 " test_threading"
767 " test_asyncio"
768 " test_shutdown"
769 ,@(if (system-hurd?)
770 '(" test_posix" ;multiple errors
771 " test_time"
772 " test_pty"
773 " test_shutil"
774 " test_tempfile" ;chflags: invalid argument:
775 ;; tbv14c9t/dir0/dir0/dir0/test0.txt
776 " test_os" ;stty: 'standard input':
777 ;; Inappropriate ioctl for device
778 " test_openpty" ;No such file or directory
779 " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
780 ;; 32752 != 4
781 " test_compileall" ;multiple errors
782 " test_poll" ;list index out of range
783 " test_subprocess" ;runs over 10min
784 " test_asyncore" ;multiple errors
785 " test_threadsignals"
786 " test_eintr" ;Process return code is -14
787 " test_io" ;multiple errors
788 " test_logging"
789 " test_signal"
790 " test_flags" ;ERROR
791 " test_bidirectional_pty"
792 " test_create_unix_connection"
793 " test_unix_sock_client_ops"
794 " test_open_unix_connection"
795 " test_open_unix_connection_error"
796 " test_read_pty_output"
797 " test_write_pty"
798 " test_concurrent_futures" ;freeze
799 " test_venv" ;freeze
800 " test_multiprocessing_forkserver" ;runs over 10min
801 " test_multiprocessing_spawn" ;runs over 10min
802 " test_glob" ;did not finish in 10h
803 " test_site" ;Invalid argument
804 " test_termios" ;os.openpty() Operation not permitted
805 " test_tty" ;os.openpty() Operation not permitted
806 " test_sqlite3" ;; sqlite3.OperationalError: database is locked
807 " test_builtin"
808 " test_capi"
809 " test_dbm_ndbm"
810 " test_exceptions"
811 " test_faulthandler"
812 " test_getopt"
813 " test_importlib"
814 " test_json"
815 " test_multiprocessing_fork"
816 " test_multiprocessing_main_handling"
817 " test_pdb "
818 " test_regrtest"
819 " test_sqlite")
820 '())))
821
822 #:modules
823 '((ice-9 ftw)
824 (ice-9 match)
825 (guix build utils)
826 (guix build gnu-build-system))
827
828 #:phases
829 #~(modify-phases %standard-phases
830 #$@(if (system-hurd?)
831 `((add-after 'unpack
832 'disable-multi-processing
833 (lambda _
834 (substitute* "Makefile.pre.in"
835 (("-j0")
836 "-j1")))))
837 '())
838 (add-before 'configure 'patch-lib-shells
839 (lambda _
840 ;; This variable is used in setup.py to enable cross compilation
841 ;; specific switches. As it is not set properly by configure
842 ;; script, set it manually.
843 #$@(if (%current-target-system)
844 '((setenv "_PYTHON_HOST_PLATFORM" ""))
845 '())
846 ;; Filter for existing files, since some may not exist in all
847 ;; versions of python that are built with this recipe.
848 (substitute* (filter file-exists?
849 '("Lib/subprocess.py"
850 "Lib/popen2.py"
851 "Lib/distutils/tests/test_spawn.py"
852 "Lib/test/support/__init__.py"
853 "Lib/test/test_subprocess.py"))
854 (("/bin/sh")
855 (which "sh")))))
856 (add-before 'configure 'do-not-record-configure-flags
857 (lambda* (#:key configure-flags #:allow-other-keys)
858 ;; Remove configure flags from the installed '_sysconfigdata.py'
859 ;; and 'Makefile' so we don't end up keeping references to the
860 ;; build tools.
861 ;;
862 ;; Preserve at least '--with-system-ffi' since otherwise the
863 ;; thing tries to build libffi, fails, and we end up with a
864 ;; Python that lacks ctypes.
865 (substitute* "configure"
866 (("^CONFIG_ARGS=.*$")
867 (format #f "CONFIG_ARGS='~a'\n"
868 (if (member "--with-system-ffi"
869 configure-flags)
870 "--with-system-ffi" ""))))))
871 (add-before 'check 'pre-check
872 (lambda _
873 ;; 'Lib/test/test_site.py' needs a valid $HOME
874 (setenv "HOME"
875 (getcwd))))
876 (add-after 'unpack 'set-source-file-times-to-1980
877 ;; XXX One of the tests uses a ZIP library to pack up some of the
878 ;; source tree, and fails with "ZIP does not support timestamps
879 ;; before 1980". Work around this by setting the file times in the
880 ;; source tree to sometime in early 1980.
881 (lambda _
882 (let ((circa-1980 (* 10 366 24 60 60)))
883 (ftw "."
884 (lambda (file stat flag)
885 (utime file circa-1980 circa-1980) #t)))))
886 (add-after 'unpack 'remove-windows-binaries
887 (lambda _
888 ;; Delete .exe from embedded .whl (zip) files
889 (for-each (lambda (whl)
890 (let ((dir "whl-content")
891 (circa-1980 (* 10 366 24 60 60)))
892 (mkdir-p dir)
893 (with-directory-excursion dir
894 (let ((whl (string-append "../" whl)))
895 (invoke "unzip" whl)
896 (for-each delete-file
897 (find-files "." "\\.exe$"))
898 (delete-file whl)
899 ;; Reset timestamps to prevent them from ending
900 ;; up in the Zip archive.
901 (ftw "."
902 (lambda (file stat flag)
903 (utime file circa-1980
904 circa-1980) #t))
905 (apply invoke "zip" "-X" whl
906 (find-files "."
907 #:directories? #t))))
908 (delete-file-recursively dir)))
909 (find-files "Lib/ensurepip" "\\.whl$"))))
910 (add-after 'install 'remove-tests
911 ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
912 ;; because these files are used by some libraries out there.
913 (lambda* (#:key outputs #:allow-other-keys)
914 (let ((out (assoc-ref outputs "out")))
915 (match (scandir (string-append out "/lib")
916 (lambda (name)
917 (string-prefix? "python" name)))
918 ((pythonX.Y)
919 (let ((testdir (string-append out "/lib/" pythonX.Y
920 "/test")))
921 (with-directory-excursion testdir
922 (for-each delete-file-recursively
923 (scandir testdir
924 (match-lambda
925 ((or "." "..")
926 #f)
927 ("support" #f)
928 (file (not (string-prefix?
929 "test_support."
930 file))))))
931 (call-with-output-file "__init__.py"
932 (const #t))))
933 (let ((libdir (string-append out "/lib/" pythonX.Y)))
934 (for-each (lambda (directory)
935 (let ((dir (string-append libdir "/"
936 directory)))
937 (when (file-exists? dir)
938 (delete-file-recursively dir))))
939 '("email/test" "ctypes/test"
940 "unittest/test"
941 "tkinter/test"
942 "sqlite3/test"
943 "bsddb/test"
944 "lib-tk/test"
945 "json/tests"
946 "distutils/tests"))))))))
947 (add-after 'remove-tests 'move-tk-inter
948 (lambda* (#:key outputs inputs #:allow-other-keys)
949 ;; When Tkinter support is built move it to a separate output so
950 ;; that the main output doesn't contain a reference to Tcl/Tk.
951 (let ((out (assoc-ref outputs "out"))
952 (tk (assoc-ref outputs "tk")))
953 (when tk
954 (match (find-files out "tkinter.*\\.so")
955 ((tkinter.so)
956 ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
957 ;; want it under TK/lib/pythonX.Y/site-packages.
958 (let* ((len (string-length out))
959 (target (string-append tk "/"
960 (string-drop (dirname
961 (dirname
962 tkinter.so))
963 len)
964 "/site-packages")))
965 (install-file tkinter.so target)
966 (delete-file tkinter.so))))
967 ;; Remove explicit store path references.
968 (let ((tcl (assoc-ref inputs "tcl"))
969 (tk (assoc-ref inputs "tk")))
970 (substitute* (find-files (string-append out "/lib")
971 "^(_sysconfigdata_.*\\.py|Makefile)$")
972 (((string-append "-L" tk "/lib"))
973 "")
974 (((string-append "-L" tcl "/lib"))
975 "")))))))
976 (add-after 'move-tk-inter 'move-idle
977 (lambda* (#:key outputs #:allow-other-keys)
978 ;; when idle is built, move it to a separate output to save some
979 ;; space (5MB)
980 (let ((out (assoc-ref outputs "out"))
981 (idle (assoc-ref outputs "idle")))
982 (when idle
983 (for-each (lambda (file)
984 (let ((target (string-append idle
985 "/bin/"
986 (basename
987 file))))
988 (install-file file
989 (dirname target))
990 (delete-file file)))
991 (find-files (string-append out "/bin")
992 "^idle"))
993 (match (find-files out "^idlelib$"
994 #:directories? #t)
995 ((idlelib)
996 (let* ((len (string-length out))
997 (target (string-append idle "/"
998 (string-drop
999 idlelib len)
1000 "/site-packages")))
1001 (mkdir-p (dirname target))
1002 (rename-file idlelib target))))))))
1003 (add-after 'move-idle 'rebuild-bytecode
1004 (lambda* (#:key outputs #:allow-other-keys)
1005 ;; Disable hash randomization to ensure the generated .pycs
1006 ;; are reproducible.
1007 (setenv "PYTHONHASHSEED" "0")
1008
1009 (for-each (lambda (output)
1010 ;; XXX: Delete existing pycs generated by the build
1011 ;; system beforehand because the -f argument does
1012 ;; not necessarily overwrite all files, leading to
1013 ;; indeterministic results.
1014 (for-each (lambda (pyc)
1015 (delete-file pyc))
1016 (find-files output "\\.pyc$"))
1017
1018 (apply invoke
1019 #$(if (%current-target-system)
1020 "python3"
1021 #~(string-append #$output "/bin/python3"))
1022 `("-m" "compileall"
1023 "-o" "0"
1024 "-o" "1"
1025 "-o" "2"
1026 "-f" ;force rebuild
1027 "--invalidation-mode=unchecked-hash"
1028 ;; Don't build lib2to3, because it's Python
1029 ;; 2 code.
1030 "-x" "lib2to3/.*"
1031 ,output)))
1032 (map cdr outputs))))
1033 (add-before 'check 'set-TZDIR
1034 (lambda* (#:key inputs native-inputs #:allow-other-keys)
1035 ;; test_email requires the Olson time zone database.
1036 (setenv "TZDIR"
1037 (string-append (assoc-ref (or native-inputs
1038 inputs) "tzdata")
1039 "/share/zoneinfo"))))
1040 (add-after 'install 'add-libxcrypt-reference-pkgconfig
1041 (lambda* (#:key inputs #:allow-other-keys)
1042 (let ((libxcrypt
1043 (false-if-exception
1044 (dirname
1045 (search-input-file inputs "lib/libcrypt.so.1")))))
1046 (when libxcrypt
1047 (substitute*
1048 (find-files (string-append #$output "/lib/pkgconfig")
1049 ".*\\.pc")
1050 (("Libs:")
1051 (string-append "Libs: " "-L" libxcrypt " -lcrypt")))))))
1052 (add-after 'install 'install-sitecustomize.py
1053 #$(customize-site version)))))
1054 (inputs (list bzip2
1055 expat
1056 gdbm
1057 libffi ;for ctypes
1058 libxcrypt ;crypto module slated for removal in 3.13
1059 sqlite ;for sqlite extension
1060 openssl
1061 readline
1062 zlib
1063 tcl
1064 tk)) ;for tkinter
1065 (native-inputs `(("tzdata" ,tzdata-for-tests)
1066 ("unzip" ,unzip)
1067 ("zip" ,(@ (gnu packages compression) zip))
1068 ("pkg-config" ,pkg-config)
1069 ("sitecustomize.py" ,(local-file (search-auxiliary-file
1070 "python/sitecustomize.py")))
1071 ;; When cross-compiling, a native version of Python itself is needed.
1072 ,@(if (%current-target-system)
1073 `(("python" ,this-package)
1074 ("which" ,which))
1075 '())))
1076 (native-search-paths
1077 (list (guix-pythonpath-search-path version)
1078 ;; Used to locate tzdata by the zoneinfo module introduced in
1079 ;; Python 3.9.
1080 (search-path-specification
1081 (variable "PYTHONTZPATH")
1082 (files (list "share/zoneinfo")))))))
1083
1084(define-public python-3.11/fixed
1085 (package/inherit python-3.11
1086 (version "3.11.14")
1087 (source (origin
1088 (inherit (package-source python-3.11))
1089 (uri (string-append "https://www.python.org/ftp/python/" version
1090 "/Python-" version ".tar.xz"))
1091 (sha256 (base32
1092 "0y4v42qm66nvizjxbnixh59283a54nki51jmbrgwkhc8bkndhgld"))))))
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 (package-arguments python)
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 (package-arguments python)
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 python-toolchain
1596 (let ((base (package/inherit python-sans-pip-wrapper)))
1597 (package
1598 (inherit base)
1599 (properties '())
1600 (name "python-toolchain")
1601 (propagated-inputs
1602 (modify-inputs (package-propagated-inputs base)
1603 (append python-pip
1604 python-pypa-build
1605 python-setuptools
1606 python-wheel)))
1607 (synopsis "Python toolchain")
1608 (description
1609 "Python toolchain including Python itself, setuptools and pip.
1610Use this package if you need a minimal Python toolchain instead of just
1611the interpreter."))))
1612
1613(define-public pythoncapi-compat
1614 ;; No release nor tags: use the latest commit.
1615 (let ((commit "ab72af8b1a9adfccb3578eea8e9b6d5c6449f409")
1616 (revision "1"))
1617 (package
1618 (name "pythoncapi-compat")
1619 (version (git-version "0.0.0" revision commit))
1620 (source (origin
1621 (method git-fetch)
1622 (uri (git-reference
1623 (url "https://github.com/python/pythoncapi-compat")
1624 (commit commit)))
1625 (file-name (git-file-name name version))
1626 (sha256
1627 (base32
1628 "0dfzfs399ik10125kvs5s8rid93lm50wray8s7b8bv90a61zjxiv"))))
1629 (build-system copy-build-system)
1630 (arguments (list #:install-plan
1631 #~'(("pythoncapi_compat.h" "include/"))))
1632 (home-page "https://github.com/python/pythoncapi-compat")
1633 (synopsis "Python C API compatibility")
1634 (description "The pythoncapi-compat project can be used to write a C or
1635C++ extension supporting a wide range of Python versions with a single code
1636base, via the @file{pythoncapi_compat.h} header file.")
1637 (license license:bsd-0))))
1638
1639(define-public micropython
1640 (package
1641 (name "micropython")
1642 (version "1.26.1")
1643 (source
1644 (origin
1645 (method url-fetch)
1646 (uri (string-append "https://github.com/micropython/micropython/"
1647 "releases/download/v" version
1648 "/micropython-" version ".tar.xz"))
1649 (sha256
1650 (base32 "165c8g60f5zf82gw2d94snyjmcgn999jn4i8ngyc0wk2vwa6bghj"))
1651 (modules '((guix build utils)))
1652 (snippet
1653 '(begin
1654 (delete-file-recursively "ports/cc3200/FreeRTOS")
1655 (with-directory-excursion "lib"
1656 ;; TODO: Unbundle axtls and berkley-db-1.xx
1657 (for-each delete-file-recursively
1658 '("libffi" "lwip" "stm32lib" "nrfx")))))))
1659 (build-system gnu-build-system)
1660 (arguments
1661 (list #:phases
1662 #~(modify-phases %standard-phases
1663 (add-before 'build 'build-mpy-cross
1664 (lambda* (#:key make-flags #:allow-other-keys)
1665 (with-directory-excursion "mpy-cross"
1666 (apply invoke "make" make-flags))))
1667 (add-after 'build-mpy-cross 'prepare-build
1668 (lambda _
1669 (chdir "ports/unix")
1670 ;; see: https://github.com/micropython/micropython/pull/4246
1671 (substitute* "Makefile"
1672 (("-Os") "-Os -ffp-contract=off"))))
1673 (add-before 'install-license-files 'chdir-back
1674 ;; We don't build in the root directory so the file isn't found.
1675 (lambda _
1676 (chdir "../..")))
1677 (delete 'configure)) ; no configure
1678 #:make-flags
1679 #~(list (string-append "PREFIX=" #$output)
1680 "V=1")
1681 #:test-target "test"))
1682 (native-inputs (list pkg-config python-wrapper))
1683 (inputs
1684 (list libffi))
1685 (home-page "https://micropython.org/")
1686 (synopsis "Python implementation for microcontrollers and constrained systems")
1687 (description "MicroPython is a lean and efficient implementation of the
1688Python 3 programming language that includes a small subset of the Python
1689standard library and is optimised to run on microcontrollers and in constrained
1690environments. MicroPython is packed full of advanced features such as an
1691interactive prompt, arbitrary precision integers, closures, list comprehension,
1692generators, exception handling and more. Still it is compact enough to fit and
1693run within just 256k of code space and 16k of RAM. MicroPython aims to be as
1694compatible with normal Python as possible to allow you to transfer code with
1695ease from the desktop to a microcontroller or embedded system.")
1696 (license license:expat)))