unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* [bug#41472] [PATCH] gnu: Add pypy3.
@ 2020-05-23  6:56 Lars-Dominik Braun
  2020-05-29 16:00 ` Ludovic Courtès
  0 siblings, 1 reply; 4+ messages in thread
From: Lars-Dominik Braun @ 2020-05-23  6:56 UTC (permalink / raw)
  To: 41472

[-- Attachment #1: Type: text/plain, Size: 797 bytes --]

Hi,

the attached patch adds pypy3, a Python 3 JIT. As you can see this is a
lot of work, because pypy’s build system is rather unconventional.  I’m
not adding pypy2, because Python 2 is essentially EOL.

I’ve tried fixing as many testcases as possible, but there are some I
don’t know how to fix. Thus I’m disabling the test suite, although
everything is in place to run it. pypy itself works fine though, the
build is reproducible and passes `guix lint`.

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.

I guess the next step would be figuring out how to add “pypy3-foo”
variants for our Python packages, right?

Cheers,
Lars


[-- Attachment #2: 0001-gnu-Add-pypy3.patch --]
[-- Type: text/x-diff, Size: 25039 bytes --]

From bdf71850523b42e9d710618d0e0d9ea9fbfe9f87 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                       | 157 ++++++++++
 3 files changed, 436 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..5300c345d4 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,155 @@ 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")
+    ;; if you intend to upgrade this package, enable the tests and check
+    ;; the results for anything abnormal
+    (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)
+       ("dash" ,dash)                   ; 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 "dash") "/bin/dash")))
+                      ;; this does not look like a good idea, since it depends
+                      ;; on the gcc toolchain, on the other hand cffi modules
+                      ;; will not be built without this
+                      (substitute* '("lib-python/3/distutils/unixccompiler.py")
+                        (("\"cc\"")
+                         (string-append "\"" (assoc-ref inputs "gcc")
+                                        "/bin/gcc\""))
+                        (("\"c\\+\\+\"")
+                         (string-append "\"" (assoc-ref inputs "gcc")
+                                        "/bin/g++\""))
+                        (("\"ar\"")
+                         (string-append "\"" (assoc-ref inputs "binutils")
+                                        "/bin/ar\"")))
+                      #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"
+                        (copy-recursively "pypy-dist" (assoc-ref outputs "out")))
+                      #t)))))
+    (home-page "https://www.pypy.org/")
+    (synopsis "Python 3.6 JIT")
+    (description "This package provides a Python 3.6 just-in-time compiler.")
+    (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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [bug#41472] [PATCH] gnu: Add pypy3.
  2020-05-23  6:56 [bug#41472] [PATCH] gnu: Add pypy3 Lars-Dominik Braun
@ 2020-05-29 16:00 ` Ludovic Courtès
  2020-05-30 16:52   ` Lars-Dominik Braun
  0 siblings, 1 reply; 4+ messages in thread
From: Ludovic Courtès @ 2020-05-29 16:00 UTC (permalink / raw)
  To: Lars-Dominik Braun; +Cc: 41472

Hi,

Lars-Dominik Braun <lars@6xq.net> skribis:

> the attached patch adds pypy3, a Python 3 JIT. As you can see this is a
> lot of work, because pypy’s build system is rather unconventional.  I’m
> not adding pypy2, because Python 2 is essentially EOL.
>
> I’ve tried fixing as many testcases as possible, but there are some I
> don’t know how to fix. Thus I’m disabling the test suite, although
> everything is in place to run it. pypy itself works fine though, the
> build is reproducible and passes `guix lint`.

Yay!

> 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.

> 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.

>>From bdf71850523b42e9d710618d0e0d9ea9fbfe9f87 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

[...]

> +(define-public pypy3
> +  (package
> +    (name "pypy3")
> +    ;; if you intend to upgrade this package, enable the tests and check
> +    ;; the results for anything abnormal

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?

Nitpick: please use uppercase at the beginning and period at the end.


[...]

> +       ("dash" ,dash)                   ; used as /bin/sh

I’d suggest ‘bash-minimal’ here, to be consistent with the other
packages.


[...]

> +    (home-page "https://www.pypy.org/")
> +    (synopsis "Python 3.6 JIT")

Maybe “Python implementation with just-in-time compilation”?

> +    (description "This package provides a Python 3.6 just-in-time compiler.")

Maybe remove “3.6” since it’s likely to become stale.  Bonus points if
you can expound a little bit.  :-)

Thanks!

Ludo’.




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [bug#41472] [PATCH] gnu: Add pypy3.
  2020-05-29 16:00 ` Ludovic Courtès
@ 2020-05-30 16:52   ` Lars-Dominik Braun
  2020-05-31 22:46     ` bug#41472: " Ludovic Courtès
  0 siblings, 1 reply; 4+ messages in thread
From: Lars-Dominik Braun @ 2020-05-30 16:52 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 41472

[-- Attachment #1: Type: text/plain, Size: 2232 bytes --]

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


[-- Attachment #2: 0001-gnu-Add-pypy3.patch --]
[-- Type: text/x-diff, Size: 25852 bytes --]

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


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* bug#41472: [PATCH] gnu: Add pypy3.
  2020-05-30 16:52   ` Lars-Dominik Braun
@ 2020-05-31 22:46     ` Ludovic Courtès
  0 siblings, 0 replies; 4+ messages in thread
From: Ludovic Courtès @ 2020-05-31 22:46 UTC (permalink / raw)
  To: Lars-Dominik Braun; +Cc: 41472-done

[-- Attachment #1: Type: text/plain, Size: 1501 bytes --]

Hi,

Lars-Dominik Braun <lars@6xq.net> skribis:

>> > 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?

Yes: as discussed elsewhere, GCC does not provide ‘cc’, and we don’t
provide it either.

> The updated patch replaces it with gcc, which seems to work.

Perfect.

>> 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.

OK.

Alright.  I took the liberty to make the changes below and committed.

Thanks!

Ludo’.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 2519 bytes --]

diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index b399931a42..9469f89bcf 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -673,7 +673,7 @@ ease from the desktop to a microcontroller or embedded system.")
        ("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
+     `(#:tests? #f     ;FIXME: Disabled for now, there are many tests failing.
        #:modules ((ice-9 ftw) (ice-9 match)
                   (guix build utils) (guix build gnu-build-system))
        #:phases (modify-phases %standard-phases
@@ -782,19 +782,18 @@ ease from the desktop to a microcontroller or embedded system.")
                                        "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"))))
+                        (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.")
+programming language employing a just-in-time compiler.  It 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/

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-05-31 22:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-23  6:56 [bug#41472] [PATCH] gnu: Add pypy3 Lars-Dominik Braun
2020-05-29 16:00 ` Ludovic Courtès
2020-05-30 16:52   ` Lars-Dominik Braun
2020-05-31 22:46     ` bug#41472: " Ludovic Courtès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).