build-system: Add pyproject-build-system.
[jackhill/guix/guix.git] / gnu / packages / python.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
3 ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2021 Ludovic Courtès <ludo@gnu.org>
4 ;;; Copyright © 2013, 2014, 2015, 2016 Andreas Enge <andreas@enge.fr>
5 ;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
6 ;;; Copyright © 2014, 2017, 2019 Eric Bavier <bavier@member.fsf.org>
7 ;;; Copyright © 2014, 2015 Federico Beffa <beffa@fbengineering.ch>
8 ;;; Copyright © 2015 Omar Radwan <toxemicsquire4@gmail.com>
9 ;;; Copyright © 2015 Pierre-Antoine Rault <par@rigelk.eu>
10 ;;; Copyright © 2015, 2016, 2017, 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
11 ;;; Copyright © 2015, 2016 Christine Lemmer-Webber <cwebber@dustycloud.org>
12 ;;; Copyright © 2015 Eric Dvorsak <eric@dvorsak.fr>
13 ;;; Copyright © 2015, 2016 David Thompson <davet@gnu.org>
14 ;;; Copyright © 2015, 2016, 2017, 2021 Leo Famulari <leo@famulari.name>
15 ;;; Copyright © 2015, 2017 Ben Woodcroft <donttrustben@gmail.com>
16 ;;; Copyright © 2015, 2016 Erik Edrosa <erik.edrosa@gmail.com>
17 ;;; Copyright © 2015, 2016, 2017, 2018, 2019, 2020 Efraim Flashner <efraim@flashner.co.il>
18 ;;; Copyright © 2015, 2017 Kyle Meyer <kyle@kyleam.com>
19 ;;; Copyright © 2015, 2016 Chris Marusich <cmmarusich@gmail.com>
20 ;;; Copyright © 2016 Danny Milosavljevic <dannym+a@scratchpost.org>
21 ;;; Copyright © 2016 Lukas Gradl <lgradl@openmailbox.org>
22 ;;; Copyright © 2016, 2018 Hartmut Goebel <h.goebel@crazy-compilers.com>
23 ;;; Copyright © 2016 Daniel Pimentel <d4n1@d4n1.org>
24 ;;; Copyright © 2016 Sou Bunnbu <iyzsong@gmail.com>
25 ;;; Copyright © 2016, 2017 Troy Sankey <sankeytms@gmail.com>
26 ;;; Copyright © 2016, 2017 Nikita <nikita@n0.is>
27 ;;; Copyright © 2016 Dylan Jeffers <sapientech@sapientech@openmailbox.org>
28 ;;; Copyright © 2016 David Craven <david@craven.ch>
29 ;;; Copyright © 2016-2022 Marius Bakke <marius@gnu.org>
30 ;;; Copyright © 2016, 2017 Stefan Reichör <stefan@xsteve.at>
31 ;;; Copyright © 2016, 2017 Alex Vong <alexvong1995@gmail.com>
32 ;;; Copyright © 2016, 2017, 2018 Arun Isaac <arunisaac@systemreboot.net>
33 ;;; Copyright © 2016–2018, 2021, 2022 Tobias Geerinckx-Rice <me@tobias.gr>
34 ;;; Copyright © 2016, 2017, 2018, 2021 Julien Lepiller <julien@lepiller.eu>
35 ;;; Copyright © 2016, 2017 Thomas Danckaert <post@thomasdanckaert.be>
36 ;;; Copyright © 2017 Carlo Zancanaro <carlo@zancanaro.id.au>
37 ;;; Copyright © 2017 Frederick M. Muriithi <fredmanglis@gmail.com>
38 ;;; Copyright © 2017, 2018 Adriano Peluso <catonano@gmail.com>
39 ;;; Copyright © 2017 Ben Sturmfels <ben@sturm.com.au>
40 ;;; Copyright © 2017, 2018, 2019 Mathieu Othacehe <m.othacehe@gmail.com>
41 ;;; Copyright © 2017 José Miguel Sánchez García <jmi2k@openmailbox.org>
42 ;;; Copyright © 2017 Roel Janssen <roel@gnu.org>
43 ;;; Copyright © 2017, 2018 Kei Kebreau <kkebreau@posteo.net>
44 ;;; Copyright © 2017 Rutger Helling <rhelling@mykolab.com>
45 ;;; Copyright © 2017 Brendan Tildesley <mail@brendan.scot>
46 ;;; Copyright © 2018 Ethan R. Jones <ethanrjones97@gmail.com
47 ;;; Copyright © 2018 Fis Trivial <ybbs.daans@hotmail.com>
48 ;;; Copyright © 2018 Vijayalakshmi Vedantham <vijimay12@gmail.com>
49 ;;; Copyright © 2018 Mathieu Lirzin <mthl@gnu.org>
50 ;;; Copyright © 2018 Adam Massmann <massmannak@gmail.com>
51 ;;; Copyright © 2016, 2018 Tomáš Čech <sleep_walker@gnu.org>
52 ;;; Copyright © 2018 Nicolas Goaziou <mail@nicolasgoaziou.fr>
53 ;;; Copyright © 2018 Oleg Pykhalov <go.wigust@gmail.com>
54 ;;; Copyright © 2018 Clément Lassieur <clement@lassieur.org>
55 ;;; Copyright © 2018, 2019, 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
56 ;;; Copyright © 2018 Luther Thompson <lutheroto@gmail.com>
57 ;;; Copyright © 2018 Vagrant Cascadian <vagrant@debian.org>
58 ;;; Copyright © 2019 Tanguy Le Carrour <tanguy@bioneland.org>
59 ;;; Copyright © 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
60 ;;; Copyright © 2020, 2021 Greg Hogan <code@greghogan.com>
61 ;;; Copyright © 2022 Philip McGrath <philip@philipmcgrath.com>
62 ;;; Copyright © 2022 jgart <jgart@dismail.de>
63 ;;; Copyright © 2021 Lars-Dominik Braun <lars@6xq.net>
64 ;;;
65 ;;; This file is part of GNU Guix.
66 ;;;
67 ;;; GNU Guix is free software; you can redistribute it and/or modify it
68 ;;; under the terms of the GNU General Public License as published by
69 ;;; the Free Software Foundation; either version 3 of the License, or (at
70 ;;; your option) any later version.
71 ;;;
72 ;;; GNU Guix is distributed in the hope that it will be useful, but
73 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
74 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
75 ;;; GNU General Public License for more details.
76 ;;;
77 ;;; You should have received a copy of the GNU General Public License
78 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
79
80 (define-module (gnu packages python)
81 #:use-module ((guix licenses) #:prefix license:)
82 #:use-module (gnu packages)
83 #:use-module (gnu packages base)
84 #:use-module (gnu packages bash)
85 #:use-module (gnu packages check)
86 #:use-module (gnu packages compression)
87 #:use-module (gnu packages dbm)
88 #:use-module (gnu packages hurd)
89 #:use-module (gnu packages libffi)
90 #:use-module (gnu packages pkg-config)
91 #:use-module (gnu packages python-build)
92 #:use-module (gnu packages readline)
93 #:use-module (gnu packages sqlite)
94 #:use-module (gnu packages tcl)
95 #:use-module (gnu packages tls)
96 #:use-module (gnu packages xml)
97 #:use-module (guix gexp)
98 #:use-module (guix packages)
99 #:use-module (guix download)
100 #:use-module (guix utils)
101 #:use-module (guix build-system gnu)
102 #:use-module (guix build-system trivial)
103 #:use-module (srfi srfi-1)
104 #:use-module (srfi srfi-26)
105
106 #:export (customize-site
107 guix-pythonpath-search-path))
108
109 (define* (customize-site version)
110 "Generate a install-sitecustomize.py phase, using VERSION."
111 `(lambda* (#:key native-inputs inputs outputs #:allow-other-keys)
112 (let* ((out (assoc-ref outputs "out"))
113 (site-packages (string-append
114 out "/lib/python"
115 ,(version-major+minor version)
116 "/site-packages"))
117 (sitecustomize.py (assoc-ref (or native-inputs inputs)
118 "sitecustomize.py"))
119 (dest (string-append site-packages "/sitecustomize.py")))
120 (mkdir-p site-packages)
121 (copy-file sitecustomize.py dest)
122 ;; Set the correct permissions on the installed file, else the byte
123 ;; compilation phase fails with a permission denied error.
124 (chmod dest #o644))))
125
126 (define (guix-pythonpath-search-path version)
127 "Generate a GUIX_PYTHONPATH search path specification, using VERSION."
128 (search-path-specification (variable "GUIX_PYTHONPATH")
129 (files (list (string-append
130 "lib/python"
131 (version-major+minor version)
132 "/site-packages")))))
133
134 (define-public python-2.7
135 (package
136 (name "python2")
137 (version "2.7.18")
138 (source
139 (origin
140 (method url-fetch)
141 (uri (string-append "https://www.python.org/ftp/python/"
142 version "/Python-" version ".tar.xz"))
143 (sha256
144 (base32
145 "0hzgxl94hnflis0d6m4szjx0b52gah7wpmcg5g00q7am6xwhwb5n"))
146 (patches (search-patches "python-2.7-search-paths.patch"
147 "python-2-deterministic-build-info.patch"
148 "python-2.7-site-prefixes.patch"
149 "python-2.7-source-date-epoch.patch"
150 "python-2.7-adjust-tests.patch"
151 "python-cross-compile.patch"
152 "python-2.7-CVE-2021-3177.patch"
153 "python-2.7-no-static-lib.patch"))
154 (modules '((guix build utils)))
155 (snippet
156 '(begin
157 ;; Ensure the bundled copies of these libraries are not used.
158 (for-each delete-file-recursively
159 '("Modules/_ctypes/libffi" "Modules/expat" "Modules/zlib"))
160
161 (substitute* "Modules/Setup.dist"
162 ;; Link Expat instead of embedding the bundled one.
163 (("^#pyexpat.*") "pyexpat pyexpat.c -lexpat\n"))
164
165 ;; Suboptimal to delete failing tests here, but if we delete them in
166 ;; the arguments then we need to make sure to strip out that phase
167 ;; when it gets inherited by python and python-minimal.
168 (for-each delete-file
169 '("Lib/test/test_compileall.py"
170 "Lib/test/test_ctypes.py" ; fails on mips64el
171 "Lib/test/test_distutils.py"
172 "Lib/test/test_import.py"
173 "Lib/test/test_shutil.py"
174 "Lib/test/test_socket.py"
175 "Lib/test/test_subprocess.py"))))))
176 (outputs '("out"
177 "tk" ;tkinter; adds 50 MiB to the closure
178 "idle")) ;programming environment; weighs 5MB
179 (build-system gnu-build-system)
180 (arguments
181 `(#:test-target "test"
182 #:configure-flags
183 (list "--enable-shared" ;allow embedding
184 "--with-system-expat" ;for XML support
185 "--with-system-ffi" ;build ctypes
186 "--with-ensurepip=install" ;install pip and setuptools
187 "--with-computed-gotos" ;main interpreter loop optimization
188 "--enable-unicode=ucs4"
189
190 ;; FIXME: These flags makes Python significantly faster, but
191 ;; leads to non-reproducible binaries.
192 ;; "--with-lto" ;increase size by 20MB, but 15% speedup
193 ;; "--enable-optimizations"
194
195 ;; Prevent the installed _sysconfigdata.py from retaining a reference
196 ;; to coreutils.
197 "INSTALL=install -c"
198 "MKDIR_P=mkdir -p"
199
200 ;; Disable runtime check failing if cross-compiling, see:
201 ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
202 ,@(if (%current-target-system)
203 '("ac_cv_buggy_getaddrinfo=no"
204 "ac_cv_file__dev_ptmx=no"
205 "ac_cv_file__dev_ptc=no")
206 '())
207 ;; -fno-semantic-interposition reinstates some optimizations by gcc
208 ;; leading to around 15% speedup. This is the default starting from
209 ;; python 3.10.
210 "CFLAGS=-fno-semantic-interposition"
211 (string-append "LDFLAGS=-Wl,-rpath="
212 (assoc-ref %outputs "out") "/lib"
213 " -fno-semantic-interposition"))
214 ;; With no -j argument tests use all available cpus, so provide one.
215 #:make-flags
216 (list (string-append
217 (format #f "TESTOPTS=-j~d" (parallel-job-count))
218 ;; Exclude the following tests as they fail
219 ;; non-deterministically with "error: [Errno 104] Connection
220 ;; reset by peer." Python 3 seems unaffected. A potential fix,
221 ;; yet to be backported to Python 2, is available at:
222 ;; https://github.com/python/cpython/commit/529525fb5a8fd9b96ab4021311a598c77588b918.
223 " --exclude test_urllib2_localnet test_httplib"))
224
225 #:modules ((ice-9 ftw) (ice-9 match)
226 (guix build utils) (guix build gnu-build-system))
227 #:phases
228 (modify-phases %standard-phases
229 (add-before
230 'configure 'patch-lib-shells
231 (lambda _
232 ;; This variable is used in setup.py to enable cross compilation
233 ;; specific switches. As it is not set properly by configure
234 ;; script, set it manually.
235 ,@(if (%current-target-system)
236 '((setenv "_PYTHON_HOST_PLATFORM" ""))
237 '())
238 ;; Filter for existing files, since some may not exist in all
239 ;; versions of python that are built with this recipe.
240 (substitute* (filter file-exists?
241 '("Lib/subprocess.py"
242 "Lib/popen2.py"
243 "Lib/distutils/tests/test_spawn.py"
244 "Lib/test/support/__init__.py"
245 "Lib/test/test_subprocess.py"))
246 (("/bin/sh") (which "sh")))))
247 ,@(if (hurd-system?)
248 `((add-before 'build 'patch-regen-for-hurd
249 (lambda* (#:key inputs #:allow-other-keys)
250 (let ((libc (assoc-ref inputs "libc")))
251 (substitute* "Lib/plat-generic/regen"
252 (("/usr/include/") (string-append libc "/include/")))))))
253 '())
254 (add-before 'configure 'do-not-record-configure-flags
255 (lambda* (#:key configure-flags #:allow-other-keys)
256 ;; Remove configure flags from the installed '_sysconfigdata.py'
257 ;; and 'Makefile' so we don't end up keeping references to the
258 ;; build tools.
259 ;;
260 ;; Preserve at least '--with-system-ffi' since otherwise the
261 ;; thing tries to build libffi, fails, and we end up with a
262 ;; Python that lacks ctypes.
263 (substitute* "configure"
264 (("^CONFIG_ARGS=.*$")
265 (format #f "CONFIG_ARGS='~a'\n"
266 (if (member "--with-system-ffi" configure-flags)
267 "--with-system-ffi"
268 ""))))))
269 (add-before 'check 'pre-check
270 (lambda _
271 ;; 'Lib/test/test_site.py' needs a valid $HOME
272 (setenv "HOME" (getcwd))))
273 (add-after 'unpack 'set-source-file-times-to-1980
274 ;; XXX One of the tests uses a ZIP library to pack up some of the
275 ;; source tree, and fails with "ZIP does not support timestamps
276 ;; before 1980". Work around this by setting the file times in the
277 ;; source tree to sometime in early 1980.
278 (lambda _
279 (let ((circa-1980 (* 10 366 24 60 60)))
280 (ftw "." (lambda (file stat flag)
281 (utime file circa-1980 circa-1980)
282 #t)))))
283 (add-after 'install 'remove-tests
284 ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
285 ;; because these files are used by some libraries out there.
286 (lambda* (#:key outputs #:allow-other-keys)
287 (let ((out (assoc-ref outputs "out")))
288 (match (scandir (string-append out "/lib")
289 (lambda (name)
290 (string-prefix? "python" name)))
291 ((pythonX.Y)
292 (let ((testdir (string-append out "/lib/" pythonX.Y
293 "/test")))
294 (with-directory-excursion testdir
295 (for-each delete-file-recursively
296 (scandir testdir
297 (match-lambda
298 ((or "." "..") #f)
299 ("support" #f)
300 (file
301 (not
302 (string-prefix? "test_support."
303 file))))))
304 (call-with-output-file "__init__.py" (const #t))))
305 (let ((libdir (string-append out "/lib/" pythonX.Y)))
306 (for-each
307 (lambda (directory)
308 (let ((dir (string-append libdir "/" directory)))
309 (when (file-exists? dir)
310 (delete-file-recursively dir))))
311 '("email/test" "ctypes/test" "unittest/test" "tkinter/test"
312 "sqlite3/test" "bsddb/test" "lib-tk/test" "json/tests"
313 "distutils/tests"))))))))
314 (add-after 'remove-tests 'move-tk-inter
315 (lambda* (#:key outputs #:allow-other-keys)
316 ;; When Tkinter support is built move it to a separate output so
317 ;; that the main output doesn't contain a reference to Tcl/Tk.
318 (let ((out (assoc-ref outputs "out"))
319 (tk (assoc-ref outputs "tk")))
320 (when tk
321 (match (find-files out "tkinter.*\\.so")
322 ((tkinter.so)
323 ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
324 ;; want it under TK/lib/pythonX.Y/site-packages.
325 (let* ((len (string-length out))
326 (target (string-append
327 tk "/"
328 (string-drop
329 (dirname (dirname tkinter.so))
330 len)
331 "/site-packages")))
332 (install-file tkinter.so target)
333 (delete-file tkinter.so))))))))
334 (add-after 'move-tk-inter 'move-idle
335 (lambda* (#:key outputs #:allow-other-keys)
336 ;; when idle is built, move it to a separate output to save some
337 ;; space (5MB)
338 (let ((out (assoc-ref outputs "out"))
339 (idle (assoc-ref outputs "idle")))
340 (when idle
341 (for-each
342 (lambda (file)
343 (let ((target (string-append idle "/bin/" (basename file))))
344 (install-file file (dirname target))
345 (delete-file file)))
346 (find-files (string-append out "/bin") "^idle"))
347 (match (find-files out "^idlelib$" #:directories? #t)
348 ((idlelib)
349 (let* ((len (string-length out))
350 (target (string-append idle "/"
351 (string-drop idlelib len)
352 "/site-packages")))
353 (mkdir-p (dirname target))
354 (rename-file idlelib target))))))))
355 (add-after 'move-idle 'rebuild-bytecode
356 (lambda* (#:key outputs #:allow-other-keys)
357 (let ((out (assoc-ref outputs "out")))
358 ;; Disable hash randomization to ensure the generated .pycs
359 ;; are reproducible.
360 (setenv "PYTHONHASHSEED" "0")
361 (for-each
362 (lambda (output)
363 (for-each (lambda (opt)
364 (format #t "Compiling with optimization level: ~a\n"
365 (if (null? opt) "none" (car opt)))
366 (apply invoke
367 `(,,(if (%current-target-system)
368 "python2"
369 '(string-append out "/bin/python"))
370 ,@opt
371 "-m" "compileall"
372 "-f" ; force rebuild
373 ;; Don't build lib2to3, because it contains
374 ;; Python 3 code.
375 "-x" "lib2to3/.*"
376 ,output)))
377 ;; Python 2 has a single file extension (.pyo) for the
378 ;; chosen level of optimization, so it doesn't make
379 ;; sense to byte compile with more than one level.
380 (list '() '("-OO"))))
381 (map cdr outputs)))))
382 (add-after 'install 'install-sitecustomize.py
383 ,(customize-site version)))))
384 (inputs
385 (list bzip2
386 expat
387 gdbm
388 libffi ; for ctypes
389 sqlite ; for sqlite extension
390 openssl-1.1
391 readline
392 zlib
393 tcl
394 tk)) ; for tkinter
395 (native-inputs
396 `(("pkg-config" ,pkg-config)
397 ("sitecustomize.py" ,(local-file (search-auxiliary-file
398 "python/sitecustomize.py")))
399 ;; When cross-compiling, a native version of Python itself is needed.
400 ,@(if (%current-target-system)
401 `(("python2" ,this-package)
402 ("which" ,which))
403 '())))
404 (native-search-paths
405 (list (guix-pythonpath-search-path version)))
406 (home-page "https://www.python.org")
407 (synopsis "High-level, dynamically-typed programming language")
408 (description
409 "Python is a remarkably powerful dynamic programming language that
410 is used in a wide variety of application domains. Some of its key
411 distinguishing features include: clear, readable syntax; strong
412 introspection capabilities; intuitive object orientation; natural
413 expression of procedural code; full modularity, supporting hierarchical
414 packages; exception-based error handling; and very high level dynamic
415 data types.")
416 (properties '((cpe-name . "python")))
417 (license license:psfl)))
418
419 ;; Current 2.x version.
420 (define-public python-2 python-2.7)
421
422 (define-public python-3.9
423 (package
424 (inherit python-2)
425 (name "python")
426 (version "3.9.9")
427 (source (origin
428 (method url-fetch)
429 (uri (string-append "https://www.python.org/ftp/python/"
430 version "/Python-" version ".tar.xz"))
431 (patches (search-patches
432 "python-3-arm-alignment.patch"
433 "python-3-deterministic-build-info.patch"
434 "python-3-fix-tests.patch"
435 "python-3-hurd-configure.patch"
436 "python-3-search-paths.patch"
437 "python-3-no-static-lib.patch"))
438 (sha256
439 (base32
440 "09vd7g71i11iz5ydqghwc8kaxr0vgji94hhwwnj77h3kll28r0h6"))
441 (modules '((guix build utils)))
442 (snippet
443 '(begin
444 ;; Delete the bundled copy of libexpat.
445 (delete-file-recursively "Modules/expat")
446 (substitute* "Modules/Setup"
447 ;; Link Expat instead of embedding the bundled one.
448 (("^#pyexpat.*") "pyexpat pyexpat.c -lexpat\n"))
449 ;; Delete windows binaries
450 (for-each delete-file
451 (find-files "Lib/distutils/command" "\\.exe$"))))))
452 (arguments
453 (substitute-keyword-arguments (package-arguments python-2)
454 ((#:make-flags _)
455 `(list (string-append
456 (format #f "TESTOPTS=-j~d" (parallel-job-count))
457 ;; test_mmap fails on low-memory systems
458 " --exclude test_mmap test_socket"
459 ,@(if (hurd-target?)
460 '(" test_posix" ;multiple errors
461 " test_time"
462 " test_pty"
463 " test_shutil"
464 " test_tempfile" ;chflags: invalid argument:
465 ; tbv14c9t/dir0/dir0/dir0/test0.txt
466 " test_asyncio" ;runs over 10min
467 " test_os" ;stty: 'standard input':
468 ; Inappropriate ioctl for device
469 " test_openpty" ;No such file or directory
470 " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
471 ; 32752 != 4
472 " test_compileall" ;multiple errors
473 " test_poll" ;list index out of range
474 " test_subprocess" ;runs over 10min
475 " test_asyncore" ;multiple errors
476 " test_threadsignals"
477 " test_eintr" ;Process return code is -14
478 " test_io" ;multiple errors
479 " test_logging"
480 " test_signal"
481 " test_threading" ;runs over 10min
482 " test_flags" ;ERROR
483 " test_bidirectional_pty"
484 " test_create_unix_connection"
485 " test_unix_sock_client_ops"
486 " test_open_unix_connection"
487 " test_open_unix_connection_error"
488 " test_read_pty_output"
489 " test_write_pty")
490 '()))))
491 ((#:phases phases)
492 `(modify-phases ,phases
493 ,@(if (hurd-system?)
494 `((delete 'patch-regen-for-hurd)) ;regen was removed after 3.5.9
495 '())
496 (add-after 'unpack 'remove-windows-binaries
497 (lambda _
498 ;; Delete .exe from embedded .whl (zip) files
499 (for-each
500 (lambda (whl)
501 (let ((dir "whl-content")
502 (circa-1980 (* 10 366 24 60 60)))
503 (mkdir-p dir)
504 (with-directory-excursion dir
505 (let ((whl (string-append "../" whl)))
506 (invoke "unzip" whl)
507 (for-each delete-file
508 (find-files "." "\\.exe$"))
509 (delete-file whl)
510 ;; Reset timestamps to prevent them from ending
511 ;; up in the Zip archive.
512 (ftw "." (lambda (file stat flag)
513 (utime file circa-1980 circa-1980)
514 #t))
515 (apply invoke "zip" "-X" whl
516 (find-files "." #:directories? #t))))
517 (delete-file-recursively dir)))
518 (find-files "Lib/ensurepip" "\\.whl$"))))
519 (add-before 'check 'set-TZDIR
520 (lambda* (#:key inputs native-inputs #:allow-other-keys)
521 ;; test_email requires the Olson time zone database.
522 (setenv "TZDIR"
523 (string-append (assoc-ref
524 (or native-inputs inputs) "tzdata")
525 "/share/zoneinfo"))))
526 (replace 'rebuild-bytecode
527 (lambda* (#:key outputs #:allow-other-keys)
528 (let ((out (assoc-ref outputs "out")))
529 ;; Disable hash randomization to ensure the generated .pycs
530 ;; are reproducible.
531 (setenv "PYTHONHASHSEED" "0")
532
533 (for-each (lambda (output)
534 ;; XXX: Delete existing pycs generated by the build
535 ;; system beforehand because the -f argument does
536 ;; not necessarily overwrite all files, leading to
537 ;; indeterministic results.
538 (for-each (lambda (pyc)
539 (delete-file pyc))
540 (find-files output "\\.pyc$"))
541
542 (apply invoke
543 `(,,(if (%current-target-system)
544 "python3"
545 '(string-append out
546 "/bin/python3"))
547 "-m" "compileall"
548 "-o" "0" "-o" "1" "-o" "2"
549 "-f" ; force rebuild
550 "--invalidation-mode=unchecked-hash"
551 ;; Don't build lib2to3, because it's
552 ;; Python 2 code.
553 "-x" "lib2to3/.*"
554 ,output)))
555 (map cdr outputs)))))
556 (replace 'install-sitecustomize.py
557 ,(customize-site version))))))
558 (inputs
559 (modify-inputs (package-inputs python-2.7)
560 (replace "openssl" openssl)))
561 (native-inputs
562 `(("tzdata" ,tzdata-for-tests)
563 ("unzip" ,unzip)
564 ("zip" ,(@ (gnu packages compression) zip))
565 ,@(if (%current-target-system)
566 `(("python3" ,this-package))
567 '())
568 ,@(package-native-inputs python-2)))
569 (native-search-paths
570 (list (guix-pythonpath-search-path version)
571 ;; Used to locate tzdata by the zoneinfo module introduced in
572 ;; Python 3.9.
573 (search-path-specification
574 (variable "PYTHONTZPATH")
575 (files (list "share/zoneinfo")))))))
576
577 ;; Current 3.x version.
578 (define-public python-3 python-3.9)
579
580 ;; Current major version.
581 (define-public python python-3)
582
583 ;; Minimal variants of Python, mostly used to break the cycle between Tk and
584 ;; Python (Tk -> libxcb -> Python.)
585
586 (define-public python2-minimal
587 (package/inherit python-2
588 (name "python2-minimal")
589 (outputs '("out"))
590
591 ;; Keep zlib, which is used by 'pip' (via the 'zipimport' module), which
592 ;; is invoked upon 'make install'. 'pip' also expects 'ctypes' and thus
593 ;; libffi. Expat is needed for XML support which is expected by a lot
594 ;; of libraries out there.
595 (inputs `(("expat" ,expat)
596 ("libffi" ,libffi)
597 ("zlib" ,zlib)))))
598
599 (define-public python-minimal
600 (package/inherit python
601 (name "python-minimal")
602 (outputs '("out"))
603
604 ;; Build fails due to missing ctypes without libffi.
605 ;; OpenSSL is a mandatory dependency of Python 3.x, for urllib;
606 ;; zlib is required by 'zipimport', used by pip. Expat is needed
607 ;; for XML support, which is generally expected to be available.
608 (inputs `(("expat" ,expat)
609 ("libffi" ,libffi)
610 ("openssl" ,openssl)
611 ("zlib" ,zlib)))))
612
613 (define-public python-debug
614 (package/inherit python
615 (name "python-debug")
616 (outputs '("out" "debug"))
617 (build-system gnu-build-system)
618 (arguments
619 (substitute-keyword-arguments (package-arguments python)
620 ((#:configure-flags flags '())
621 `(cons "--with-pydebug" ,flags))))
622 (synopsis
623 "Python with the debug hooks enabled")
624 (description
625 "This variant of Python provides an interpreter built with
626 @code{--with-pydebug} to help develop and debug extensions. See
627 @url{https://pythonextensionpatterns.readthedocs.io/en/latest/debugging/debug.html},
628 for more information.")))
629
630 (define* (wrap-python3 python
631 #:optional
632 (name (string-append (package-name python) "-wrapper")))
633 (package/inherit python
634 (name name)
635 (source #f)
636 (build-system trivial-build-system)
637 (outputs '("out"))
638 (inputs `(("bash" ,bash)))
639 (propagated-inputs `(("python" ,python)))
640 (arguments
641 `(#:modules ((guix build utils))
642 #:builder
643 (begin
644 (use-modules (guix build utils))
645 (let ((bin (string-append (assoc-ref %outputs "out") "/bin"))
646 (python (string-append (assoc-ref %build-inputs "python") "/bin/")))
647 (mkdir-p bin)
648 (for-each
649 (lambda (old new)
650 (symlink (string-append python old)
651 (string-append bin "/" new)))
652 `("python3" ,"pydoc3" ,"pip3")
653 `("python" ,"pydoc" ,"pip"))
654 ;; python-config outputs search paths based upon its location,
655 ;; use a bash wrapper to avoid changing its outputs.
656 (let ((bash (string-append (assoc-ref %build-inputs "bash")
657 "/bin/bash"))
658 (old (string-append python "python3-config"))
659 (new (string-append bin "/python-config")))
660 (with-output-to-file new
661 (lambda ()
662 (format #t "#!~a~%" bash)
663 (format #t "exec \"~a\" \"$@\"~%" old)
664 (chmod new #o755))))))))
665 (synopsis "Wrapper for the Python 3 commands")
666 (description
667 "This package provides wrappers for the commands of Python@tie{}3.x such
668 that they can also be invoked under their usual names---e.g., @command{python}
669 instead of @command{python3} or @command{pip} instead of @command{pip3}.
670
671 To function properly, this package should not be installed together with the
672 @code{python} package: this package uses the @code{python} package as a
673 propagated input, so installing this package already makes both the versioned
674 and the unversioned commands available.")))
675
676 (define-public python-wrapper (wrap-python3 python))
677 (define-public python-minimal-wrapper (wrap-python3 python-minimal))
678
679 ;; The Python used in pyproject-build-system.
680 (define-public python-sans-pip
681 (hidden-package
682 (package/inherit python
683 (arguments
684 (substitute-keyword-arguments (package-arguments python)
685 ((#:configure-flags flags #~())
686 #~(append '("--with-ensurepip=no")
687 (delete "--with-ensurepip=install" #$flags))))))))
688
689 (define-public python-sans-pip-wrapper
690 (wrap-python3 python-sans-pip))
691
692 (define-public python-toolchain
693 (let ((base (package/inherit python-sans-pip-wrapper)))
694 (package
695 (inherit base)
696 (properties '())
697 (name "python-toolchain")
698 (propagated-inputs
699 (modify-inputs (package-propagated-inputs base)
700 (append python-pip
701 python-pypa-build
702 python-setuptools
703 python-wheel)))
704 (synopsis "Python toolchain")
705 (description
706 "Python toolchain including Python itself, setuptools and pip.
707 Use this package if you need a minimal Python toolchain instead of just
708 the interpreter."))))
709
710 (define-public micropython
711 (package
712 (name "micropython")
713 (version "1.19")
714 (source
715 (origin
716 (method url-fetch)
717 (uri (string-append "https://github.com/micropython/micropython/"
718 "releases/download/v" version
719 "/micropython-" version ".tar.xz"))
720 (sha256
721 (base32 "090bbls5vnicynjyjqqd5zqwx8d6zxp7wlnrxgh0b4s8cyf5i8zj"))
722 (modules '((guix build utils)))
723 (snippet
724 '(begin
725 (delete-file-recursively "ports/cc3200/FreeRTOS")
726 (with-directory-excursion "lib"
727 ;; TODO: Unbundle axtls and berkley-db-1.xx
728 (for-each delete-file-recursively
729 '("libffi" "lwip" "stm32lib" "nrfx")))))))
730 (build-system gnu-build-system)
731 (arguments
732 (list #:phases
733 #~(modify-phases %standard-phases
734 (add-before 'build 'build-mpy-cross
735 (lambda* (#:key make-flags #:allow-other-keys)
736 (with-directory-excursion "mpy-cross"
737 (apply invoke "make" make-flags))))
738 (add-after 'build-mpy-cross 'prepare-build
739 (lambda _
740 (chdir "ports/unix")
741 ;; see: https://github.com/micropython/micropython/pull/4246
742 (substitute* "Makefile"
743 (("-Os") "-Os -ffp-contract=off"))))
744 (add-before 'install-license-files 'chdir-back
745 ;; We don't build in the root directory so the file isn't found.
746 (lambda _
747 (chdir "../..")))
748 (delete 'configure)) ; no configure
749 #:make-flags
750 #~(list (string-append "PREFIX=" #$output)
751 "V=1")
752 #:test-target "test"))
753 (native-inputs (list pkg-config python-wrapper))
754 (inputs
755 (list libffi))
756 (home-page "https://micropython.org/")
757 (synopsis "Python implementation for microcontrollers and constrained systems")
758 (description "MicroPython is a lean and efficient implementation of the
759 Python 3 programming language that includes a small subset of the Python
760 standard library and is optimised to run on microcontrollers and in constrained
761 environments. MicroPython is packed full of advanced features such as an
762 interactive prompt, arbitrary precision integers, closures, list comprehension,
763 generators, exception handling and more. Still it is compact enough to fit and
764 run within just 256k of code space and 16k of RAM. MicroPython aims to be as
765 compatible with normal Python as possible to allow you to transfer code with
766 ease from the desktop to a microcontroller or embedded system.")
767 (license license:expat)))