diff mbox series

[bug#41472] gnu: Add pypy3.

Message ID 20200530165239.GA186839@noor.fritz.box
State Accepted
Headers show
Series [bug#41472] gnu: Add pypy3. | expand

Checks

Context Check Description
cbaines/comparison success View comparision
cbaines/git branch success View Git branch
cbaines/applying patch fail View Laminar job

Commit Message

Lars-Dominik Braun May 30, 2020, 4:52 p.m. UTC
Hi Ludo,

> > One thing I don’t like right now is the dependency on gcc-toolchain
> > (i.e. gcc and binutils) in distutils. I don’t know how to avoid that,
> > since building CFFI modules won’t work without patching.
> Is CFFI able to pick ‘gcc’ from $PATH?  If it can do it, we can avoid
> hardcoding the absolute file name of GCC and instead leave it up to the
> user to add GCC to their environment when they want to use CFFI.
yes, it is, but it looks for the executable "cc", which – oddly – our
gcc-toolchain does not provide. Is this intentional? The updated patch
replaces it with gcc, which seems to work.

> > I guess the next step would be figuring out how to add “pypy3-foo”
> > variants for our Python packages, right?
> Maybe.  Is it generally applicable?  I hear that many core Python
> packages require CPython, which makes it hard to migrate to a different
> implementation.
For plain Python packages it works pretty much out of the box. Afaik C
extensions are supported, but software making heavy use of those does
not benefit from PyPy’s JIT.

> The advice seems to be very general; did you mean that people should
> look for something specific in the build log, for example because test
> failures are silently ignored?
No, not really. Just to run the disabled test suite and see if it goes
from “a few failures” to “everything is broken now”. I could selectively
patch the testsuite to disable currently failing tests, but I’m not
competent enough to judge which one can be skipped safely (due to
sandboxing limitations for example) and which indicate an actual
failure. I’ll remove the comment.

> I’d suggest ‘bash-minimal’ here, to be consistent with the other
> packages.
Done, actually `guix size dash` includes bash-minimal…

> Maybe “Python implementation with just-in-time compilation”?
Sounds good, done.

> Maybe remove “3.6” since it’s likely to become stale.  Bonus points if
> you can expound a little bit.  :-)
I copy-edited a paragraph from Wikipedia. Hope that’s acceptable.

Additionally I removed some test data from the output, which is not
required at runtime and removed python2 from the closure by patching a
few shebangs.

Cheers,
Lars
diff mbox series

Patch

From 1c4f594f89baf6fce3cd5e02a8f7ffd836bc3bc2 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Fri, 22 May 2020 16:02:26 +0200
Subject: [PATCH] gnu: Add pypy3.

* gnu/packages/python.scm (pypy3): New public variable.
* gnu/packages/patches/pypy3-7.3.1-fix-tests.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it
---
 gnu/local.mk                                  |   1 +
 .../patches/pypy3-7.3.1-fix-tests.patch       | 278 ++++++++++++++++++
 gnu/packages/python.scm                       | 172 +++++++++++
 3 files changed, 451 insertions(+)
 create mode 100644 gnu/packages/patches/pypy3-7.3.1-fix-tests.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 91f094ce0f..2407825cd4 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1440,6 +1440,7 @@  dist_patch_DATA =						\
   %D%/packages/patches/python-unittest2-python3-compat.patch	\
   %D%/packages/patches/python-unittest2-remove-argparse.patch	\
   %D%/packages/patches/python-waitress-fix-tests.patch		\
+  %D%/packages/patches/pypy3-7.3.1-fix-tests.patch		\
   %D%/packages/patches/qemu-glibc-2.27.patch 			\
   %D%/packages/patches/qrcodegen-cpp-make-install.patch		\
   %D%/packages/patches/qt4-ldflags.patch			\
diff --git a/gnu/packages/patches/pypy3-7.3.1-fix-tests.patch b/gnu/packages/patches/pypy3-7.3.1-fix-tests.patch
new file mode 100644
index 0000000000..464aad967f
--- /dev/null
+++ b/gnu/packages/patches/pypy3-7.3.1-fix-tests.patch
@@ -0,0 +1,278 @@ 
+Fix a few testcases. Adapted from python-3-fix-tests.patch.
+
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/ctypes/test/test_callbacks.py pypy3.6-v7.3.1-src/lib-python/3/ctypes/test/test_callbacks.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/ctypes/test/test_callbacks.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/ctypes/test/test_callbacks.py	2020-05-21 14:19:14.827288853 +0200
+@@ -4,6 +4,7 @@
+ from ctypes import *
+ from ctypes.test import need_symbol
+ import _ctypes_test
++import platform
+ 
+ class Callbacks(unittest.TestCase):
+     functype = CFUNCTYPE
+@@ -178,6 +179,8 @@
+ 
+         self.assertLess(diff, 0.01, "%s not less than 0.01" % diff)
+ 
++    @unittest.skipIf(platform.machine() in ['mips64'],
++                     "This test fails on this platform")
+     def test_issue_8959_a(self):
+         from ctypes.util import find_library
+         libc_path = find_library("c")
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/ctypes/test/test_libc.py pypy3.6-v7.3.1-src/lib-python/3/ctypes/test/test_libc.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/ctypes/test/test_libc.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/ctypes/test/test_libc.py	2020-05-21 14:19:14.827288853 +0200
+@@ -2,6 +2,7 @@
+ 
+ from ctypes import *
+ import _ctypes_test
++import platform
+ 
+ lib = CDLL(_ctypes_test.__file__)
+ 
+@@ -17,6 +18,8 @@
+         import math
+         self.assertEqual(lib.my_sqrt(2.0), math.sqrt(2.0))
+ 
++    @unittest.skipIf(platform.machine() in ['mips64'],
++                     "This test fails on this platform")
+     def test_qsort(self):
+         comparefunc = CFUNCTYPE(c_int, POINTER(c_char), POINTER(c_char))
+         lib.my_qsort.argtypes = c_void_p, c_size_t, c_size_t, comparefunc
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/distutils/tests/test_archive_util.py pypy3.6-v7.3.1-src/lib-python/3/distutils/tests/test_archive_util.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/distutils/tests/test_archive_util.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/distutils/tests/test_archive_util.py	2020-05-21 14:19:14.827288853 +0200
+@@ -333,6 +333,7 @@
+         self.assertEqual(os.path.basename(res), 'archive.tar.xz')
+         self.assertEqual(self._tarinfo(res), self._created_files)
+ 
++    @unittest.skipIf(True, "getgrgid(0)[0] raises a KeyError on Guix")
+     def test_make_archive_owner_group(self):
+         # testing make_archive with owner and group, with various combinations
+         # this works even if there's not gid/uid support
+@@ -362,6 +363,7 @@
+ 
+     @unittest.skipUnless(ZLIB_SUPPORT, "Requires zlib")
+     @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
++    @unittest.skipIf(True, "getgrgid(0)[0] raises a KeyError on Guix")
+     def test_tarfile_root_owner(self):
+         tmpdir =  self._create_files()
+         base_name = os.path.join(self.mkdtemp(), 'archive')
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/distutils/tests/test_sdist.py pypy3.6-v7.3.1-src/lib-python/3/distutils/tests/test_sdist.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/distutils/tests/test_sdist.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/distutils/tests/test_sdist.py	2020-05-21 14:19:14.827288853 +0200
+@@ -443,6 +443,7 @@
+                      "The tar command is not found")
+     @unittest.skipIf(find_executable('gzip') is None,
+                      "The gzip command is not found")
++    @unittest.skipIf(True, "getgrgid(0)[0] raises a KeyError on Guix")
+     def test_make_distribution_owner_group(self):
+         # now building a sdist
+         dist, cmd = self.get_cmd()
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_asyncio/test_base_events.py pypy3.6-v7.3.1-src/lib-python/3/test/test_asyncio/test_base_events.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_asyncio/test_base_events.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/test/test_asyncio/test_base_events.py	2020-05-21 14:19:14.827288853 +0200
+@@ -1296,6 +1296,8 @@
+         self._test_create_connection_ip_addr(m_socket, False)
+ 
+     @patch_socket
++    @unittest.skipUnless(support.is_resource_enabled('network'),
++                         'network is not enabled')
+     def test_create_connection_service_name(self, m_socket):
+         m_socket.getaddrinfo = socket.getaddrinfo
+         sock = m_socket.socket.return_value
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_generators.py pypy3.6-v7.3.1-src/lib-python/3/test/test_generators.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_generators.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/test/test_generators.py	2020-05-21 14:19:14.827288853 +0200
+@@ -35,6 +35,7 @@
+         else:
+             return "FAILED"
+ 
++    @unittest.skipIf(True, 'Keyboard interrupts do not work in the Guix build environment')
+     def test_raise_and_yield_from(self):
+         gen = self.generator1()
+         gen.send(None)
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/test/_test_multiprocessing.py pypy3.6-v7.3.1-src/lib-python/3/test/_test_multiprocessing.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/test/_test_multiprocessing.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/test/_test_multiprocessing.py	2020-05-21 14:19:14.827288853 +0200
+@@ -1212,6 +1212,7 @@
+         if pid is not None:
+             os.kill(pid, signal.SIGINT)
+ 
++    @unittest.skipIf(True, "This fails for unknown reasons on Guix")
+     def test_wait_result(self):
+         if isinstance(self, ProcessesMixin) and sys.platform != 'win32':
+             pid = os.getpid()
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_normalization.py pypy3.6-v7.3.1-src/lib-python/3/test/test_normalization.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_normalization.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/test/test_normalization.py	2020-05-21 14:19:14.827288853 +0200
+@@ -2,6 +2,7 @@
+ import unittest
+ 
+ from http.client import HTTPException
++from urllib.error import URLError
+ import sys
+ from unicodedata import normalize, unidata_version
+ 
+@@ -43,6 +44,8 @@
+         except PermissionError:
+             self.skipTest(f"Permission error when downloading {TESTDATAURL} "
+                           f"into the test data directory")
++        except URLError:
++            self.skipTest("DNS lookups are not enabled.")
+         except (OSError, HTTPException):
+             self.fail(f"Could not retrieve {TESTDATAURL}")
+ 
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_pathlib.py pypy3.6-v7.3.1-src/lib-python/3/test/test_pathlib.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_pathlib.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/test/test_pathlib.py	2020-05-21 14:19:14.827288853 +0200
+@@ -2130,8 +2130,7 @@
+         self.assertEqual(given, expect)
+         self.assertEqual(set(p.rglob("FILEd*")), set())
+ 
+-    @unittest.skipUnless(hasattr(pwd, 'getpwall'),
+-                         'pwd module does not expose getpwall()')
++    @unittest.skipIf(True, "Guix builder home is '/' which causes trouble for these tests")
+     def test_expanduser(self):
+         P = self.cls
+         support.import_module('pwd')
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_pdb.py pypy3.6-v7.3.1-src/lib-python/3/test/test_pdb.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_pdb.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/test/test_pdb.py	2020-05-21 14:20:24.377203281 +0200
+@@ -1136,11 +1136,11 @@
+     > <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
+     -> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
+     (Pdb) continue
+-    pdb 1: <built-in function default_int_handler>
++    pdb 1: Handlers.SIG_IGN
+     > <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
+     -> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
+     (Pdb) continue
+-    pdb 2: <built-in function default_int_handler>
++    pdb 2: Handlers.SIG_IGN
+     """
+ 
+ class PdbTestCase(unittest.TestCase):
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_regrtest.py pypy3.6-v7.3.1-src/lib-python/3/test/test_regrtest.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_regrtest.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/test/test_regrtest.py	2020-05-21 14:19:14.827288853 +0200
+@@ -766,6 +766,7 @@
+         output = self.run_tests('--fromfile', filename)
+         self.check_executed_tests(output, tests)
+ 
++    @unittest.skipIf(True, 'Keyboard interrupts do not work in the Guix build environment.')
+     def test_interrupted(self):
+         code = TEST_INTERRUPTED
+         test = self.create_test('sigint', code=code)
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_resource.py pypy3.6-v7.3.1-src/lib-python/3/test/test_resource.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_resource.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/test/test_resource.py	2020-05-21 14:19:14.827288853 +0200
+@@ -146,6 +146,7 @@
+ 
+     @unittest.skipUnless(hasattr(resource, 'prlimit'), 'no prlimit')
+     @support.requires_linux_version(2, 6, 36)
++    @unittest.skipIf(True, "Bug: the PermissionError is not raised")
+     def test_prlimit(self):
+         self.assertRaises(TypeError, resource.prlimit)
+         self.assertRaises(ProcessLookupError, resource.prlimit,
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_shutil.py pypy3.6-v7.3.1-src/lib-python/3/test/test_shutil.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_shutil.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/test/test_shutil.py	2020-05-21 14:19:14.827288853 +0200
+@@ -1138,6 +1138,7 @@
+         self.assertRaises(ValueError, make_archive, base_name, 'xxx')
+ 
+     @support.requires_zlib
++    @unittest.skipIf(True, "getgrgid(0)[0] raises a KeyError on Guix")
+     def test_make_archive_owner_group(self):
+         # testing make_archive with owner and group, with various combinations
+         # this works even if there's not gid/uid support
+@@ -1166,6 +1167,7 @@
+ 
+ 
+     @support.requires_zlib
++    @unittest.skipIf(True, "getgrgid(0)[0] raises a KeyError on Guix")
+     @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
+     def test_tarfile_root_owner(self):
+         root_dir, base_dir = self._create_files()
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_socket.py pypy3.6-v7.3.1-src/lib-python/3/test/test_socket.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_socket.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/test/test_socket.py	2020-05-21 14:19:14.827288853 +0200
+@@ -815,6 +815,8 @@
+         if not fqhn in all_host_names:
+             self.fail("Error testing host resolution mechanisms. (fqdn: %s, all: %s)" % (fqhn, repr(all_host_names)))
+ 
++    @unittest.skipUnless(support.is_resource_enabled('network'),
++                         'network is not enabled')
+     def test_host_resolution(self):
+         for addr in [support.HOST, '10.0.0.1', '255.255.255.255']:
+             self.assertEqual(socket.gethostbyname(addr), addr)
+@@ -934,6 +936,8 @@
+             self.assertRaises(OverflowError, socket.htonl, k)
+             self.assertRaises(OverflowError, socket.htons, k)
+ 
++    @unittest.skipUnless(os.path.exists("/etc/services"),
++                         "getservbyname uses /etc/services, which is not in the chroot")
+     def testGetServBy(self):
+         eq = self.assertEqual
+         # Find one service that exists, then check all the related interfaces.
+@@ -1278,6 +1282,8 @@
+             raise
+         self.assertRaises(TypeError, s.ioctl, socket.SIO_LOOPBACK_FAST_PATH, None)
+ 
++    @unittest.skipUnless(os.path.exists("/etc/gai.conf"),
++                         "getaddrinfo() will fail")
+     def testGetaddrinfo(self):
+         try:
+             socket.getaddrinfo('localhost', 80)
+@@ -1357,6 +1363,8 @@
+         # only IP addresses are allowed
+         self.assertRaises(OSError, socket.getnameinfo, ('mail.python.org',0), 0)
+ 
++    @unittest.skipUnless(os.path.exists("/etc/gai.conf"),
++                         "getaddrinfo() will fail")
+     @unittest.skipUnless(support.is_resource_enabled('network'),
+                          'network is not enabled')
+     def test_idna(self):
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_spwd.py pypy3.6-v7.3.1-src/lib-python/3/test/test_spwd.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_spwd.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/test/test_spwd.py	2020-05-21 14:19:14.827288853 +0200
+@@ -5,8 +5,7 @@
+ spwd = support.import_module('spwd')
+ 
+ 
+-@unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0,
+-                     'root privileges required')
++@unittest.skipUnless(os.path.exists("/etc/shadow"), 'spwd tests require /etc/shadow')
+ class TestSpwdRoot(unittest.TestCase):
+ 
+     def test_getspall(self):
+@@ -56,8 +55,7 @@
+             self.assertRaises(TypeError, spwd.getspnam, bytes_name)
+ 
+ 
+-@unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() != 0,
+-                     'non-root user required')
++@unittest.skipUnless(os.path.exists("/etc/shadow"), 'spwd tests require /etc/shadow')
+ class TestSpwdNonRoot(unittest.TestCase):
+ 
+     def test_getspnam_exception(self):
+diff -Naur pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_tarfile.py pypy3.6-v7.3.1-src/lib-python/3/test/test_tarfile.py
+--- pypy3.6-v7.3.1-src.orig/lib-python/3/test/test_tarfile.py	1970-01-01 01:00:01.000000000 +0100
++++ pypy3.6-v7.3.1-src/lib-python/3/test/test_tarfile.py	2020-05-21 14:19:14.827288853 +0200
+@@ -2491,9 +2491,12 @@
+         import pwd, grp
+     except ImportError:
+         return False
+-    if pwd.getpwuid(0)[0] != 'root':
+-        return False
+-    if grp.getgrgid(0)[0] != 'root':
++    try:
++        if pwd.getpwuid(0)[0] != 'root':
++            return False
++        if grp.getgrgid(0)[0] != 'root':
++            return False
++    except KeyError:
+         return False
+     return True
+ 
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 1ec002df73..b399931a42 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -80,12 +80,17 @@ 
   #:use-module (gnu packages)
   #:use-module (gnu packages base)
   #:use-module (gnu packages bash)
+  #:use-module (gnu packages certs)
+  #:use-module (gnu packages check)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages dbm)
   #:use-module (gnu packages hurd)
   #:use-module (gnu packages libffi)
+  #:use-module (gnu packages ncurses)
   #:use-module (gnu packages pkg-config)
+  #:use-module (gnu packages python-xyz)
   #:use-module (gnu packages readline)
+  #:use-module (gnu packages shells)
   #:use-module (gnu packages sqlite)
   #:use-module (gnu packages tcl)
   #:use-module (gnu packages tls)
@@ -631,3 +636,170 @@  run within just 256k of code space and 16k of RAM.  MicroPython aims to be as
 compatible with normal Python as possible to allow you to transfer code with
 ease from the desktop to a microcontroller or embedded system.")
     (license license:expat)))
+
+(define-public pypy3
+  (package
+    (name "pypy3")
+    (version "7.3.1")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "https://bitbucket.org/pypy/pypy/downloads/" ;
+                                  "pypy3.6-v" version "-src.tar.bz2"))
+              (sha256
+               (base32
+                "10zsk8jby8j6visk5mzikpb1cidvz27qq4pfpa26jv53klic6b0c"))
+              (patches (search-patches "pypy3-7.3.1-fix-tests.patch"))))
+    (build-system gnu-build-system)
+    (native-inputs
+     `(("python-2" ,python-2)
+       ("pkg-config" ,pkg-config)
+       ("tar" ,tar)                     ; Required for package.py
+       ("python2-pycparser" ,python2-pycparser)
+       ("python2-hypothesis" ,python2-hypothesis)
+       ("nss-certs" ,nss-certs)         ; For ssl tests
+       ("gzip" ,gzip)))
+    (inputs
+     `(("libffi" ,libffi)
+       ("zlib" ,zlib)
+       ("ncurses" ,ncurses)
+       ("openssl" ,openssl)
+       ("expat" ,expat)
+       ("bzip2" ,bzip2)
+       ("sqlite" ,sqlite)
+       ("gdbm" ,gdbm)
+       ("tcl" ,tcl)
+       ("tk" ,tk)
+       ("glibc" ,glibc)
+       ("bash-minimal" ,bash-minimal)   ; Used as /bin/sh
+       ("xz" ,xz)))                     ; liblzma
+    (arguments
+     `(#:tests? #f ; Disabled for now, there are simply too many unfixable tests failing
+       #:modules ((ice-9 ftw) (ice-9 match)
+                  (guix build utils) (guix build gnu-build-system))
+       #:phases (modify-phases %standard-phases
+                  (delete 'configure)
+                  (add-after 'unpack 'patch-source
+                    (lambda* (#:key inputs outputs #:allow-other-keys)
+                      (substitute* '("rpython/rlib/clibffi.py")
+                        ;; find_library does not work for libc
+                        (("ctypes\\.util\\.find_library\\('c'\\)") "'libc.so'"))
+                      (substitute* '("lib_pypy/cffi/_pycparser/ply/cpp.py")
+                        ;; Make reproducible (XXX: unused?)
+                        (("time\\.localtime\\(\\)") "time.gmtime(0)"))
+                      (substitute* '("pypy/module/sys/version.py")
+                        ;; Make reproducible
+                        (("t\\.gmtime\\(\\)") "t.gmtime(0)"))
+                      (substitute* '("lib_pypy/_tkinter/tklib_build.py")
+                        ;; Link to versioned libtcl and libtk
+                        (("linklibs = \\['tcl', 'tk'\\]")
+                         "linklibs = ['tcl8.6', 'tk8.6']")
+                        (("incdirs = \\[\\]")
+                         (string-append "incdirs = ['"
+                                        (assoc-ref inputs "tcl")
+                                        "/include', '"
+                                        (assoc-ref inputs "tk")
+                                        "/include']")))
+                      (substitute* '("lib_pypy/_curses_build.py")
+                        ;; Find curses
+                        (("/usr/local") (assoc-ref inputs "ncurses")))
+                      (substitute* '("lib_pypy/_sqlite3_build.py")
+                        ;; Always use search paths
+                        (("sys\\.platform\\.startswith\\('freebsd'\\)") "True")
+                        ;; Find sqlite3
+                        (("/usr/local") (assoc-ref inputs "sqlite"))
+                        (("libname = 'sqlite3'")
+                         (string-append "libname = '"
+                                        (assoc-ref inputs "sqlite")
+                                        "/lib/libsqlite3.so.0'")))
+                      (substitute* '("lib-python/3/subprocess.py")
+                        ;; Fix shell path
+                        (("/bin/sh")
+                         (string-append (assoc-ref inputs "bash-minimal") "/bin/sh")))
+                      (substitute* '("lib-python/3/distutils/unixccompiler.py")
+                        ;; gcc-toolchain does not provide symlink cc -> gcc
+                        (("\"cc\"") "\"gcc\""))
+                      #t))
+                  (add-after
+                      'unpack 'set-source-file-times-to-1980
+                    ;; copied from python package, required by zip testcase
+                    (lambda _
+                      (let ((circa-1980 (* 10 366 24 60 60)))
+                        (ftw "." (lambda (file stat flag)
+                                   (utime file circa-1980 circa-1980)
+                                   #t))
+                        #t)))
+                  (replace 'build
+                    (lambda* (#:key inputs #:allow-other-keys)
+                      (with-directory-excursion "pypy/goal"
+                        ;; Build with jit optimization.
+                        (invoke "python2"
+                                "../../rpython/bin/rpython"
+                                (string-append "--make-jobs="
+                                               (number->string (parallel-job-count)))
+                                "-Ojit"
+                                "targetpypystandalone"))
+                      ;; Build c modules and package everything, so tests work.
+                      (with-directory-excursion "pypy/tool/release"
+                        (unsetenv "PYTHONPATH") ; Do not use the system’s python libs:
+                                        ; AttributeError: module 'enum' has no
+                                        ; attribute 'IntFlag'
+                        (invoke "python2" "package.py"
+                                "--archive-name" "pypy-dist"
+                                "--builddir" (getcwd)))))
+                  (replace 'check
+                    (lambda* (#:key tests? #:allow-other-keys)
+                      (if tests?
+                          (begin
+                            (setenv "HOME" "/tmp") ; test_with_pip tries to
+                                        ; access ~/.cache/pip
+                            ;; Run library tests only (no interpreter unit
+                            ;; tests). This is what Gentoo does.
+                            (invoke
+                             "python2"
+                             "pypy/test_all.py"
+                             "--pypy=pypy/tool/release/pypy-dist/bin/pypy3"
+                             "lib-python"))
+                          (format #t "test suite not run~%"))
+                      #t))
+                  (replace 'install
+                    (lambda* (#:key inputs outputs #:allow-other-keys)
+                      (with-directory-excursion "pypy/tool/release"
+                        ;; Delete test data.
+                        (for-each
+                         (lambda (x)
+                           (delete-file-recursively (string-append
+                                                     "pypy-dist/lib-python/3/" x)))
+                         '("tkinter/test"
+                           "test"
+                           "sqlite3/test"
+                           "lib2to3/tests"
+                           "idlelib/idle_test"
+                           "distutils/tests"
+                           "ctypes/test"
+                           "unittest/test"))
+                        ;; Patch shebang referencing python2
+                        (substitute* '("pypy-dist/lib-python/3/cgi.py"
+                                       "pypy-dist/lib-python/3/encodings/rot_13.py")
+                          (("#!.+/bin/python")
+                           (string-append "#!" (assoc-ref outputs "out") "/bin/pypy3")))
+                        (with-fluids
+                         ((%default-port-encoding "ISO-8859-1"))
+                         (substitute*
+                             '("pypy-dist/lib_pypy/_md5.py" "pypy-dist/lib_pypy/_sha1.py")
+                           (("#!.+/bin/python")
+                            (string-append "#!" (assoc-ref outputs "out") "/bin/pypy3"))))
+                        (copy-recursively "pypy-dist" (assoc-ref outputs "out")))
+                      #t)))))
+    (home-page "https://www.pypy.org/")
+    (synopsis "Python implementation with just-in-time compilation")
+    (description "PyPy is a faster, alternative implementation of the Python
+programming language employing a just-in-time compiler.  Supports most Python
+code natively, including C extensions.")
+    (license (list license:expat        ; pypy itself; _pytest/
+                   license:psfl ; python standard library in lib-python/
+                   license:asl2.0 ; dotviewer/font/ and some of lib-python/
+                   license:gpl3+ ; ./rpython/rlib/rvmprof/src/shared/libbacktrace/dwarf2.*
+                   license:bsd-3 ; lib_pypy/cffi/_pycparser/ply/
+                   (license:non-copyleft
+                    "http://www.unicode.org/copyright.html")))))
+
-- 
2.26.2