~ruther/guix-local

eda8a841ac7457ffe05c4a4248d6dff074b72326 — Efraim Flashner 8 years ago b7883b1 + 49c620e
Merge remote-tracking branch 'origin/python-updates' into core-updates
M gnu/local.mk => gnu/local.mk +4 -4
@@ 958,14 958,13 @@ dist_patch_DATA =						\
  %D%/packages/patches/pygpgme-disable-problematic-tests.patch  \
  %D%/packages/patches/pyqt-configure.patch			\
  %D%/packages/patches/python-2-deterministic-build-info.patch	\
  %D%/packages/patches/python-2.7-getentropy-on-old-kernels.patch	\
  %D%/packages/patches/python-2.7-adjust-tests.patch		\
  %D%/packages/patches/python-2.7-search-paths.patch		\
  %D%/packages/patches/python-2.7-site-prefixes.patch		\
  %D%/packages/patches/python-2.7-source-date-epoch.patch	\
  %D%/packages/patches/python-3-deterministic-build-info.patch	\
  %D%/packages/patches/python-3-search-paths.patch		\
  %D%/packages/patches/python-3.5-fix-tests.patch		\
  %D%/packages/patches/python-3.5-getentropy-on-old-kernels.patch	\
  %D%/packages/patches/python-3-fix-tests.patch			\
  %D%/packages/patches/python-dendropy-fix-tests.patch		\
  %D%/packages/patches/python-fix-tests.patch			\
  %D%/packages/patches/python-genshi-add-support-for-python-3.4-AST.patch	\


@@ 990,7 989,8 @@ dist_patch_DATA =						\
  %D%/packages/patches/python2-pygobject-2-gi-info-type-error-domain.patch \
  %D%/packages/patches/python-pygpgme-fix-pinentry-tests.patch	\
  %D%/packages/patches/python2-subprocess32-disable-input-test.patch	\
  %D%/packages/patches/python2-unittest2-remove-argparse.patch \
  %D%/packages/patches/python-unittest2-python3-compat.patch	\
  %D%/packages/patches/python-unittest2-remove-argparse.patch	\
  %D%/packages/patches/qt4-ldflags.patch			\
  %D%/packages/patches/qtscript-disable-tests.patch		\
  %D%/packages/patches/quagga-reproducible-build.patch          \

M gnu/packages/backup.scm => gnu/packages/backup.scm +1 -3
@@ 522,9 522,7 @@ detection, and lossless compression.")
    (native-inputs
     `(("python-cython" ,python-cython)
       ("python-setuptools-scm" ,python-setuptools-scm)
       ;; Borg 1.0.8's test suite uses 'tmpdir_factory', which was introduced in
       ;; pytest 2.8.
       ("python-pytest" ,python-pytest-3.0)
       ("python-pytest" ,python-pytest)
       ;; For generating the documentation.
       ("python-sphinx" ,python-sphinx)
       ("python-guzzle-sphinx-theme" ,python-guzzle-sphinx-theme)))

M gnu/packages/calendar.scm => gnu/packages/calendar.scm +1 -2
@@ 118,8 118,7 @@ data units.")
                              "not test_printics_read_from_stdin "
                              "and not test_import_from_stdin"))))))))
    (native-inputs
      ;; XXX Uses tmpdir_factory, introduced in pytest 2.8.
     `(("python-pytest" ,python-pytest-3.0)
     `(("python-pytest" ,python-pytest)
       ("python-pytest-cov" ,python-pytest-cov)
       ("python-setuptools-scm" ,python-setuptools-scm)
       ;; Required for tests

M gnu/packages/databases.scm => gnu/packages/databases.scm +1 -1
@@ 1814,7 1814,7 @@ Memory-Mapped Database} (LMDB), a high-performance key-value store.")
             #t)))))
    (native-inputs
     `(("python-pytest-mock" ,python-pytest-mock)
       ("python-pytest" ,python-pytest-3.0)
       ("python-pytest" ,python-pytest)
       ("python-flexmock" ,python-flexmock)))
    (propagated-inputs
     `(("python-backpack" ,python-backpack)

A gnu/packages/patches/python-2.7-adjust-tests.patch => gnu/packages/patches/python-2.7-adjust-tests.patch +22 -0
@@ 0,0 1,22 @@
SIGINT is ignored in the Guix build environment.

--- a/Lib/test/test_regrtest.py
+++ b/Lib/test/test_regrtest.py
@@ -399,6 +399,8 @@
         output = self.run_tests('--fromfile', filename)
         self.check_executed_tests(output, tests)
 
+    @unittest.skipIf(True,
+        "KeyboardInterrupts do not work in the build environment")
     def test_interrupted(self):
         code = TEST_INTERRUPTED
         test = self.create_test('sigint', code=code)
@@ -416,6 +418,8 @@
                  % (self.TESTNAME_REGEX, len(tests)))
         self.check_line(output, regex)
 
+    @unittest.skipIf(True,
+        "KeyboardInterrupts do not work in the build environment")
     def test_slow_interrupted(self):
         # Issue #25373: test --slowest with an interrupted test
         code = TEST_INTERRUPTED

D gnu/packages/patches/python-2.7-getentropy-on-old-kernels.patch => gnu/packages/patches/python-2.7-getentropy-on-old-kernels.patch +0 -54
@@ 1,54 0,0 @@
This patch resolves a compatibility issue when compiled against glibc
2.25
and run runder kernels < 3.17:

https://bugzilla.redhat.com/show_bug.cgi?id=1410175

Upstream bug URLs:

https://bugs.python.org/issue29157
https://bugs.python.org/issue29188

Patch adapted from upstream source repository:

https://github.com/python/cpython/commit/01bdbad3e951014c58581635b94b22868537901c

From 01bdbad3e951014c58581635b94b22868537901c Mon Sep 17 00:00:00 2001
From: Victor Stinner <victor.stinner@gmail.com>
Date: Mon, 9 Jan 2017 11:10:41 +0100
Subject: [PATCH] Don't use getentropy() on Linux

Issue #29188: Support glibc 2.24 on Linux: don't use getentropy() function but
read from /dev/urandom to get random bytes, for example in os.urandom().  On
Linux, getentropy() is implemented which getrandom() is blocking mode, whereas
os.urandom() should not block.
---
 Misc/NEWS       |  5 +++++
 Python/random.c | 11 +++++++++--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/Python/random.c b/Python/random.c
index 57c41ffcd6..000cb36938 100644
--- a/Python/random.c
+++ b/Python/random.c
@@ -97,8 +97,15 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
 }
 
 /* Issue #25003: Don't use getentropy() on Solaris (available since
- * Solaris 11.3), it is blocking whereas os.urandom() should not block. */
-#elif defined(HAVE_GETENTROPY) && !defined(sun)
+   Solaris 11.3), it is blocking whereas os.urandom() should not block.
+
+   Issue #29188: Don't use getentropy() on Linux since the glibc 2.24
+   implements it with the getrandom() syscall which can fail with ENOSYS,
+   and this error is not supported in py_getentropy() and getrandom() is called
+   with flags=0 which blocks until system urandom is initialized, which is not
+   the desired behaviour to seed the Python hash secret nor for os.urandom():
+   see the PEP 524 which was only implemented in Python 3.6. */
+#elif defined(HAVE_GETENTROPY) && !defined(sun) && !defined(linux)
 #define PY_GETENTROPY 1
 
 /* Fill buffer with size pseudo-random bytes generated by getentropy().
-- 
2.12.0


R gnu/packages/patches/python-3.5-fix-tests.patch => gnu/packages/patches/python-3-fix-tests.patch +83 -3
@@ 3,16 3,16 @@ prior revisions of Python.

--- Lib/test/test_pathlib.py     2014-03-01 03:02:36.088311000 +0100
+++ Lib/test/test_pathlib.py     2014-03-01 04:56:37.768311000 +0100
@@ -1986,8 +1986,9 @@
         expect = set() if not support.fs_is_case_insensitive(BASE) else given
@@ -2132,8 +2132,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')
         import pwd
--- Lib/test/test_tarfile.py        2016-02-24 19:22:52.597208055 +0000
+++ Lib/test/test_tarfile.py     2016-02-24 20:50:48.941950135 +0000
@@ -2305,11 +2305,14 @@


@@ 67,3 67,83 @@ outcome. Unfortunately, this will make it fail for users running
     """

 class PdbTestCase(unittest.TestCase):
--- Lib/test/test_socket.py
+++ Lib/test/test_socket.py
@@ -802,6 +802,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)
--- Lib/test/test_spwd.py
+++ Lib/test/test_spwd.py
@@ -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):
--- Lib/test/test_regrtest.py
+++ Lib/test/test_regrtest.py
@@ -700,6 +700,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)
@@ -717,6 +718,7 @@
                  % (self.TESTNAME_REGEX, len(tests)))
         self.check_line(output, regex)
 
+    @unittest.skipIf(True, 'Keyboard interrupts do not work in the Guix build environment.')
     def test_slow_interrupted(self):
         # Issue #25373: test --slowest with an interrupted test
         code = TEST_INTERRUPTED
--- Lib/test/test_generators.py
+++ Lib/test/test_generators.py
@@ -29,6 +29,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)
--- Lib/test/test_normalization.py
+++ Lib/test/test_normalization.py
@@ -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}")
 

D gnu/packages/patches/python-3.5-getentropy-on-old-kernels.patch => gnu/packages/patches/python-3.5-getentropy-on-old-kernels.patch +0 -720
@@ 1,720 0,0 @@
This patch resolves a compatibility issue when compiled against glibc 2.25
and run runder kernels < 3.17:

https://bugzilla.redhat.com/show_bug.cgi?id=1410175

Upstream bug URL: https://bugs.python.org/issue29157

Patch copied from upstream source repository:

https://hg.python.org/cpython/rev/8125d9a8152b

# HG changeset patch
# User Victor Stinner <victor.stinner@gmail.com>
# Date 1483957133 -3600
# Node ID 8125d9a8152b79e712cb09c7094b9129b9bcea86
# Parent  337461574c90281630751b6095c4e1baf380cf7d
Issue #29157: Prefer getrandom() over getentropy()

Copy and then adapt Python/random.c from default branch. Difference between 3.5
and default branches:

* Python 3.5 only uses getrandom() in non-blocking mode: flags=GRND_NONBLOCK
* If getrandom() fails with EAGAIN: py_getrandom() immediately fails and
  remembers that getrandom() doesn't work.
* Python 3.5 has no _PyOS_URandomNonblock() function: _PyOS_URandom()
  works in non-blocking mode on Python 3.5

diff --git a/Python/random.c b/Python/random.c
--- Python/random.c
+++ Python/random.c
@@ -1,6 +1,9 @@
 #include "Python.h"
 #ifdef MS_WINDOWS
 #  include <windows.h>
+/* All sample MSDN wincrypt programs include the header below. It is at least
+ * required with Min GW. */
+#  include <wincrypt.h>
 #else
 #  include <fcntl.h>
 #  ifdef HAVE_SYS_STAT_H
@@ -37,10 +40,9 @@ win32_urandom_init(int raise)
     return 0;
 
 error:
-    if (raise)
+    if (raise) {
         PyErr_SetFromWindowsErr(0);
-    else
-        Py_FatalError("Failed to initialize Windows random API (CryptoGen)");
+    }
     return -1;
 }
 
@@ -53,8 +55,9 @@ win32_urandom(unsigned char *buffer, Py_
 
     if (hCryptProv == 0)
     {
-        if (win32_urandom_init(raise) == -1)
+        if (win32_urandom_init(raise) == -1) {
             return -1;
+        }
     }
 
     while (size > 0)
@@ -63,11 +66,9 @@ win32_urandom(unsigned char *buffer, Py_
         if (!CryptGenRandom(hCryptProv, (DWORD)chunk, buffer))
         {
             /* CryptGenRandom() failed */
-            if (raise)
+            if (raise) {
                 PyErr_SetFromWindowsErr(0);
-            else
-                Py_FatalError("Failed to initialized the randomized hash "
-                        "secret using CryptoGen)");
+            }
             return -1;
         }
         buffer += chunk;
@@ -76,58 +77,23 @@ win32_urandom(unsigned char *buffer, Py_
     return 0;
 }
 
-/* Issue #25003: Don't use getentropy() on Solaris (available since
- * Solaris 11.3), it is blocking whereas os.urandom() should not block. */
-#elif defined(HAVE_GETENTROPY) && !defined(sun)
-#define PY_GETENTROPY 1
-
-/* Fill buffer with size pseudo-random bytes generated by getentropy().
-   Return 0 on success, or raise an exception and return -1 on error.
-
-   If fatal is nonzero, call Py_FatalError() instead of raising an exception
-   on error. */
-static int
-py_getentropy(unsigned char *buffer, Py_ssize_t size, int fatal)
-{
-    while (size > 0) {
-        Py_ssize_t len = Py_MIN(size, 256);
-        int res;
-
-        if (!fatal) {
-            Py_BEGIN_ALLOW_THREADS
-            res = getentropy(buffer, len);
-            Py_END_ALLOW_THREADS
-
-            if (res < 0) {
-                PyErr_SetFromErrno(PyExc_OSError);
-                return -1;
-            }
-        }
-        else {
-            res = getentropy(buffer, len);
-            if (res < 0)
-                Py_FatalError("getentropy() failed");
-        }
-
-        buffer += len;
-        size -= len;
-    }
-    return 0;
-}
-
-#else
+#else /* !MS_WINDOWS */
 
 #if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL)
 #define PY_GETRANDOM 1
 
-/* Call getrandom()
+/* Call getrandom() to get random bytes:
+
    - Return 1 on success
-   - Return 0 if getrandom() syscall is not available (failed with ENOSYS or
-     EPERM) or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom
-     not initialized yet) and raise=0.
+   - Return 0 if getrandom() is not available (failed with ENOSYS or EPERM),
+     or if getrandom(GRND_NONBLOCK) failed with EAGAIN (system urandom not
+     initialized yet).
    - Raise an exception (if raise is non-zero) and return -1 on error:
-     getrandom() failed with EINTR and the Python signal handler raised an
-     exception, or getrandom() failed with a different error. */
+     if getrandom() failed with EINTR, raise is non-zero and the Python signal
+     handler raised an exception, or if getrandom() failed with a different
+     error.
+
+   getrandom() is retried if it failed with EINTR: interrupted by a signal. */
 static int
 py_getrandom(void *buffer, Py_ssize_t size, int raise)
 {
@@ -142,16 +108,19 @@ py_getrandom(void *buffer, Py_ssize_t si
      * see https://bugs.python.org/issue26839. To avoid this, use the
      * GRND_NONBLOCK flag. */
     const int flags = GRND_NONBLOCK;
+    char *dest;
     long n;
 
     if (!getrandom_works) {
         return 0;
     }
 
+    dest = buffer;
     while (0 < size) {
 #ifdef sun
         /* Issue #26735: On Solaris, getrandom() is limited to returning up
-           to 1024 bytes */
+           to 1024 bytes. Call it multiple times if more bytes are
+           requested. */
         n = Py_MIN(size, 1024);
 #else
         n = Py_MIN(size, LONG_MAX);
@@ -161,34 +130,35 @@ py_getrandom(void *buffer, Py_ssize_t si
 #ifdef HAVE_GETRANDOM
         if (raise) {
             Py_BEGIN_ALLOW_THREADS
-            n = getrandom(buffer, n, flags);
+            n = getrandom(dest, n, flags);
             Py_END_ALLOW_THREADS
         }
         else {
-            n = getrandom(buffer, n, flags);
+            n = getrandom(dest, n, flags);
         }
 #else
         /* On Linux, use the syscall() function because the GNU libc doesn't
-         * expose the Linux getrandom() syscall yet. See:
-         * https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
+           expose the Linux getrandom() syscall yet. See:
+           https://sourceware.org/bugzilla/show_bug.cgi?id=17252 */
         if (raise) {
             Py_BEGIN_ALLOW_THREADS
-            n = syscall(SYS_getrandom, buffer, n, flags);
+            n = syscall(SYS_getrandom, dest, n, flags);
             Py_END_ALLOW_THREADS
         }
         else {
-            n = syscall(SYS_getrandom, buffer, n, flags);
+            n = syscall(SYS_getrandom, dest, n, flags);
         }
 #endif
 
         if (n < 0) {
-            /* ENOSYS: getrandom() syscall not supported by the kernel (but
-             * maybe supported by the host which built Python). EPERM:
-             * getrandom() syscall blocked by SECCOMP or something else. */
+            /* ENOSYS: the syscall is not supported by the kernel.
+               EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
+               or something else. */
             if (errno == ENOSYS || errno == EPERM) {
                 getrandom_works = 0;
                 return 0;
             }
+
             if (errno == EAGAIN) {
                 /* getrandom(GRND_NONBLOCK) fails with EAGAIN if the system
                    urandom is not initialiazed yet. In this case, fall back on
@@ -202,32 +172,101 @@ py_getrandom(void *buffer, Py_ssize_t si
             }
 
             if (errno == EINTR) {
-                if (PyErr_CheckSignals()) {
-                    if (!raise) {
-                        Py_FatalError("getrandom() interrupted by a signal");
+                if (raise) {
+                    if (PyErr_CheckSignals()) {
+                        return -1;
                     }
-                    return -1;
                 }
 
-                /* retry getrandom() */
+                /* retry getrandom() if it was interrupted by a signal */
                 continue;
             }
 
             if (raise) {
                 PyErr_SetFromErrno(PyExc_OSError);
             }
-            else {
-                Py_FatalError("getrandom() failed");
+            return -1;
+        }
+
+        dest += n;
+        size -= n;
+    }
+    return 1;
+}
+
+#elif defined(HAVE_GETENTROPY)
+#define PY_GETENTROPY 1
+
+/* Fill buffer with size pseudo-random bytes generated by getentropy():
+
+   - Return 1 on success
+   - Return 0 if getentropy() syscall is not available (failed with ENOSYS or
+     EPERM).
+   - Raise an exception (if raise is non-zero) and return -1 on error:
+     if getentropy() failed with EINTR, raise is non-zero and the Python signal
+     handler raised an exception, or if getentropy() failed with a different
+     error.
+
+   getentropy() is retried if it failed with EINTR: interrupted by a signal. */
+static int
+py_getentropy(char *buffer, Py_ssize_t size, int raise)
+{
+    /* Is getentropy() supported by the running kernel? Set to 0 if
+       getentropy() failed with ENOSYS or EPERM. */
+    static int getentropy_works = 1;
+
+    if (!getentropy_works) {
+        return 0;
+    }
+
+    while (size > 0) {
+        /* getentropy() is limited to returning up to 256 bytes. Call it
+           multiple times if more bytes are requested. */
+        Py_ssize_t len = Py_MIN(size, 256);
+        int res;
+
+        if (raise) {
+            Py_BEGIN_ALLOW_THREADS
+            res = getentropy(buffer, len);
+            Py_END_ALLOW_THREADS
+        }
+        else {
+            res = getentropy(buffer, len);
+        }
+
+        if (res < 0) {
+            /* ENOSYS: the syscall is not supported by the running kernel.
+               EPERM: the syscall is blocked by a security policy (ex: SECCOMP)
+               or something else. */
+            if (errno == ENOSYS || errno == EPERM) {
+                getentropy_works = 0;
+                return 0;
+            }
+
+            if (errno == EINTR) {
+                if (raise) {
+                    if (PyErr_CheckSignals()) {
+                        return -1;
+                    }
+                }
+
+                /* retry getentropy() if it was interrupted by a signal */
+                continue;
+            }
+
+            if (raise) {
+                PyErr_SetFromErrno(PyExc_OSError);
             }
             return -1;
         }
 
-        buffer += n;
-        size -= n;
+        buffer += len;
+        size -= len;
     }
     return 1;
 }
-#endif
+#endif /* defined(HAVE_GETENTROPY) && !defined(sun) */
+
 
 static struct {
     int fd;
@@ -235,136 +274,123 @@ static struct {
     ino_t st_ino;
 } urandom_cache = { -1 };
 
+/* Read random bytes from the /dev/urandom device:
 
-/* Read 'size' random bytes from py_getrandom(). Fall back on reading from
-   /dev/urandom if getrandom() is not available.
+   - Return 0 on success
+   - Raise an exception (if raise is non-zero) and return -1 on error
 
-   Call Py_FatalError() on error. */
-static void
-dev_urandom_noraise(unsigned char *buffer, Py_ssize_t size)
+   Possible causes of errors:
+
+   - open() failed with ENOENT, ENXIO, ENODEV, EACCES: the /dev/urandom device
+     was not found. For example, it was removed manually or not exposed in a
+     chroot or container.
+   - open() failed with a different error
+   - fstat() failed
+   - read() failed or returned 0
+
+   read() is retried if it failed with EINTR: interrupted by a signal.
+
+   The file descriptor of the device is kept open between calls to avoid using
+   many file descriptors when run in parallel from multiple threads:
+   see the issue #18756.
+
+   st_dev and st_ino fields of the file descriptor (from fstat()) are cached to
+   check if the file descriptor was replaced by a different file (which is
+   likely a bug in the application): see the issue #21207.
+
+   If the file descriptor was closed or replaced, open a new file descriptor
+   but don't close the old file descriptor: it probably points to something
+   important for some third-party code. */
+static int
+dev_urandom(char *buffer, Py_ssize_t size, int raise)
 {
     int fd;
     Py_ssize_t n;
 
-    assert (0 < size);
+    if (raise) {
+        struct _Py_stat_struct st;
 
-#ifdef PY_GETRANDOM
-    if (py_getrandom(buffer, size, 0) == 1) {
-        return;
+        if (urandom_cache.fd >= 0) {
+            /* Does the fd point to the same thing as before? (issue #21207) */
+            if (_Py_fstat_noraise(urandom_cache.fd, &st)
+                || st.st_dev != urandom_cache.st_dev
+                || st.st_ino != urandom_cache.st_ino) {
+                /* Something changed: forget the cached fd (but don't close it,
+                   since it probably points to something important for some
+                   third-party code). */
+                urandom_cache.fd = -1;
+            }
+        }
+        if (urandom_cache.fd >= 0)
+            fd = urandom_cache.fd;
+        else {
+            fd = _Py_open("/dev/urandom", O_RDONLY);
+            if (fd < 0) {
+                if (errno == ENOENT || errno == ENXIO ||
+                    errno == ENODEV || errno == EACCES) {
+                    PyErr_SetString(PyExc_NotImplementedError,
+                                    "/dev/urandom (or equivalent) not found");
+                }
+                /* otherwise, keep the OSError exception raised by _Py_open() */
+                return -1;
+            }
+            if (urandom_cache.fd >= 0) {
+                /* urandom_fd was initialized by another thread while we were
+                   not holding the GIL, keep it. */
+                close(fd);
+                fd = urandom_cache.fd;
+            }
+            else {
+                if (_Py_fstat(fd, &st)) {
+                    close(fd);
+                    return -1;
+                }
+                else {
+                    urandom_cache.fd = fd;
+                    urandom_cache.st_dev = st.st_dev;
+                    urandom_cache.st_ino = st.st_ino;
+                }
+            }
+        }
+
+        do {
+            n = _Py_read(fd, buffer, (size_t)size);
+            if (n == -1)
+                return -1;
+            if (n == 0) {
+                PyErr_Format(PyExc_RuntimeError,
+                        "Failed to read %zi bytes from /dev/urandom",
+                        size);
+                return -1;
+            }
+
+            buffer += n;
+            size -= n;
+        } while (0 < size);
     }
-    /* getrandom() failed with ENOSYS or EPERM,
-       fall back on reading /dev/urandom */
-#endif
-
-    fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
-    if (fd < 0) {
-        Py_FatalError("Failed to open /dev/urandom");
-    }
-
-    while (0 < size)
-    {
-        do {
-            n = read(fd, buffer, (size_t)size);
-        } while (n < 0 && errno == EINTR);
-
-        if (n <= 0) {
-            /* read() failed or returned 0 bytes */
-            Py_FatalError("Failed to read bytes from /dev/urandom");
-            break;
-        }
-        buffer += n;
-        size -= n;
-    }
-    close(fd);
-}
-
-/* Read 'size' random bytes from py_getrandom(). Fall back on reading from
-   /dev/urandom if getrandom() is not available.
-
-   Return 0 on success. Raise an exception and return -1 on error. */
-static int
-dev_urandom_python(char *buffer, Py_ssize_t size)
-{
-    int fd;
-    Py_ssize_t n;
-    struct _Py_stat_struct st;
-#ifdef PY_GETRANDOM
-    int res;
-#endif
-
-    if (size <= 0)
-        return 0;
-
-#ifdef PY_GETRANDOM
-    res = py_getrandom(buffer, size, 1);
-    if (res < 0) {
-        return -1;
-    }
-    if (res == 1) {
-        return 0;
-    }
-    /* getrandom() failed with ENOSYS or EPERM,
-       fall back on reading /dev/urandom */
-#endif
-
-    if (urandom_cache.fd >= 0) {
-        /* Does the fd point to the same thing as before? (issue #21207) */
-        if (_Py_fstat_noraise(urandom_cache.fd, &st)
-            || st.st_dev != urandom_cache.st_dev
-            || st.st_ino != urandom_cache.st_ino) {
-            /* Something changed: forget the cached fd (but don't close it,
-               since it probably points to something important for some
-               third-party code). */
-            urandom_cache.fd = -1;
-        }
-    }
-    if (urandom_cache.fd >= 0)
-        fd = urandom_cache.fd;
     else {
-        fd = _Py_open("/dev/urandom", O_RDONLY);
+        fd = _Py_open_noraise("/dev/urandom", O_RDONLY);
         if (fd < 0) {
-            if (errno == ENOENT || errno == ENXIO ||
-                errno == ENODEV || errno == EACCES)
-                PyErr_SetString(PyExc_NotImplementedError,
-                                "/dev/urandom (or equivalent) not found");
-            /* otherwise, keep the OSError exception raised by _Py_open() */
             return -1;
         }
-        if (urandom_cache.fd >= 0) {
-            /* urandom_fd was initialized by another thread while we were
-               not holding the GIL, keep it. */
-            close(fd);
-            fd = urandom_cache.fd;
-        }
-        else {
-            if (_Py_fstat(fd, &st)) {
+
+        while (0 < size)
+        {
+            do {
+                n = read(fd, buffer, (size_t)size);
+            } while (n < 0 && errno == EINTR);
+
+            if (n <= 0) {
+                /* stop on error or if read(size) returned 0 */
                 close(fd);
                 return -1;
             }
-            else {
-                urandom_cache.fd = fd;
-                urandom_cache.st_dev = st.st_dev;
-                urandom_cache.st_ino = st.st_ino;
-            }
+
+            buffer += n;
+            size -= n;
         }
+        close(fd);
     }
-
-    do {
-        n = _Py_read(fd, buffer, (size_t)size);
-        if (n == -1) {
-            return -1;
-        }
-        if (n == 0) {
-            PyErr_Format(PyExc_RuntimeError,
-                    "Failed to read %zi bytes from /dev/urandom",
-                    size);
-            return -1;
-        }
-
-        buffer += n;
-        size -= n;
-    } while (0 < size);
-
     return 0;
 }
 
@@ -376,8 +402,8 @@ dev_urandom_close(void)
         urandom_cache.fd = -1;
     }
 }
+#endif /* !MS_WINDOWS */
 
-#endif
 
 /* Fill buffer with pseudo-random bytes generated by a linear congruent
    generator (LCG):
@@ -400,29 +426,98 @@ lcg_urandom(unsigned int x0, unsigned ch
     }
 }
 
+/* Read random bytes:
+
+   - Return 0 on success
+   - Raise an exception (if raise is non-zero) and return -1 on error
+
+   Used sources of entropy ordered by preference, preferred source first:
+
+   - CryptGenRandom() on Windows
+   - getrandom() function (ex: Linux and Solaris): call py_getrandom()
+   - getentropy() function (ex: OpenBSD): call py_getentropy()
+   - /dev/urandom device
+
+   Read from the /dev/urandom device if getrandom() or getentropy() function
+   is not available or does not work.
+
+   Prefer getrandom() over getentropy() because getrandom() supports blocking
+   and non-blocking mode and Python requires non-blocking RNG at startup to
+   initialize its hash secret: see the PEP 524.
+
+   Prefer getrandom() and getentropy() over reading directly /dev/urandom
+   because these functions don't need file descriptors and so avoid ENFILE or
+   EMFILE errors (too many open files): see the issue #18756.
+
+   Only use RNG running in the kernel. They are more secure because it is
+   harder to get the internal state of a RNG running in the kernel land than a
+   RNG running in the user land. The kernel has a direct access to the hardware
+   and has access to hardware RNG, they are used as entropy sources.
+
+   Note: the OpenSSL RAND_pseudo_bytes() function does not automatically reseed
+   its RNG on fork(), two child processes (with the same pid) generate the same
+   random numbers: see issue #18747. Kernel RNGs don't have this issue,
+   they have access to good quality entropy sources.
+
+   If raise is zero:
+
+   - Don't raise an exception on error
+   - Don't call the Python signal handler (don't call PyErr_CheckSignals()) if
+     a function fails with EINTR: retry directly the interrupted function
+   - Don't release the GIL to call functions.
+*/
+static int
+pyurandom(void *buffer, Py_ssize_t size, int raise)
+{
+#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
+    int res;
+#endif
+
+    if (size < 0) {
+        if (raise) {
+            PyErr_Format(PyExc_ValueError,
+                         "negative argument not allowed");
+        }
+        return -1;
+    }
+
+    if (size == 0) {
+        return 0;
+    }
+
+#ifdef MS_WINDOWS
+    return win32_urandom((unsigned char *)buffer, size, raise);
+#else
+
+#if defined(PY_GETRANDOM) || defined(PY_GETENTROPY)
+#ifdef PY_GETRANDOM
+    res = py_getrandom(buffer, size, raise);
+#else
+    res = py_getentropy(buffer, size, raise);
+#endif
+    if (res < 0) {
+        return -1;
+    }
+    if (res == 1) {
+        return 0;
+    }
+    /* getrandom() or getentropy() function is not available: failed with
+       ENOSYS, EPERM or EAGAIN. Fall back on reading from /dev/urandom. */
+#endif
+
+    return dev_urandom(buffer, size, raise);
+#endif
+}
+
 /* Fill buffer with size pseudo-random bytes from the operating system random
    number generator (RNG). It is suitable for most cryptographic purposes
    except long living private keys for asymmetric encryption.
 
-   Return 0 on success, raise an exception and return -1 on error. */
+   Return 0 on success. Raise an exception and return -1 on error. */
 int
 _PyOS_URandom(void *buffer, Py_ssize_t size)
 {
-    if (size < 0) {
-        PyErr_Format(PyExc_ValueError,
-                     "negative argument not allowed");
-        return -1;
-    }
-    if (size == 0)
-        return 0;
-
-#ifdef MS_WINDOWS
-    return win32_urandom((unsigned char *)buffer, size, 1);
-#elif defined(PY_GETENTROPY)
-    return py_getentropy(buffer, size, 0);
-#else
-    return dev_urandom_python((char*)buffer, size);
-#endif
+    return pyurandom(buffer, size, 1);
 }
 
 void
@@ -463,13 +558,14 @@ void
         }
     }
     else {
-#ifdef MS_WINDOWS
-        (void)win32_urandom(secret, secret_size, 0);
-#elif defined(PY_GETENTROPY)
-        (void)py_getentropy(secret, secret_size, 1);
-#else
-        dev_urandom_noraise(secret, secret_size);
-#endif
+        int res;
+
+        /* _PyRandom_Init() is called very early in the Python initialization
+           and so exceptions cannot be used (use raise=0). */
+        res = pyurandom(secret, secret_size, 0);
+        if (res < 0) {
+            Py_FatalError("failed to get random numbers to initialize Python");
+        }
     }
 }
 
@@ -481,8 +577,6 @@ void
         CryptReleaseContext(hCryptProv, 0);
         hCryptProv = 0;
     }
-#elif defined(PY_GETENTROPY)
-    /* nothing to clean */
 #else
     dev_urandom_close();
 #endif


A gnu/packages/patches/python-unittest2-python3-compat.patch => gnu/packages/patches/python-unittest2-python3-compat.patch +34 -0
@@ 0,0 1,34 @@
Skip tests that fail with newer versions of Python.

Patch copied from Gentoo:

https://gitweb.gentoo.org/repo/gentoo.git/tree/dev-python/unittest2/files/unittest2-1.1.0-python3.5-test.patch

diff --git a/unittest2/test/test_loader.py b/unittest2/test/test_loader.py
index 683f662..347eea5 100644
--- a/unittest2/test/test_loader.py
+++ b/unittest2/test/test_loader.py
@@ -509,6 +509,7 @@ class Test_TestLoader(unittest2.TestCase):
     #
     # What happens when an impossible name is given, relative to the provided
     # `module`?
+    @unittest.skipIf(sys.version_info[:2] >= (3, 5), "python 3.5 has problems here")
     def test_loadTestsFromName__relative_malformed_name(self):
         loader = unittest.TestLoader()
 
@@ -811,6 +812,7 @@ class Test_TestLoader(unittest2.TestCase):
     # TestCase or TestSuite instance."
     #
     # What happens when presented with an impossible module name?
+    @unittest.skipIf(sys.version_info[:2] >= (3, 5), "python 3.5 has problems here")
     def test_loadTestsFromNames__malformed_name(self):
         loader = unittest2.TestLoader()
 
@@ -918,6 +920,7 @@ class Test_TestLoader(unittest2.TestCase):
     # "The method optionally resolves name relative to the given module"
     #
     # What happens when presented with an impossible attribute name?
+    @unittest.skipIf(sys.version_info[:2] >= (3, 5), "python 3.5 has problems here")
     def test_loadTestsFromNames__relative_malformed_name(self):
         loader = unittest.TestLoader()
 

R gnu/packages/patches/python2-unittest2-remove-argparse.patch => gnu/packages/patches/python-unittest2-remove-argparse.patch +0 -0
M gnu/packages/python.scm => gnu/packages/python.scm +179 -160
@@ 132,7 132,7 @@
(define-public python-2.7
  (package
    (name "python")
    (version "2.7.13")
    (version "2.7.14")
    (source
     (origin
      (method url-fetch)


@@ 140,12 140,12 @@
                          version "/Python-" version ".tar.xz"))
      (sha256
       (base32
        "0cgpk3zk0fgpji59pb4zy9nzljr70qzgv1vpz5hq5xw2d2c47m9m"))
        "0rka541ys16jwzcnnvjp2v12m4cwgd2jp6wj4kj511p715pb5zvi"))
      (patches (search-patches "python-2.7-search-paths.patch"
                               "python-2-deterministic-build-info.patch"
                               "python-2.7-site-prefixes.patch"
                               "python-2.7-source-date-epoch.patch"
                               "python-2.7-getentropy-on-old-kernels.patch"))
                               "python-2.7-adjust-tests.patch"))
      (modules '((guix build utils)))
      ;; suboptimal to delete failing tests here, but if we delete them in the
      ;; arguments then we need to make sure to strip out that phase when it


@@ 203,6 203,7 @@
                                  '("Lib/subprocess.py"
                                    "Lib/popen2.py"
                                    "Lib/distutils/tests/test_spawn.py"
                                    "Lib/test/support/__init__.py"
                                    "Lib/test/test_subprocess.py"))
               (("/bin/sh") (which "sh")))



@@ 328,28 329,28 @@ data types.")
;; Current 2.x version.
(define-public python-2 python-2.7)

(define-public python-3.5
(define-public python-3.6
  (package (inherit python-2)
    (version "3.5.3")
    (version "3.6.3")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://www.python.org/ftp/python/"
                                  version "/Python-" version ".tar.xz"))
              (patches (search-patches
                        "python-fix-tests.patch"
                        "python-3.5-fix-tests.patch"
                        "python-3.5-getentropy-on-old-kernels.patch"
                        "python-3-fix-tests.patch"
                        "python-3-deterministic-build-info.patch"
                        "python-3-search-paths.patch"))
              (patch-flags '("-p0"))
              (sha256
               (base32
                "1c6v1n9nz4mlx9mw1125fxpmbrgniqdbbx9hnqx44maqazb2mzpf"))
                "1nl1raaagr4car787a2hmjv2dw6gqny53xfd6wisbgx4r5kxk9yd"))
              (snippet
               '(begin
                  (for-each delete-file
                            '("Lib/ctypes/test/test_win32.py" ; fails on aarch64
                              "Lib/test/test_fcntl.py"))
                            '("Lib/ctypes/test/test_structures.py" ; fails on aarch64
                              "Lib/ctypes/test/test_win32.py" ; fails on aarch64
                              "Lib/test/test_fcntl.py")) ; fails on aarch64
                  #t))))
    (arguments (substitute-keyword-arguments (package-arguments python-2)
                 ((#:tests? _) #t)))


@@ 361,7 362,7 @@ data types.")
                                        "/site-packages"))))))))

;; Current 3.x version.
(define-public python-3 python-3.5)
(define-public python-3 python-3.6)

;; Current major version.
(define-public python python-3)


@@ 933,45 934,43 @@ API for locking files.")
(define-public python-mock
  (package
    (name "python-mock")
    (version "1.0.1")
    (version "2.0.0")
    (source
     (origin
       (method url-fetch)
       (uri (pypi-uri "mock" version))
       (sha256
        (base32
         "0kzlsbki6q0awf89rc287f3aj8x431lrajf160a70z0ikhnxsfdq"))))
         "1flbpksir5sqrvq2z0dp8sl4bzbadg21sj4d42w3klpdfvgvcn5i"))))
    (propagated-inputs
     `(("python-pbr" ,python-pbr-minimal)
       ("python-six" ,python-six)))
    (build-system python-build-system)
    (arguments '(#:test-target "check"))
    (native-inputs
     `(("python-unittest2" ,python-unittest2)))
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (replace 'check
           (lambda _
             (zero? (system* "unit2")))))))
    (home-page "https://github.com/testing-cabal/mock")
    (synopsis "Python mocking and patching library for testing")
    (description
     "Mock is a library for testing in Python.  It allows you to replace parts
of your system under test with mock objects and make assertions about how they
have been used.")
    (properties `((python2-variant . ,(delay python2-mock))))
    (license license:expat)))

(define-public python2-mock
  (package-with-python2 python-mock))

;;; Some packages (notably, certbot and python-acme) rely on this newer version
;;; of python-mock. However, a large number of packages fail to build with
;;; mock@2, so we add a new variable for now. Also, there may be a dependency
;;; cycle between mock and six, so we avoid creating python2-mock@2 for now.
(define-public python-mock-2
  (package
    (inherit python-mock)
    (version "2.0.0")
    (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "mock" version))
        (sha256
         (base32
          "1flbpksir5sqrvq2z0dp8sl4bzbadg21sj4d42w3klpdfvgvcn5i"))))
    (propagated-inputs
     `(("python-pbr" ,python-pbr-minimal)
       ,@(package-propagated-inputs python-mock)))))
  (let ((base (package-with-python2
               (strip-python2-variant python-mock))))
    (package (inherit base)
      (propagated-inputs
       `(("python2-functools32" ,python2-functools32)
         ("python2-funcsigs" ,python2-funcsigs)
         ,@(package-propagated-inputs base))))))

(define-public python-setuptools
  (package


@@ 1169,18 1168,24 @@ password storage.")
(define-public python-six
  (package
    (name "python-six")
    (version "1.10.0")
    (version "1.11.0")
    (source
     (origin
      (method url-fetch)
      (uri (pypi-uri "six" version))
      (sha256
       (base32
        "0snmb8xffb3vsma0z67i0h0w2g2dy0p3gsgh9gi4i0kgc5l8spqh"))))
        "1scqzwc51c875z23phj48gircqjgnn3af8zy2izjwmnlxrxsgs3h"))))
    (build-system python-build-system)
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (replace 'check
           (lambda _
             (zero? (system* "py.test" "-v")))))))
    (native-inputs
     `(("python-py" ,python-py)
       ("python-pytest" ,python-pytest)))
       ("python-pytest" ,python-pytest-bootstrap)))
    (home-page "http://pypi.python.org/pypi/six/")
    (synopsis "Python 2 and 3 compatibility utilities")
    (description


@@ 1566,6 1571,28 @@ bug tracker.")
    (home-page "http://www.liquidx.net/pybugz/")
    (license license:gpl2)))

(define-public python2-enum
  (package
    (name "python2-enum")
    (version "0.4.6")
    (source (origin
              (method url-fetch)
              (uri (pypi-uri "enum" version))
              (sha256
               (base32
                "13lk3yrwj42vl30kw3c194f739nrfrdg64s6i0v2p636n4k8brsl"))))
    (build-system python-build-system)
    (arguments
     `(#:python ,python-2))
    (home-page "http://pypi.python.org/pypi/enum/")
    (synopsis "Robust enumerated type support in Python")
    (description
     "This provides a module for robust enumerations in Python.  It has
been superseded by the Python standard library and is provided only for
compatibility.")
    ;; Choice of either license.
    (license (list license:gpl3+ license:psfl))))

(define-public python-enum34
  (package
    (name "python-enum34")


@@ 1816,20 1843,51 @@ interfaces and processes.")
(define-public python2-nose2
  (package-with-python2 python-nose2))

(define-public python2-funcsigs
  (package
    (name "python2-funcsigs")
    (version "1.0.2")
    (source (origin
              (method url-fetch)
              (uri (pypi-uri "funcsigs" version))
              (sha256
               (base32
                "0l4g5818ffyfmfs1a924811azhjj8ax9xd1cffr1mzd3ycn0zfx7"))))
    (build-system python-build-system)
    (arguments
     `(#:python ,python-2))
    (native-inputs
     `(("python2-unittest2" ,python2-unittest2)))
    (home-page "http://funcsigs.readthedocs.org")
    (synopsis "Python function signatures from PEP362")
    (description
     "Backport of @code{funcsigs} which was introduced in Python 3.3.")
    (license license:asl2.0)))

(define-public python-unittest2
  (package
    (name "python-unittest2")
    (version "0.5.1")
    (version "1.1.0")
    (source
     (origin
       (method url-fetch)
       (uri (string-append
             "https://pypi.python.org/packages/source/u/unittest2py3k/unittest2py3k-"
             version ".tar.gz"))
       (uri (pypi-uri "unittest2" version))
       (patches
        (search-patches "python-unittest2-python3-compat.patch"
                        "python-unittest2-remove-argparse.patch"))
       (sha256
        (base32
         "00yl6lskygcrddx5zspkhr0ibgvpknl4678kkm6s626539grq93q"))))
         "0y855kmx7a8rnf81d3lh5lyxai1908xjp0laf4glwa4c8472m212"))))
    (build-system python-build-system)
    (arguments
     '(#:phases
       (modify-phases %standard-phases
         (replace 'check
           (lambda _
             (zero? (system* "python" "-m" "unittest2" "discover" "--verbose")))))))
    (propagated-inputs
     `(("python-six" ,python-six)
       ("python-traceback2" ,python-traceback2)))
    (home-page "http://pypi.python.org/pypi/unittest2")
    (synopsis "Python unit testing library")
    (description


@@ 1838,26 1896,7 @@ standard library.")
    (license license:psfl)))

(define-public python2-unittest2
  (package (inherit python-unittest2)
    (name "python2-unittest2")
    (version "1.1.0")
    (source
     (origin
       (method url-fetch)
       (uri (string-append
             "https://pypi.python.org/packages/source/u/unittest2/unittest2-"
             version ".tar.gz"))
       (sha256
        (base32
         "0y855kmx7a8rnf81d3lh5lyxai1908xjp0laf4glwa4c8472m212"))
       (patches
        (search-patches "python2-unittest2-remove-argparse.patch"))))
    (propagated-inputs
     `(("python2-six" ,python2-six)
       ("python2-traceback2" ,python2-traceback2)))
    (arguments
     `(#:python ,python-2
       #:tests? #f)))) ; no setup.py test command
  (package-with-python2 python-unittest2))

(define-public python-pafy
  (package


@@ 1886,14 1925,14 @@ standard library.")
(define-public python-py
  (package
    (name "python-py")
    (version "1.4.32")
    (version "1.4.34")
    (source
     (origin
       (method url-fetch)
       (uri (pypi-uri "py" version))
       (sha256
        (base32
         "19s1pql9pq85h1qzsdwgyb8a3k1qgkvh33b02m8kfqhizz8rzf64"))))
         "1qyd5z0hv8ymxy84v5vig3vps2fvhcf4bdlksb3r03h549fmhb8g"))))
    (build-system python-build-system)
    (arguments
     ;; FIXME: "ImportError: 'test' module incorrectly imported from


@@ 1914,30 1953,39 @@ code introspection, and logging.")
(define-public python-pytest
  (package
    (name "python-pytest")
    (version "2.7.3")
    (version "3.2.3")
    (source
     (origin
       (method url-fetch)
       (uri (string-append
             "https://pypi.python.org/packages/source/p/pytest/pytest-"
             version ".tar.gz"))
       (uri (pypi-uri "pytest" version))
       (sha256
        (base32
         "1z4yi986f9n0p8qmzmn21m21m8j1x78hk3505f89baqm6pdw7afm"))
       (modules '((guix build utils)))
       (snippet
        ;; One of the tests involves the /usr directory, so it fails.
        '(substitute* "testing/test_argcomplete.py"
           (("def test_remove_dir_prefix\\(self\\):")
            "@pytest.mark.xfail\n    def test_remove_dir_prefix(self):")))))
         "0g6w86ks73fnrnsyib9ii2rbyx830vn7aglsjqz9v1n2xwbndyi7"))))
    (build-system python-build-system)
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (add-before 'check 'disable-invalid-tests
           (lambda _
             ;; Some tests involves the /usr directory, and fails.
             (substitute* "testing/test_argcomplete.py"
               (("def test_remove_dir_prefix\\(self\\):")
                "@pytest.mark.xfail\n    def test_remove_dir_prefix(self):"))
             (substitute* "testing/test_argcomplete.py"
               (("def test_remove_dir_prefix" line)
                (string-append "@pytest.mark.skip"
                               "(reason=\"Assumes that /usr exists.\")\n    "
                               line)))
             #t)))))
    (propagated-inputs
     `(("python-py" ,python-py)))
    (native-inputs
     `(;; Tests need the "regular" bash since 'bash-final' lacks `compgen`.
       ("bash" ,bash)
       ("python-hypothesis" ,python-hypothesis)
       ("python-nose" ,python-nose)
       ("python-mock" ,python-mock)))
       ("python-mock" ,python-mock)
       ("python-setuptools-scm" ,python-setuptools-scm)))
    (home-page "http://pytest.org")
    (synopsis "Python testing library")
    (description


@@ 1949,41 1997,15 @@ and many external plugins.")
(define-public python2-pytest
  (package-with-python2 python-pytest))

;; Some packages require a newer pytest.
(define-public python-pytest-3.0
(define-public python-pytest-bootstrap
  (package
    (inherit python-pytest)
    (name "python-pytest")
    (version "3.0.7")
    (source (origin
              (method url-fetch)
              (uri (pypi-uri "pytest" version))
              (sha256
               (base32
                "1asc4b2nd2a4f0g3r12y97rslq5wliji7b73wwkvdrm5s7mrc1mp"))))
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (add-before 'check 'disable-invalid-test
           (lambda _
             (substitute* "testing/test_argcomplete.py"
               (("def test_remove_dir_prefix" line)
                (string-append "@pytest.mark.skip"
                               "(reason=\"Assumes that /usr exists.\")\n    "
                               line)))
             #t)))))
    (native-inputs
     `(("python-hypothesis" ,python-hypothesis)
       ,@(package-native-inputs python-pytest)))
    (properties `((python2-variant . ,(delay python2-pytest-3.0))))))
    (name "python-pytest-bootstrap")
    (native-inputs `(("python-setuptools-scm" ,python-setuptools-scm)))
    (arguments `(#:tests? #f))))

(define-public python2-pytest-3.0
  (let ((base (package-with-python2
                (strip-python2-variant python-pytest-3.0))))
    (package (inherit base)
      (native-inputs
        `(("python2-enum34" ,python2-enum34)
          ,@(package-native-inputs base))))))
(define-public python2-pytest-bootstrap
  (package-with-python2 python-pytest-bootstrap))

(define-public python-pytest-cov
  (package


@@ 2045,7 2067,7 @@ supports coverage of subprocesses.")
               (string-append "version = \"" ,version "\"")))
            #t)))))
    (native-inputs
     `(("python-pytest" ,python-pytest)
     `(("python-pytest" ,python-pytest-bootstrap)
       ("python-setuptools-scm" ,python-setuptools-scm)))
    (home-page "https://github.com/pytest-dev/pytest-runner")
    (synopsis "Invoke py.test as a distutils command")


@@ 2433,14 2455,14 @@ have failed since the last commit or what tests are currently failing.")
(define-public python-coverage
  (package
    (name "python-coverage")
    (version "4.1")
    (version "4.4.1")
    (source
     (origin
       (method url-fetch)
       (uri (pypi-uri "coverage" version))
       (sha256
        (base32
         "01rbr4br4lsk0lwn8fb96zwd2xr4f0mg1w7iq3j11i8f5ig2nqs1"))))
         "097l4s3ssxm1vncsn0nw3a1pbzah28773q36c1ab9wz01r04973s"))))
    (build-system python-build-system)
    (arguments
     ;; FIXME: 95 tests failed, 539 passed, 6 skipped, 2 errors.


@@ 2882,7 2904,7 @@ somewhat intelligible.")
           #t))))
    (build-system python-build-system)
    (native-inputs
     `(("python-pytest" ,python-pytest-3.0)
     `(("python-pytest" ,python-pytest)
       ("python-pytest-cov" ,python-pytest-cov)
       ("python-pytest-runner" ,python-pytest-runner)))
    (home-page "https://github.com/progrium/pyjwt")


@@ 3076,18 3098,6 @@ for Python.")
        (base32
         "1zzrkywhziqffrzks14kzixz7nd4yh2vc0fb04a68vfd2ai03anx"))))
    (build-system python-build-system)
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         ;; These files cannot be built with Python < 3.6.  See
         ;; https://github.com/pallets/jinja/issues/655
         ;; FIXME: Remove this when the "python" package is upgraded.
         (add-after 'unpack 'delete-incompatible-files
           (lambda _
             (for-each delete-file
                       '("jinja2/asyncsupport.py"
                         "jinja2/asyncfilters.py"))
             #t)))))
    (propagated-inputs
     `(("python-markupsafe" ,python-markupsafe)))
    (home-page "http://jinja.pocoo.org/")


@@ 3338,7 3348,7 @@ sources.")
     `(("python-sphinxcontrib-websupport" ,python-sphinxcontrib-websupport)
       ,@(package-propagated-inputs python-sphinx)))
    (native-inputs
     `(("python-pytest" ,python-pytest-3.0)
     `(("python-pytest" ,python-pytest)
       ("imagemagick" ,imagemagick) ; for "convert"
       ,@(package-native-inputs python-sphinx)))
    (properties '())))


@@ 3356,7 3366,7 @@ sources.")
        (base32
         "0kw1axswbvaavr8ggyf4qr6hnisnrzlbkkcdada69vk1x9xjassg"))))
    (native-inputs
     `(("python-pytest" ,python-pytest-3.0)
     `(("python-pytest" ,python-pytest)
       ,@(package-native-inputs python-sphinx)))))

(define-public python2-sphinx


@@ 5307,7 5317,7 @@ Python language binding specification.")
    (arguments '(#:tests? #f)) ; Test file 'grako.ebnf' is missing from archive.
    (native-inputs
     `(("unzip" ,unzip)
       ("python-pytest" ,python-pytest-3.0)
       ("python-pytest" ,python-pytest)
       ("python-pytest-runner" ,python-pytest-runner)))
    (home-page "https://bitbucket.org/neogeny/grako")
    (synopsis "EBNF parser generator")


@@ 5365,7 5375,7 @@ cluster without needing to write any wrapper code yourself.")
        (base32 "0zizn61n5z5hq421hkypk9pw8s6fpxw30f4hsg7k4ivwzy3gjw9j"))))
    (build-system python-build-system)
    (native-inputs
     `(("python-pytest" ,python-pytest-3.0)
     `(("python-pytest" ,python-pytest)
       ("python-mock" ,python-mock)
       ("python-tox" ,python-tox)
       ("which" ,which))) ;for tests


@@ 5428,7 5438,7 @@ displayed.")
         (replace 'check (lambda _ (zero? (system* "nosetests" "-v")))))))
    (native-inputs
     `(("python-nose" ,python-nose)
       ("python-pytest" ,python-pytest-3.0)
       ("python-pytest" ,python-pytest)
       ("man-db" ,man-db)
       ("which" ,which)
       ("bash-full" ,bash)))                 ;full Bash for 'test_replwrap.py'


@@ 5449,13 5459,13 @@ child application and control it as if a human were typing commands.")
(define-public python-setuptools-scm
  (package
    (name "python-setuptools-scm")
    (version "1.15.0")
    (version "1.15.6")
    (source (origin
              (method url-fetch)
              (uri (pypi-uri "setuptools_scm" version))
              (sha256
               (base32
                "0bwyc5markib0i7i2qlyhdzxhiywzxbkfiapldma8m91m82jvwfs"))))
                "0pzvfmx8s20yrgkgwfbxaspz2x1g38qv61jpm0ns91lrb22ldas9"))))
    (build-system python-build-system)
    (home-page "https://github.com/pypa/setuptools_scm/")
    (synopsis "Manage Python package versions in SCM metadata")


@@ 6990,14 7000,14 @@ PEP 8.")
(define-public python-pyflakes
  (package
    (name "python-pyflakes")
    (version "1.0.0")
    (version "1.5.0")
    (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "pyflakes" version))
        (sha256
          (base32
            "0qs2sgqszq7wcplis8509wk2ygqcrwzbs1ghfj3svvivq2j377pk"))))
            "1x1pcca4a24k4pw8x1c77sgi58cg1wl2k38mp8a25k608pzls3da"))))
    (build-system python-build-system)
    (home-page
      "https://github.com/pyflakes/pyflakes")


@@ 7012,17 7022,17 @@ PEP 8.")
(define-public python-mccabe
  (package
    (name "python-mccabe")
    (version "0.4.0")
    (version "0.6.1")
    (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "mccabe" version))
        (sha256
          (base32
            "0yr08a36h8lqlif10l4xcikbbig7q8f41gqywir7rrvnv3mi4aws"))))
            "07w3p1qm44hgxf3vvwz84kswpsx6s7kvaibzrsx5dzm0hli1i3fx"))))
    (build-system python-build-system)
    (native-inputs
      `(("python-pytest" ,python-pytest)
      `(("python-pytest" ,python-pytest-bootstrap)
        ("python-pytest-runner" ,python-pytest-runner)))
    (home-page "https://github.com/flintwork/mccabe")
    (synopsis "McCabe checker, plugin for flake8")


@@ 7095,39 7105,48 @@ complexity of Python source code.")
(define-public python-flake8
  (package
    (name "python-flake8")
    (version "2.5.4")
    (version "3.4.1")
    (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "flake8" version))
        (sha256
          (base32
            "0bs9cz4fr99r2rwig1b8jwaadl1nan7kgpdzqwj0bwbckwbmh7nc"))
        (modules '((guix build utils)))
        (snippet
         '(begin
            ;; Remove pre-compiled .pyc files from source.
            (for-each delete-file-recursively
                      (find-files "." "__pycache__" #:directories? #t))
            (for-each delete-file (find-files "." "\\.pyc$"))
            #t))))
            "1n0i38592vy3q0x2a9bf8z6rhhn04i30wsn5i5zzcj7qkxvl8062"))))
    (build-system python-build-system)
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (delete 'check)
         (add-after 'install 'check
          (lambda* (#:key inputs outputs #:allow-other-keys)
            (add-installed-pythonpath inputs outputs)
            (zero? (system* "pytest" "-v")))))))
    (propagated-inputs
      `(("python-pep8" ,python-pep8)
      `(("python-pycodestyle" ,python-pycodestyle)
        ("python-pyflakes" ,python-pyflakes)
        ;; flake8 depends on a newer setuptools than provided by python.
        ("python-setuptools" ,python-setuptools)
        ("python-mccabe" ,python-mccabe)))
    (native-inputs
      `(("python-mock" ,python-mock) ; TODO: only required for < 3.3
        ("python-nose" ,python-nose)))
        ("python-pytest" ,python-pytest-bootstrap)
        ("python-pytest-runner" ,python-pytest-runner)))
    (home-page "https://gitlab.com/pycqa/flake8")
    (synopsis
      "The modular source code checker: pep8, pyflakes and co")
    (description
      "Flake8 is a wrapper around PyFlakes, pep8 and python-mccabe.")
    (properties `((python2-variant . ,(delay python2-flake8))))
    (license license:expat)))

(define-public python2-flake8
  (package-with-python2 python-flake8))
  (let ((base (package-with-python2 (strip-python2-variant python-flake8))))
    (package (inherit base)
      (propagated-inputs
       `(("python2-configparser" ,python2-configparser)
         ("python2-enum" ,python2-enum)
          ,@(package-propagated-inputs base))))))

(define-public python-flake8-polyfill
  (package


@@ 8008,7 8027,7 @@ responses, rather than doing any computation.")
       ("python-hypothesis" ,python-hypothesis)
       ("python-pretend" ,python-pretend)
       ("python-pytz" ,python-pytz)
       ("python-pytest" ,python-pytest-3.0)))
       ("python-pytest" ,python-pytest)))
    (home-page "https://github.com/pyca/cryptography")
    (synopsis "Cryptographic recipes and primitives for Python")
    (description


@@ 8068,7 8087,7 @@ message digests and key derivation functions.")
    (native-inputs
     `(("python-flaky" ,python-flaky)
       ("python-pretend" ,python-pretend)
       ("python-pytest" ,python-pytest-3.0)))
       ("python-pytest" ,python-pytest)))
    (home-page "https://github.com/pyca/pyopenssl")
    (synopsis "Python wrapper module around the OpenSSL library")
    (description


@@ 10138,7 10157,7 @@ Amazon Web Services (AWS) API.")
    (build-system python-build-system)
    (native-inputs
     `(("python-flake8" ,python-flake8)
       ("python-pytest" ,python-pytest)))
       ("python-pytest" ,python-pytest-bootstrap)))
    (synopsis "Library for property based testing")
    (description "Hypothesis is a library for testing your Python code against a
much larger range of examples than you would ever want to write by hand.  It’s


@@ 15035,7 15054,7 @@ for Flask.")
         "0gf2dpahpl5igb7jh1sr9acj3z3gp7zahqdqb69nk6wx01c8kc1g"))))
    (build-system python-build-system)
    (propagated-inputs
     `(("pytest" ,python-pytest-3.0)))
     `(("pytest" ,python-pytest)))
    (home-page "https://github.com/fschulze/pytest-warnings")
    (synopsis "Pytest plugin to list Python warnings in pytest report")
    (description


@@ 15059,7 15078,7 @@ pytest report.")
         "038049nyjl7di59ycnxvc9nydivc5m8np3hqq84j2iirkccdbs5n"))))
    (build-system python-build-system)
    (propagated-inputs
     `(("pytest" ,python-pytest-3.0)))
     `(("pytest" ,python-pytest)))
    (home-page "http://bitbucket.org/memedough/pytest-capturelog/overview")
    (synopsis "Pytest plugin to catch log messages")
    (description


@@ 15084,7 15103,7 @@ pytest report.")
    (native-inputs
     `(("unzip" ,unzip)))
    (propagated-inputs
     `(("pytest" ,python-pytest-3.0)))
     `(("pytest" ,python-pytest)))
    (home-page "https://github.com/eisensheng/pytest-catchlog")
    (synopsis "Pytest plugin to catch log messages")
    (description


@@ 16075,7 16094,7 @@ address is valid and really exists.")
     `(("python-dateutil" ,python-dateutil)
       ("python-simplejson" ,python-simplejson)))
    (native-inputs
     `(("python-pytest-3.0" ,python-pytest-3.0)
     `(("python-pytest" ,python-pytest)
       ("python-pytz" ,python-pytz)))
    (home-page "https://github.com/marshmallow-code/marshmallow")
    (synopsis "Convert complex datatypes to and from native


@@ 16122,7 16141,7 @@ complex datatypes to and from native Python datatypes.")
    (propagated-inputs
     `(("python-pyyaml" ,python-pyyaml)))
    (native-inputs
     `(("python-pytest-3.0" ,python-pytest-3.0)
     `(("python-pytest" ,python-pytest)
       ("python-flask" ,python-flask)
       ("python-marshmallow" ,python-marshmallow)
       ("python-tornado" ,python-tornado)


@@ 16175,7 16194,7 @@ Swagger 2.0).")
       ("python-flake8" ,python-flake8)
       ("python-flask-restful" ,python-flask-restful)
       ("python-flex" ,python-flex)
       ("python-pytest-3.0" ,python-pytest-3.0)
       ("python-pytest" ,python-pytest)
       ("python-pytest-cov" ,python-pytest-cov)
       ("python-marshmallow" ,python-marshmallow)
       ("python-apispec" ,python-apispec)))


@@ 16678,7 16697,7 @@ their files and supports any packaging format (including wheels).")
     `(;; The tests depend on unittest2, and our version is a bit too old.
       #:tests? #f))
    (native-inputs
     `(("python-pbr" ,python-pbr)))
     `(("python-pbr" ,python-pbr-minimal)))
    (home-page
      "https://github.com/testing-cabal/linecache2")
    (synopsis "Backports of the linecache module")


@@ 16707,7 16726,7 @@ lines are read from a single file.")
     `(;; python-traceback2 and python-unittest2 depend on one another.
       #:tests? #f))
    (native-inputs
     `(("python-pbr" ,python-pbr)))
     `(("python-pbr" ,python-pbr-minimal)))
    (propagated-inputs
      `(("python-linecache2" ,python-linecache2)))
    (home-page

M gnu/packages/tls.scm => gnu/packages/tls.scm +2 -2
@@ 515,7 515,7 @@ netcat implementation that supports TLS.")
               #t))))))
    ;; TODO: Add optional inputs for testing.
    (native-inputs
     `(("python-mock" ,python-mock-2)
     `(("python-mock" ,python-mock)
       ;; For documentation
       ("python-sphinx" ,python-sphinx)
       ("python-sphinxcontrib-programoutput" ,python-sphinxcontrib-programoutput)


@@ 564,7 564,7 @@ netcat implementation that supports TLS.")
    ;; TODO: Add optional inputs for testing.
    (native-inputs
     `(("python-nose" ,python-nose)
       ("python-mock" ,python-mock-2)
       ("python-mock" ,python-mock)
       ;; For documentation
       ("python-sphinx" ,python-sphinx)
       ("python-sphinx-rtd-theme" ,python-sphinx-rtd-theme)

M gnu/packages/web.scm => gnu/packages/web.scm +1 -1
@@ 5154,7 5154,7 @@ command-line arguments or read from stdin.")
       ("python-schema" ,python-schema-0.5)
       ("python-backports-csv" ,python-backports-csv)))
    (native-inputs
     `(("python-pytest-3.0" ,python-pytest-3.0)
     `(("python-pytest" ,python-pytest)
       ("python-pytest-capturelog" ,python-pytest-capturelog)
       ("python-responses" ,python-responses)))
    (home-page "https://github.com/jjjake/internetarchive")