Merge remote-tracking branch 'origin/python-updates' into core-updates
This commit is contained in:
		
						commit
						eda8a841ac
					
				
					 14 changed files with 394 additions and 1016 deletions
				
			
		| 
						 | 
					@ -958,14 +958,13 @@ dist_patch_DATA =						\
 | 
				
			||||||
  %D%/packages/patches/pygpgme-disable-problematic-tests.patch  \
 | 
					  %D%/packages/patches/pygpgme-disable-problematic-tests.patch  \
 | 
				
			||||||
  %D%/packages/patches/pyqt-configure.patch			\
 | 
					  %D%/packages/patches/pyqt-configure.patch			\
 | 
				
			||||||
  %D%/packages/patches/python-2-deterministic-build-info.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-search-paths.patch		\
 | 
				
			||||||
  %D%/packages/patches/python-2.7-site-prefixes.patch		\
 | 
					  %D%/packages/patches/python-2.7-site-prefixes.patch		\
 | 
				
			||||||
  %D%/packages/patches/python-2.7-source-date-epoch.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-deterministic-build-info.patch	\
 | 
				
			||||||
  %D%/packages/patches/python-3-search-paths.patch		\
 | 
					  %D%/packages/patches/python-3-search-paths.patch		\
 | 
				
			||||||
  %D%/packages/patches/python-3.5-fix-tests.patch		\
 | 
					  %D%/packages/patches/python-3-fix-tests.patch			\
 | 
				
			||||||
  %D%/packages/patches/python-3.5-getentropy-on-old-kernels.patch	\
 | 
					 | 
				
			||||||
  %D%/packages/patches/python-dendropy-fix-tests.patch		\
 | 
					  %D%/packages/patches/python-dendropy-fix-tests.patch		\
 | 
				
			||||||
  %D%/packages/patches/python-fix-tests.patch			\
 | 
					  %D%/packages/patches/python-fix-tests.patch			\
 | 
				
			||||||
  %D%/packages/patches/python-genshi-add-support-for-python-3.4-AST.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/python2-pygobject-2-gi-info-type-error-domain.patch \
 | 
				
			||||||
  %D%/packages/patches/python-pygpgme-fix-pinentry-tests.patch	\
 | 
					  %D%/packages/patches/python-pygpgme-fix-pinentry-tests.patch	\
 | 
				
			||||||
  %D%/packages/patches/python2-subprocess32-disable-input-test.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/qt4-ldflags.patch			\
 | 
				
			||||||
  %D%/packages/patches/qtscript-disable-tests.patch		\
 | 
					  %D%/packages/patches/qtscript-disable-tests.patch		\
 | 
				
			||||||
  %D%/packages/patches/quagga-reproducible-build.patch          \
 | 
					  %D%/packages/patches/quagga-reproducible-build.patch          \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -522,9 +522,7 @@ detection, and lossless compression.")
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-cython" ,python-cython)
 | 
					     `(("python-cython" ,python-cython)
 | 
				
			||||||
       ("python-setuptools-scm" ,python-setuptools-scm)
 | 
					       ("python-setuptools-scm" ,python-setuptools-scm)
 | 
				
			||||||
       ;; Borg 1.0.8's test suite uses 'tmpdir_factory', which was introduced in
 | 
					       ("python-pytest" ,python-pytest)
 | 
				
			||||||
       ;; pytest 2.8.
 | 
					 | 
				
			||||||
       ("python-pytest" ,python-pytest-3.0)
 | 
					 | 
				
			||||||
       ;; For generating the documentation.
 | 
					       ;; For generating the documentation.
 | 
				
			||||||
       ("python-sphinx" ,python-sphinx)
 | 
					       ("python-sphinx" ,python-sphinx)
 | 
				
			||||||
       ("python-guzzle-sphinx-theme" ,python-guzzle-sphinx-theme)))
 | 
					       ("python-guzzle-sphinx-theme" ,python-guzzle-sphinx-theme)))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,8 +118,7 @@ data units.")
 | 
				
			||||||
                              "not test_printics_read_from_stdin "
 | 
					                              "not test_printics_read_from_stdin "
 | 
				
			||||||
                              "and not test_import_from_stdin"))))))))
 | 
					                              "and not test_import_from_stdin"))))))))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
      ;; XXX Uses tmpdir_factory, introduced in pytest 2.8.
 | 
					     `(("python-pytest" ,python-pytest)
 | 
				
			||||||
     `(("python-pytest" ,python-pytest-3.0)
 | 
					 | 
				
			||||||
       ("python-pytest-cov" ,python-pytest-cov)
 | 
					       ("python-pytest-cov" ,python-pytest-cov)
 | 
				
			||||||
       ("python-setuptools-scm" ,python-setuptools-scm)
 | 
					       ("python-setuptools-scm" ,python-setuptools-scm)
 | 
				
			||||||
       ;; Required for tests
 | 
					       ;; Required for tests
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1814,7 +1814,7 @@ Memory-Mapped Database} (LMDB), a high-performance key-value store.")
 | 
				
			||||||
             #t)))))
 | 
					             #t)))))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-pytest-mock" ,python-pytest-mock)
 | 
					     `(("python-pytest-mock" ,python-pytest-mock)
 | 
				
			||||||
       ("python-pytest" ,python-pytest-3.0)
 | 
					       ("python-pytest" ,python-pytest)
 | 
				
			||||||
       ("python-flexmock" ,python-flexmock)))
 | 
					       ("python-flexmock" ,python-flexmock)))
 | 
				
			||||||
    (propagated-inputs
 | 
					    (propagated-inputs
 | 
				
			||||||
     `(("python-backpack" ,python-backpack)
 | 
					     `(("python-backpack" ,python-backpack)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										22
									
								
								gnu/packages/patches/python-2.7-adjust-tests.patch
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								gnu/packages/patches/python-2.7-adjust-tests.patch
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										149
									
								
								gnu/packages/patches/python-3-fix-tests.patch
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								gnu/packages/patches/python-3-fix-tests.patch
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,149 @@
 | 
				
			||||||
 | 
					Additional test fixes which affect Python 3.5 (and presumably later) but not
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					@@ -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')
 | 
				
			||||||
 | 
					--- 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 @@
 | 
				
			||||||
 | 
					     try:
 | 
				
			||||||
 | 
					         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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- Lib/test/test_asyncio/test_base_events.py
 | 
				
			||||||
 | 
					+++ Lib/test/test_asyncio/test_base_events.py
 | 
				
			||||||
 | 
					@@ -1216,6 +1216,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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--- Lib/test/test_pdb.py.org    2017-03-12 03:09:01.991856701 +0100
 | 
				
			||||||
 | 
					+++ Lib/test/test_pdb.py        2017-03-12 03:26:17.742572869 +0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For some reason, KeyboardInterrupts do not work in the build
 | 
				
			||||||
 | 
					environment (lack of controlling TTY?). Just change the expected
 | 
				
			||||||
 | 
					outcome. Unfortunately, this will make it fail for users running
 | 
				
			||||||
 | 
					`python -m test test_pdb test_pdb` interactively.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@@ -928,11 +928,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]>(5)test_function()
 | 
				
			||||||
 | 
					     -> sess.set_trace(sys._getframe())
 | 
				
			||||||
 | 
					     (Pdb) continue
 | 
				
			||||||
 | 
					-    pdb 2: <built-in function default_int_handler>
 | 
				
			||||||
 | 
					+    pdb 2: Handlers.SIG_IGN
 | 
				
			||||||
 | 
					     """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 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}")
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
| 
						 | 
					@ -1,69 +0,0 @@
 | 
				
			||||||
Additional test fixes which affect Python 3.5 (and presumably later) but not
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
         self.assertEqual(given, expect)
 | 
					 | 
				
			||||||
         self.assertEqual(set(p.rglob("FILEd*")), set())
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
+    @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 @@
 | 
					 | 
				
			||||||
     try:
 | 
					 | 
				
			||||||
         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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- Lib/test/test_asyncio/test_base_events.py
 | 
					 | 
				
			||||||
+++ Lib/test/test_asyncio/test_base_events.py
 | 
					 | 
				
			||||||
@@ -1216,6 +1216,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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- Lib/test/test_pdb.py.org    2017-03-12 03:09:01.991856701 +0100
 | 
					 | 
				
			||||||
+++ Lib/test/test_pdb.py        2017-03-12 03:26:17.742572869 +0100
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
For some reason, KeyboardInterrupts do not work in the build
 | 
					 | 
				
			||||||
environment (lack of controlling TTY?). Just change the expected
 | 
					 | 
				
			||||||
outcome. Unfortunately, this will make it fail for users running
 | 
					 | 
				
			||||||
`python -m test test_pdb test_pdb` interactively.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -928,11 +928,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]>(5)test_function()
 | 
					 | 
				
			||||||
     -> sess.set_trace(sys._getframe())
 | 
					 | 
				
			||||||
     (Pdb) continue
 | 
					 | 
				
			||||||
-    pdb 2: <built-in function default_int_handler>
 | 
					 | 
				
			||||||
+    pdb 2: Handlers.SIG_IGN
 | 
					 | 
				
			||||||
     """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 class PdbTestCase(unittest.TestCase):
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										34
									
								
								gnu/packages/patches/python-unittest2-python3-compat.patch
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								gnu/packages/patches/python-unittest2-python3-compat.patch
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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()
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
| 
						 | 
					@ -132,7 +132,7 @@
 | 
				
			||||||
(define-public python-2.7
 | 
					(define-public python-2.7
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (name "python")
 | 
					    (name "python")
 | 
				
			||||||
    (version "2.7.13")
 | 
					    (version "2.7.14")
 | 
				
			||||||
    (source
 | 
					    (source
 | 
				
			||||||
     (origin
 | 
					     (origin
 | 
				
			||||||
      (method url-fetch)
 | 
					      (method url-fetch)
 | 
				
			||||||
| 
						 | 
					@ -140,12 +140,12 @@
 | 
				
			||||||
                          version "/Python-" version ".tar.xz"))
 | 
					                          version "/Python-" version ".tar.xz"))
 | 
				
			||||||
      (sha256
 | 
					      (sha256
 | 
				
			||||||
       (base32
 | 
					       (base32
 | 
				
			||||||
        "0cgpk3zk0fgpji59pb4zy9nzljr70qzgv1vpz5hq5xw2d2c47m9m"))
 | 
					        "0rka541ys16jwzcnnvjp2v12m4cwgd2jp6wj4kj511p715pb5zvi"))
 | 
				
			||||||
      (patches (search-patches "python-2.7-search-paths.patch"
 | 
					      (patches (search-patches "python-2.7-search-paths.patch"
 | 
				
			||||||
                               "python-2-deterministic-build-info.patch"
 | 
					                               "python-2-deterministic-build-info.patch"
 | 
				
			||||||
                               "python-2.7-site-prefixes.patch"
 | 
					                               "python-2.7-site-prefixes.patch"
 | 
				
			||||||
                               "python-2.7-source-date-epoch.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)))
 | 
					      (modules '((guix build utils)))
 | 
				
			||||||
      ;; suboptimal to delete failing tests here, but if we delete them in the
 | 
					      ;; 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
 | 
					      ;; arguments then we need to make sure to strip out that phase when it
 | 
				
			||||||
| 
						 | 
					@ -203,6 +203,7 @@
 | 
				
			||||||
                                  '("Lib/subprocess.py"
 | 
					                                  '("Lib/subprocess.py"
 | 
				
			||||||
                                    "Lib/popen2.py"
 | 
					                                    "Lib/popen2.py"
 | 
				
			||||||
                                    "Lib/distutils/tests/test_spawn.py"
 | 
					                                    "Lib/distutils/tests/test_spawn.py"
 | 
				
			||||||
 | 
					                                    "Lib/test/support/__init__.py"
 | 
				
			||||||
                                    "Lib/test/test_subprocess.py"))
 | 
					                                    "Lib/test/test_subprocess.py"))
 | 
				
			||||||
               (("/bin/sh") (which "sh")))
 | 
					               (("/bin/sh") (which "sh")))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -328,28 +329,28 @@ data types.")
 | 
				
			||||||
;; Current 2.x version.
 | 
					;; Current 2.x version.
 | 
				
			||||||
(define-public python-2 python-2.7)
 | 
					(define-public python-2 python-2.7)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-public python-3.5
 | 
					(define-public python-3.6
 | 
				
			||||||
  (package (inherit python-2)
 | 
					  (package (inherit python-2)
 | 
				
			||||||
    (version "3.5.3")
 | 
					    (version "3.6.3")
 | 
				
			||||||
    (source (origin
 | 
					    (source (origin
 | 
				
			||||||
              (method url-fetch)
 | 
					              (method url-fetch)
 | 
				
			||||||
              (uri (string-append "https://www.python.org/ftp/python/"
 | 
					              (uri (string-append "https://www.python.org/ftp/python/"
 | 
				
			||||||
                                  version "/Python-" version ".tar.xz"))
 | 
					                                  version "/Python-" version ".tar.xz"))
 | 
				
			||||||
              (patches (search-patches
 | 
					              (patches (search-patches
 | 
				
			||||||
                        "python-fix-tests.patch"
 | 
					                        "python-fix-tests.patch"
 | 
				
			||||||
                        "python-3.5-fix-tests.patch"
 | 
					                        "python-3-fix-tests.patch"
 | 
				
			||||||
                        "python-3.5-getentropy-on-old-kernels.patch"
 | 
					 | 
				
			||||||
                        "python-3-deterministic-build-info.patch"
 | 
					                        "python-3-deterministic-build-info.patch"
 | 
				
			||||||
                        "python-3-search-paths.patch"))
 | 
					                        "python-3-search-paths.patch"))
 | 
				
			||||||
              (patch-flags '("-p0"))
 | 
					              (patch-flags '("-p0"))
 | 
				
			||||||
              (sha256
 | 
					              (sha256
 | 
				
			||||||
               (base32
 | 
					               (base32
 | 
				
			||||||
                "1c6v1n9nz4mlx9mw1125fxpmbrgniqdbbx9hnqx44maqazb2mzpf"))
 | 
					                "1nl1raaagr4car787a2hmjv2dw6gqny53xfd6wisbgx4r5kxk9yd"))
 | 
				
			||||||
              (snippet
 | 
					              (snippet
 | 
				
			||||||
               '(begin
 | 
					               '(begin
 | 
				
			||||||
                  (for-each delete-file
 | 
					                  (for-each delete-file
 | 
				
			||||||
                            '("Lib/ctypes/test/test_win32.py" ; fails on aarch64
 | 
					                            '("Lib/ctypes/test/test_structures.py" ; fails on aarch64
 | 
				
			||||||
                              "Lib/test/test_fcntl.py"))
 | 
					                              "Lib/ctypes/test/test_win32.py" ; fails on aarch64
 | 
				
			||||||
 | 
					                              "Lib/test/test_fcntl.py")) ; fails on aarch64
 | 
				
			||||||
                  #t))))
 | 
					                  #t))))
 | 
				
			||||||
    (arguments (substitute-keyword-arguments (package-arguments python-2)
 | 
					    (arguments (substitute-keyword-arguments (package-arguments python-2)
 | 
				
			||||||
                 ((#:tests? _) #t)))
 | 
					                 ((#:tests? _) #t)))
 | 
				
			||||||
| 
						 | 
					@ -361,7 +362,7 @@ data types.")
 | 
				
			||||||
                                        "/site-packages"))))))))
 | 
					                                        "/site-packages"))))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;; Current 3.x version.
 | 
					;; Current 3.x version.
 | 
				
			||||||
(define-public python-3 python-3.5)
 | 
					(define-public python-3 python-3.6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;; Current major version.
 | 
					;; Current major version.
 | 
				
			||||||
(define-public python python-3)
 | 
					(define-public python python-3)
 | 
				
			||||||
| 
						 | 
					@ -933,45 +934,43 @@ API for locking files.")
 | 
				
			||||||
(define-public python-mock
 | 
					(define-public python-mock
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (name "python-mock")
 | 
					    (name "python-mock")
 | 
				
			||||||
    (version "1.0.1")
 | 
					    (version "2.0.0")
 | 
				
			||||||
    (source
 | 
					    (source
 | 
				
			||||||
     (origin
 | 
					     (origin
 | 
				
			||||||
       (method url-fetch)
 | 
					       (method url-fetch)
 | 
				
			||||||
       (uri (pypi-uri "mock" version))
 | 
					       (uri (pypi-uri "mock" version))
 | 
				
			||||||
       (sha256
 | 
					       (sha256
 | 
				
			||||||
        (base32
 | 
					        (base32
 | 
				
			||||||
         "0kzlsbki6q0awf89rc287f3aj8x431lrajf160a70z0ikhnxsfdq"))))
 | 
					         "1flbpksir5sqrvq2z0dp8sl4bzbadg21sj4d42w3klpdfvgvcn5i"))))
 | 
				
			||||||
 | 
					    (propagated-inputs
 | 
				
			||||||
 | 
					     `(("python-pbr" ,python-pbr-minimal)
 | 
				
			||||||
 | 
					       ("python-six" ,python-six)))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (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")
 | 
					    (home-page "https://github.com/testing-cabal/mock")
 | 
				
			||||||
    (synopsis "Python mocking and patching library for testing")
 | 
					    (synopsis "Python mocking and patching library for testing")
 | 
				
			||||||
    (description
 | 
					    (description
 | 
				
			||||||
     "Mock is a library for testing in Python.  It allows you to replace parts
 | 
					     "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
 | 
					of your system under test with mock objects and make assertions about how they
 | 
				
			||||||
have been used.")
 | 
					have been used.")
 | 
				
			||||||
 | 
					    (properties `((python2-variant . ,(delay python2-mock))))
 | 
				
			||||||
    (license license:expat)))
 | 
					    (license license:expat)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-public python2-mock
 | 
					(define-public python2-mock
 | 
				
			||||||
  (package-with-python2 python-mock))
 | 
					  (let ((base (package-with-python2
 | 
				
			||||||
 | 
					               (strip-python2-variant python-mock))))
 | 
				
			||||||
;;; Some packages (notably, certbot and python-acme) rely on this newer version
 | 
					    (package (inherit base)
 | 
				
			||||||
;;; of python-mock. However, a large number of packages fail to build with
 | 
					      (propagated-inputs
 | 
				
			||||||
;;; mock@2, so we add a new variable for now. Also, there may be a dependency
 | 
					       `(("python2-functools32" ,python2-functools32)
 | 
				
			||||||
;;; cycle between mock and six, so we avoid creating python2-mock@2 for now.
 | 
					         ("python2-funcsigs" ,python2-funcsigs)
 | 
				
			||||||
(define-public python-mock-2
 | 
					         ,@(package-propagated-inputs base))))))
 | 
				
			||||||
  (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)))))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-public python-setuptools
 | 
					(define-public python-setuptools
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
| 
						 | 
					@ -1169,18 +1168,24 @@ password storage.")
 | 
				
			||||||
(define-public python-six
 | 
					(define-public python-six
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (name "python-six")
 | 
					    (name "python-six")
 | 
				
			||||||
    (version "1.10.0")
 | 
					    (version "1.11.0")
 | 
				
			||||||
    (source
 | 
					    (source
 | 
				
			||||||
     (origin
 | 
					     (origin
 | 
				
			||||||
      (method url-fetch)
 | 
					      (method url-fetch)
 | 
				
			||||||
      (uri (pypi-uri "six" version))
 | 
					      (uri (pypi-uri "six" version))
 | 
				
			||||||
      (sha256
 | 
					      (sha256
 | 
				
			||||||
       (base32
 | 
					       (base32
 | 
				
			||||||
        "0snmb8xffb3vsma0z67i0h0w2g2dy0p3gsgh9gi4i0kgc5l8spqh"))))
 | 
					        "1scqzwc51c875z23phj48gircqjgnn3af8zy2izjwmnlxrxsgs3h"))))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (build-system python-build-system)
 | 
				
			||||||
 | 
					    (arguments
 | 
				
			||||||
 | 
					     `(#:phases
 | 
				
			||||||
 | 
					       (modify-phases %standard-phases
 | 
				
			||||||
 | 
					         (replace 'check
 | 
				
			||||||
 | 
					           (lambda _
 | 
				
			||||||
 | 
					             (zero? (system* "py.test" "-v")))))))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-py" ,python-py)
 | 
					     `(("python-py" ,python-py)
 | 
				
			||||||
       ("python-pytest" ,python-pytest)))
 | 
					       ("python-pytest" ,python-pytest-bootstrap)))
 | 
				
			||||||
    (home-page "http://pypi.python.org/pypi/six/")
 | 
					    (home-page "http://pypi.python.org/pypi/six/")
 | 
				
			||||||
    (synopsis "Python 2 and 3 compatibility utilities")
 | 
					    (synopsis "Python 2 and 3 compatibility utilities")
 | 
				
			||||||
    (description
 | 
					    (description
 | 
				
			||||||
| 
						 | 
					@ -1566,6 +1571,28 @@ bug tracker.")
 | 
				
			||||||
    (home-page "http://www.liquidx.net/pybugz/")
 | 
					    (home-page "http://www.liquidx.net/pybugz/")
 | 
				
			||||||
    (license license:gpl2)))
 | 
					    (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
 | 
					(define-public python-enum34
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (name "python-enum34")
 | 
					    (name "python-enum34")
 | 
				
			||||||
| 
						 | 
					@ -1816,20 +1843,51 @@ interfaces and processes.")
 | 
				
			||||||
(define-public python2-nose2
 | 
					(define-public python2-nose2
 | 
				
			||||||
  (package-with-python2 python-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
 | 
					(define-public python-unittest2
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (name "python-unittest2")
 | 
					    (name "python-unittest2")
 | 
				
			||||||
    (version "0.5.1")
 | 
					    (version "1.1.0")
 | 
				
			||||||
    (source
 | 
					    (source
 | 
				
			||||||
     (origin
 | 
					     (origin
 | 
				
			||||||
       (method url-fetch)
 | 
					       (method url-fetch)
 | 
				
			||||||
       (uri (string-append
 | 
					       (uri (pypi-uri "unittest2" version))
 | 
				
			||||||
             "https://pypi.python.org/packages/source/u/unittest2py3k/unittest2py3k-"
 | 
					       (patches
 | 
				
			||||||
             version ".tar.gz"))
 | 
					        (search-patches "python-unittest2-python3-compat.patch"
 | 
				
			||||||
 | 
					                        "python-unittest2-remove-argparse.patch"))
 | 
				
			||||||
       (sha256
 | 
					       (sha256
 | 
				
			||||||
        (base32
 | 
					        (base32
 | 
				
			||||||
         "00yl6lskygcrddx5zspkhr0ibgvpknl4678kkm6s626539grq93q"))))
 | 
					         "0y855kmx7a8rnf81d3lh5lyxai1908xjp0laf4glwa4c8472m212"))))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (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")
 | 
					    (home-page "http://pypi.python.org/pypi/unittest2")
 | 
				
			||||||
    (synopsis "Python unit testing library")
 | 
					    (synopsis "Python unit testing library")
 | 
				
			||||||
    (description
 | 
					    (description
 | 
				
			||||||
| 
						 | 
					@ -1838,26 +1896,7 @@ standard library.")
 | 
				
			||||||
    (license license:psfl)))
 | 
					    (license license:psfl)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-public python2-unittest2
 | 
					(define-public python2-unittest2
 | 
				
			||||||
  (package (inherit python-unittest2)
 | 
					  (package-with-python2 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
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-public python-pafy
 | 
					(define-public python-pafy
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
| 
						 | 
					@ -1886,14 +1925,14 @@ standard library.")
 | 
				
			||||||
(define-public python-py
 | 
					(define-public python-py
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (name "python-py")
 | 
					    (name "python-py")
 | 
				
			||||||
    (version "1.4.32")
 | 
					    (version "1.4.34")
 | 
				
			||||||
    (source
 | 
					    (source
 | 
				
			||||||
     (origin
 | 
					     (origin
 | 
				
			||||||
       (method url-fetch)
 | 
					       (method url-fetch)
 | 
				
			||||||
       (uri (pypi-uri "py" version))
 | 
					       (uri (pypi-uri "py" version))
 | 
				
			||||||
       (sha256
 | 
					       (sha256
 | 
				
			||||||
        (base32
 | 
					        (base32
 | 
				
			||||||
         "19s1pql9pq85h1qzsdwgyb8a3k1qgkvh33b02m8kfqhizz8rzf64"))))
 | 
					         "1qyd5z0hv8ymxy84v5vig3vps2fvhcf4bdlksb3r03h549fmhb8g"))))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (build-system python-build-system)
 | 
				
			||||||
    (arguments
 | 
					    (arguments
 | 
				
			||||||
     ;; FIXME: "ImportError: 'test' module incorrectly imported from
 | 
					     ;; FIXME: "ImportError: 'test' module incorrectly imported from
 | 
				
			||||||
| 
						 | 
					@ -1914,30 +1953,39 @@ code introspection, and logging.")
 | 
				
			||||||
(define-public python-pytest
 | 
					(define-public python-pytest
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (name "python-pytest")
 | 
					    (name "python-pytest")
 | 
				
			||||||
    (version "2.7.3")
 | 
					    (version "3.2.3")
 | 
				
			||||||
    (source
 | 
					    (source
 | 
				
			||||||
     (origin
 | 
					     (origin
 | 
				
			||||||
       (method url-fetch)
 | 
					       (method url-fetch)
 | 
				
			||||||
       (uri (string-append
 | 
					       (uri (pypi-uri "pytest" version))
 | 
				
			||||||
             "https://pypi.python.org/packages/source/p/pytest/pytest-"
 | 
					 | 
				
			||||||
             version ".tar.gz"))
 | 
					 | 
				
			||||||
       (sha256
 | 
					       (sha256
 | 
				
			||||||
        (base32
 | 
					        (base32
 | 
				
			||||||
         "1z4yi986f9n0p8qmzmn21m21m8j1x78hk3505f89baqm6pdw7afm"))
 | 
					         "0g6w86ks73fnrnsyib9ii2rbyx830vn7aglsjqz9v1n2xwbndyi7"))))
 | 
				
			||||||
       (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):")))))
 | 
					 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (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
 | 
					    (propagated-inputs
 | 
				
			||||||
     `(("python-py" ,python-py)))
 | 
					     `(("python-py" ,python-py)))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(;; Tests need the "regular" bash since 'bash-final' lacks `compgen`.
 | 
					     `(;; Tests need the "regular" bash since 'bash-final' lacks `compgen`.
 | 
				
			||||||
       ("bash" ,bash)
 | 
					       ("bash" ,bash)
 | 
				
			||||||
 | 
					       ("python-hypothesis" ,python-hypothesis)
 | 
				
			||||||
       ("python-nose" ,python-nose)
 | 
					       ("python-nose" ,python-nose)
 | 
				
			||||||
       ("python-mock" ,python-mock)))
 | 
					       ("python-mock" ,python-mock)
 | 
				
			||||||
 | 
					       ("python-setuptools-scm" ,python-setuptools-scm)))
 | 
				
			||||||
    (home-page "http://pytest.org")
 | 
					    (home-page "http://pytest.org")
 | 
				
			||||||
    (synopsis "Python testing library")
 | 
					    (synopsis "Python testing library")
 | 
				
			||||||
    (description
 | 
					    (description
 | 
				
			||||||
| 
						 | 
					@ -1949,41 +1997,15 @@ and many external plugins.")
 | 
				
			||||||
(define-public python2-pytest
 | 
					(define-public python2-pytest
 | 
				
			||||||
  (package-with-python2 python-pytest))
 | 
					  (package-with-python2 python-pytest))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;; Some packages require a newer pytest.
 | 
					(define-public python-pytest-bootstrap
 | 
				
			||||||
(define-public python-pytest-3.0
 | 
					 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (inherit python-pytest)
 | 
					    (inherit python-pytest)
 | 
				
			||||||
    (name "python-pytest")
 | 
					    (name "python-pytest-bootstrap")
 | 
				
			||||||
    (version "3.0.7")
 | 
					    (native-inputs `(("python-setuptools-scm" ,python-setuptools-scm)))
 | 
				
			||||||
    (source (origin
 | 
					    (arguments `(#:tests? #f))))
 | 
				
			||||||
              (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))))))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-public python2-pytest-3.0
 | 
					(define-public python2-pytest-bootstrap
 | 
				
			||||||
  (let ((base (package-with-python2
 | 
					  (package-with-python2 python-pytest-bootstrap))
 | 
				
			||||||
                (strip-python2-variant python-pytest-3.0))))
 | 
					 | 
				
			||||||
    (package (inherit base)
 | 
					 | 
				
			||||||
      (native-inputs
 | 
					 | 
				
			||||||
        `(("python2-enum34" ,python2-enum34)
 | 
					 | 
				
			||||||
          ,@(package-native-inputs base))))))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-public python-pytest-cov
 | 
					(define-public python-pytest-cov
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
| 
						 | 
					@ -2045,7 +2067,7 @@ supports coverage of subprocesses.")
 | 
				
			||||||
               (string-append "version = \"" ,version "\"")))
 | 
					               (string-append "version = \"" ,version "\"")))
 | 
				
			||||||
            #t)))))
 | 
					            #t)))))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-pytest" ,python-pytest)
 | 
					     `(("python-pytest" ,python-pytest-bootstrap)
 | 
				
			||||||
       ("python-setuptools-scm" ,python-setuptools-scm)))
 | 
					       ("python-setuptools-scm" ,python-setuptools-scm)))
 | 
				
			||||||
    (home-page "https://github.com/pytest-dev/pytest-runner")
 | 
					    (home-page "https://github.com/pytest-dev/pytest-runner")
 | 
				
			||||||
    (synopsis "Invoke py.test as a distutils command")
 | 
					    (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
 | 
					(define-public python-coverage
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (name "python-coverage")
 | 
					    (name "python-coverage")
 | 
				
			||||||
    (version "4.1")
 | 
					    (version "4.4.1")
 | 
				
			||||||
    (source
 | 
					    (source
 | 
				
			||||||
     (origin
 | 
					     (origin
 | 
				
			||||||
       (method url-fetch)
 | 
					       (method url-fetch)
 | 
				
			||||||
       (uri (pypi-uri "coverage" version))
 | 
					       (uri (pypi-uri "coverage" version))
 | 
				
			||||||
       (sha256
 | 
					       (sha256
 | 
				
			||||||
        (base32
 | 
					        (base32
 | 
				
			||||||
         "01rbr4br4lsk0lwn8fb96zwd2xr4f0mg1w7iq3j11i8f5ig2nqs1"))))
 | 
					         "097l4s3ssxm1vncsn0nw3a1pbzah28773q36c1ab9wz01r04973s"))))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (build-system python-build-system)
 | 
				
			||||||
    (arguments
 | 
					    (arguments
 | 
				
			||||||
     ;; FIXME: 95 tests failed, 539 passed, 6 skipped, 2 errors.
 | 
					     ;; FIXME: 95 tests failed, 539 passed, 6 skipped, 2 errors.
 | 
				
			||||||
| 
						 | 
					@ -2882,7 +2904,7 @@ somewhat intelligible.")
 | 
				
			||||||
           #t))))
 | 
					           #t))))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (build-system python-build-system)
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-pytest" ,python-pytest-3.0)
 | 
					     `(("python-pytest" ,python-pytest)
 | 
				
			||||||
       ("python-pytest-cov" ,python-pytest-cov)
 | 
					       ("python-pytest-cov" ,python-pytest-cov)
 | 
				
			||||||
       ("python-pytest-runner" ,python-pytest-runner)))
 | 
					       ("python-pytest-runner" ,python-pytest-runner)))
 | 
				
			||||||
    (home-page "https://github.com/progrium/pyjwt")
 | 
					    (home-page "https://github.com/progrium/pyjwt")
 | 
				
			||||||
| 
						 | 
					@ -3076,18 +3098,6 @@ for Python.")
 | 
				
			||||||
        (base32
 | 
					        (base32
 | 
				
			||||||
         "1zzrkywhziqffrzks14kzixz7nd4yh2vc0fb04a68vfd2ai03anx"))))
 | 
					         "1zzrkywhziqffrzks14kzixz7nd4yh2vc0fb04a68vfd2ai03anx"))))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (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
 | 
					    (propagated-inputs
 | 
				
			||||||
     `(("python-markupsafe" ,python-markupsafe)))
 | 
					     `(("python-markupsafe" ,python-markupsafe)))
 | 
				
			||||||
    (home-page "http://jinja.pocoo.org/")
 | 
					    (home-page "http://jinja.pocoo.org/")
 | 
				
			||||||
| 
						 | 
					@ -3338,7 +3348,7 @@ sources.")
 | 
				
			||||||
     `(("python-sphinxcontrib-websupport" ,python-sphinxcontrib-websupport)
 | 
					     `(("python-sphinxcontrib-websupport" ,python-sphinxcontrib-websupport)
 | 
				
			||||||
       ,@(package-propagated-inputs python-sphinx)))
 | 
					       ,@(package-propagated-inputs python-sphinx)))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-pytest" ,python-pytest-3.0)
 | 
					     `(("python-pytest" ,python-pytest)
 | 
				
			||||||
       ("imagemagick" ,imagemagick) ; for "convert"
 | 
					       ("imagemagick" ,imagemagick) ; for "convert"
 | 
				
			||||||
       ,@(package-native-inputs python-sphinx)))
 | 
					       ,@(package-native-inputs python-sphinx)))
 | 
				
			||||||
    (properties '())))
 | 
					    (properties '())))
 | 
				
			||||||
| 
						 | 
					@ -3356,7 +3366,7 @@ sources.")
 | 
				
			||||||
        (base32
 | 
					        (base32
 | 
				
			||||||
         "0kw1axswbvaavr8ggyf4qr6hnisnrzlbkkcdada69vk1x9xjassg"))))
 | 
					         "0kw1axswbvaavr8ggyf4qr6hnisnrzlbkkcdada69vk1x9xjassg"))))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-pytest" ,python-pytest-3.0)
 | 
					     `(("python-pytest" ,python-pytest)
 | 
				
			||||||
       ,@(package-native-inputs python-sphinx)))))
 | 
					       ,@(package-native-inputs python-sphinx)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-public python2-sphinx
 | 
					(define-public python2-sphinx
 | 
				
			||||||
| 
						 | 
					@ -5307,7 +5317,7 @@ Python language binding specification.")
 | 
				
			||||||
    (arguments '(#:tests? #f)) ; Test file 'grako.ebnf' is missing from archive.
 | 
					    (arguments '(#:tests? #f)) ; Test file 'grako.ebnf' is missing from archive.
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("unzip" ,unzip)
 | 
					     `(("unzip" ,unzip)
 | 
				
			||||||
       ("python-pytest" ,python-pytest-3.0)
 | 
					       ("python-pytest" ,python-pytest)
 | 
				
			||||||
       ("python-pytest-runner" ,python-pytest-runner)))
 | 
					       ("python-pytest-runner" ,python-pytest-runner)))
 | 
				
			||||||
    (home-page "https://bitbucket.org/neogeny/grako")
 | 
					    (home-page "https://bitbucket.org/neogeny/grako")
 | 
				
			||||||
    (synopsis "EBNF parser generator")
 | 
					    (synopsis "EBNF parser generator")
 | 
				
			||||||
| 
						 | 
					@ -5365,7 +5375,7 @@ cluster without needing to write any wrapper code yourself.")
 | 
				
			||||||
        (base32 "0zizn61n5z5hq421hkypk9pw8s6fpxw30f4hsg7k4ivwzy3gjw9j"))))
 | 
					        (base32 "0zizn61n5z5hq421hkypk9pw8s6fpxw30f4hsg7k4ivwzy3gjw9j"))))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (build-system python-build-system)
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-pytest" ,python-pytest-3.0)
 | 
					     `(("python-pytest" ,python-pytest)
 | 
				
			||||||
       ("python-mock" ,python-mock)
 | 
					       ("python-mock" ,python-mock)
 | 
				
			||||||
       ("python-tox" ,python-tox)
 | 
					       ("python-tox" ,python-tox)
 | 
				
			||||||
       ("which" ,which))) ;for tests
 | 
					       ("which" ,which))) ;for tests
 | 
				
			||||||
| 
						 | 
					@ -5428,7 +5438,7 @@ displayed.")
 | 
				
			||||||
         (replace 'check (lambda _ (zero? (system* "nosetests" "-v")))))))
 | 
					         (replace 'check (lambda _ (zero? (system* "nosetests" "-v")))))))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-nose" ,python-nose)
 | 
					     `(("python-nose" ,python-nose)
 | 
				
			||||||
       ("python-pytest" ,python-pytest-3.0)
 | 
					       ("python-pytest" ,python-pytest)
 | 
				
			||||||
       ("man-db" ,man-db)
 | 
					       ("man-db" ,man-db)
 | 
				
			||||||
       ("which" ,which)
 | 
					       ("which" ,which)
 | 
				
			||||||
       ("bash-full" ,bash)))                 ;full Bash for 'test_replwrap.py'
 | 
					       ("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
 | 
					(define-public python-setuptools-scm
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (name "python-setuptools-scm")
 | 
					    (name "python-setuptools-scm")
 | 
				
			||||||
    (version "1.15.0")
 | 
					    (version "1.15.6")
 | 
				
			||||||
    (source (origin
 | 
					    (source (origin
 | 
				
			||||||
              (method url-fetch)
 | 
					              (method url-fetch)
 | 
				
			||||||
              (uri (pypi-uri "setuptools_scm" version))
 | 
					              (uri (pypi-uri "setuptools_scm" version))
 | 
				
			||||||
              (sha256
 | 
					              (sha256
 | 
				
			||||||
               (base32
 | 
					               (base32
 | 
				
			||||||
                "0bwyc5markib0i7i2qlyhdzxhiywzxbkfiapldma8m91m82jvwfs"))))
 | 
					                "0pzvfmx8s20yrgkgwfbxaspz2x1g38qv61jpm0ns91lrb22ldas9"))))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (build-system python-build-system)
 | 
				
			||||||
    (home-page "https://github.com/pypa/setuptools_scm/")
 | 
					    (home-page "https://github.com/pypa/setuptools_scm/")
 | 
				
			||||||
    (synopsis "Manage Python package versions in SCM metadata")
 | 
					    (synopsis "Manage Python package versions in SCM metadata")
 | 
				
			||||||
| 
						 | 
					@ -6990,14 +7000,14 @@ PEP 8.")
 | 
				
			||||||
(define-public python-pyflakes
 | 
					(define-public python-pyflakes
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (name "python-pyflakes")
 | 
					    (name "python-pyflakes")
 | 
				
			||||||
    (version "1.0.0")
 | 
					    (version "1.5.0")
 | 
				
			||||||
    (source
 | 
					    (source
 | 
				
			||||||
      (origin
 | 
					      (origin
 | 
				
			||||||
        (method url-fetch)
 | 
					        (method url-fetch)
 | 
				
			||||||
        (uri (pypi-uri "pyflakes" version))
 | 
					        (uri (pypi-uri "pyflakes" version))
 | 
				
			||||||
        (sha256
 | 
					        (sha256
 | 
				
			||||||
          (base32
 | 
					          (base32
 | 
				
			||||||
            "0qs2sgqszq7wcplis8509wk2ygqcrwzbs1ghfj3svvivq2j377pk"))))
 | 
					            "1x1pcca4a24k4pw8x1c77sgi58cg1wl2k38mp8a25k608pzls3da"))))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (build-system python-build-system)
 | 
				
			||||||
    (home-page
 | 
					    (home-page
 | 
				
			||||||
      "https://github.com/pyflakes/pyflakes")
 | 
					      "https://github.com/pyflakes/pyflakes")
 | 
				
			||||||
| 
						 | 
					@ -7012,17 +7022,17 @@ PEP 8.")
 | 
				
			||||||
(define-public python-mccabe
 | 
					(define-public python-mccabe
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (name "python-mccabe")
 | 
					    (name "python-mccabe")
 | 
				
			||||||
    (version "0.4.0")
 | 
					    (version "0.6.1")
 | 
				
			||||||
    (source
 | 
					    (source
 | 
				
			||||||
      (origin
 | 
					      (origin
 | 
				
			||||||
        (method url-fetch)
 | 
					        (method url-fetch)
 | 
				
			||||||
        (uri (pypi-uri "mccabe" version))
 | 
					        (uri (pypi-uri "mccabe" version))
 | 
				
			||||||
        (sha256
 | 
					        (sha256
 | 
				
			||||||
          (base32
 | 
					          (base32
 | 
				
			||||||
            "0yr08a36h8lqlif10l4xcikbbig7q8f41gqywir7rrvnv3mi4aws"))))
 | 
					            "07w3p1qm44hgxf3vvwz84kswpsx6s7kvaibzrsx5dzm0hli1i3fx"))))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (build-system python-build-system)
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
      `(("python-pytest" ,python-pytest)
 | 
					      `(("python-pytest" ,python-pytest-bootstrap)
 | 
				
			||||||
        ("python-pytest-runner" ,python-pytest-runner)))
 | 
					        ("python-pytest-runner" ,python-pytest-runner)))
 | 
				
			||||||
    (home-page "https://github.com/flintwork/mccabe")
 | 
					    (home-page "https://github.com/flintwork/mccabe")
 | 
				
			||||||
    (synopsis "McCabe checker, plugin for flake8")
 | 
					    (synopsis "McCabe checker, plugin for flake8")
 | 
				
			||||||
| 
						 | 
					@ -7095,39 +7105,48 @@ complexity of Python source code.")
 | 
				
			||||||
(define-public python-flake8
 | 
					(define-public python-flake8
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
    (name "python-flake8")
 | 
					    (name "python-flake8")
 | 
				
			||||||
    (version "2.5.4")
 | 
					    (version "3.4.1")
 | 
				
			||||||
    (source
 | 
					    (source
 | 
				
			||||||
      (origin
 | 
					      (origin
 | 
				
			||||||
        (method url-fetch)
 | 
					        (method url-fetch)
 | 
				
			||||||
        (uri (pypi-uri "flake8" version))
 | 
					        (uri (pypi-uri "flake8" version))
 | 
				
			||||||
        (sha256
 | 
					        (sha256
 | 
				
			||||||
          (base32
 | 
					          (base32
 | 
				
			||||||
            "0bs9cz4fr99r2rwig1b8jwaadl1nan7kgpdzqwj0bwbckwbmh7nc"))
 | 
					            "1n0i38592vy3q0x2a9bf8z6rhhn04i30wsn5i5zzcj7qkxvl8062"))))
 | 
				
			||||||
        (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))))
 | 
					 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (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
 | 
					    (propagated-inputs
 | 
				
			||||||
      `(("python-pep8" ,python-pep8)
 | 
					      `(("python-pycodestyle" ,python-pycodestyle)
 | 
				
			||||||
        ("python-pyflakes" ,python-pyflakes)
 | 
					        ("python-pyflakes" ,python-pyflakes)
 | 
				
			||||||
 | 
					        ;; flake8 depends on a newer setuptools than provided by python.
 | 
				
			||||||
 | 
					        ("python-setuptools" ,python-setuptools)
 | 
				
			||||||
        ("python-mccabe" ,python-mccabe)))
 | 
					        ("python-mccabe" ,python-mccabe)))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
      `(("python-mock" ,python-mock) ; TODO: only required for < 3.3
 | 
					      `(("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")
 | 
					    (home-page "https://gitlab.com/pycqa/flake8")
 | 
				
			||||||
    (synopsis
 | 
					    (synopsis
 | 
				
			||||||
      "The modular source code checker: pep8, pyflakes and co")
 | 
					      "The modular source code checker: pep8, pyflakes and co")
 | 
				
			||||||
    (description
 | 
					    (description
 | 
				
			||||||
      "Flake8 is a wrapper around PyFlakes, pep8 and python-mccabe.")
 | 
					      "Flake8 is a wrapper around PyFlakes, pep8 and python-mccabe.")
 | 
				
			||||||
 | 
					    (properties `((python2-variant . ,(delay python2-flake8))))
 | 
				
			||||||
    (license license:expat)))
 | 
					    (license license:expat)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-public python2-flake8
 | 
					(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
 | 
					(define-public python-flake8-polyfill
 | 
				
			||||||
  (package
 | 
					  (package
 | 
				
			||||||
| 
						 | 
					@ -8008,7 +8027,7 @@ responses, rather than doing any computation.")
 | 
				
			||||||
       ("python-hypothesis" ,python-hypothesis)
 | 
					       ("python-hypothesis" ,python-hypothesis)
 | 
				
			||||||
       ("python-pretend" ,python-pretend)
 | 
					       ("python-pretend" ,python-pretend)
 | 
				
			||||||
       ("python-pytz" ,python-pytz)
 | 
					       ("python-pytz" ,python-pytz)
 | 
				
			||||||
       ("python-pytest" ,python-pytest-3.0)))
 | 
					       ("python-pytest" ,python-pytest)))
 | 
				
			||||||
    (home-page "https://github.com/pyca/cryptography")
 | 
					    (home-page "https://github.com/pyca/cryptography")
 | 
				
			||||||
    (synopsis "Cryptographic recipes and primitives for Python")
 | 
					    (synopsis "Cryptographic recipes and primitives for Python")
 | 
				
			||||||
    (description
 | 
					    (description
 | 
				
			||||||
| 
						 | 
					@ -8068,7 +8087,7 @@ message digests and key derivation functions.")
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-flaky" ,python-flaky)
 | 
					     `(("python-flaky" ,python-flaky)
 | 
				
			||||||
       ("python-pretend" ,python-pretend)
 | 
					       ("python-pretend" ,python-pretend)
 | 
				
			||||||
       ("python-pytest" ,python-pytest-3.0)))
 | 
					       ("python-pytest" ,python-pytest)))
 | 
				
			||||||
    (home-page "https://github.com/pyca/pyopenssl")
 | 
					    (home-page "https://github.com/pyca/pyopenssl")
 | 
				
			||||||
    (synopsis "Python wrapper module around the OpenSSL library")
 | 
					    (synopsis "Python wrapper module around the OpenSSL library")
 | 
				
			||||||
    (description
 | 
					    (description
 | 
				
			||||||
| 
						 | 
					@ -10138,7 +10157,7 @@ Amazon Web Services (AWS) API.")
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (build-system python-build-system)
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-flake8" ,python-flake8)
 | 
					     `(("python-flake8" ,python-flake8)
 | 
				
			||||||
       ("python-pytest" ,python-pytest)))
 | 
					       ("python-pytest" ,python-pytest-bootstrap)))
 | 
				
			||||||
    (synopsis "Library for property based testing")
 | 
					    (synopsis "Library for property based testing")
 | 
				
			||||||
    (description "Hypothesis is a library for testing your Python code against a
 | 
					    (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
 | 
					much larger range of examples than you would ever want to write by hand.  It’s
 | 
				
			||||||
| 
						 | 
					@ -15035,7 +15054,7 @@ for Flask.")
 | 
				
			||||||
         "0gf2dpahpl5igb7jh1sr9acj3z3gp7zahqdqb69nk6wx01c8kc1g"))))
 | 
					         "0gf2dpahpl5igb7jh1sr9acj3z3gp7zahqdqb69nk6wx01c8kc1g"))))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (build-system python-build-system)
 | 
				
			||||||
    (propagated-inputs
 | 
					    (propagated-inputs
 | 
				
			||||||
     `(("pytest" ,python-pytest-3.0)))
 | 
					     `(("pytest" ,python-pytest)))
 | 
				
			||||||
    (home-page "https://github.com/fschulze/pytest-warnings")
 | 
					    (home-page "https://github.com/fschulze/pytest-warnings")
 | 
				
			||||||
    (synopsis "Pytest plugin to list Python warnings in pytest report")
 | 
					    (synopsis "Pytest plugin to list Python warnings in pytest report")
 | 
				
			||||||
    (description
 | 
					    (description
 | 
				
			||||||
| 
						 | 
					@ -15059,7 +15078,7 @@ pytest report.")
 | 
				
			||||||
         "038049nyjl7di59ycnxvc9nydivc5m8np3hqq84j2iirkccdbs5n"))))
 | 
					         "038049nyjl7di59ycnxvc9nydivc5m8np3hqq84j2iirkccdbs5n"))))
 | 
				
			||||||
    (build-system python-build-system)
 | 
					    (build-system python-build-system)
 | 
				
			||||||
    (propagated-inputs
 | 
					    (propagated-inputs
 | 
				
			||||||
     `(("pytest" ,python-pytest-3.0)))
 | 
					     `(("pytest" ,python-pytest)))
 | 
				
			||||||
    (home-page "http://bitbucket.org/memedough/pytest-capturelog/overview")
 | 
					    (home-page "http://bitbucket.org/memedough/pytest-capturelog/overview")
 | 
				
			||||||
    (synopsis "Pytest plugin to catch log messages")
 | 
					    (synopsis "Pytest plugin to catch log messages")
 | 
				
			||||||
    (description
 | 
					    (description
 | 
				
			||||||
| 
						 | 
					@ -15084,7 +15103,7 @@ pytest report.")
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("unzip" ,unzip)))
 | 
					     `(("unzip" ,unzip)))
 | 
				
			||||||
    (propagated-inputs
 | 
					    (propagated-inputs
 | 
				
			||||||
     `(("pytest" ,python-pytest-3.0)))
 | 
					     `(("pytest" ,python-pytest)))
 | 
				
			||||||
    (home-page "https://github.com/eisensheng/pytest-catchlog")
 | 
					    (home-page "https://github.com/eisensheng/pytest-catchlog")
 | 
				
			||||||
    (synopsis "Pytest plugin to catch log messages")
 | 
					    (synopsis "Pytest plugin to catch log messages")
 | 
				
			||||||
    (description
 | 
					    (description
 | 
				
			||||||
| 
						 | 
					@ -16075,7 +16094,7 @@ address is valid and really exists.")
 | 
				
			||||||
     `(("python-dateutil" ,python-dateutil)
 | 
					     `(("python-dateutil" ,python-dateutil)
 | 
				
			||||||
       ("python-simplejson" ,python-simplejson)))
 | 
					       ("python-simplejson" ,python-simplejson)))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-pytest-3.0" ,python-pytest-3.0)
 | 
					     `(("python-pytest" ,python-pytest)
 | 
				
			||||||
       ("python-pytz" ,python-pytz)))
 | 
					       ("python-pytz" ,python-pytz)))
 | 
				
			||||||
    (home-page "https://github.com/marshmallow-code/marshmallow")
 | 
					    (home-page "https://github.com/marshmallow-code/marshmallow")
 | 
				
			||||||
    (synopsis "Convert complex datatypes to and from native
 | 
					    (synopsis "Convert complex datatypes to and from native
 | 
				
			||||||
| 
						 | 
					@ -16122,7 +16141,7 @@ complex datatypes to and from native Python datatypes.")
 | 
				
			||||||
    (propagated-inputs
 | 
					    (propagated-inputs
 | 
				
			||||||
     `(("python-pyyaml" ,python-pyyaml)))
 | 
					     `(("python-pyyaml" ,python-pyyaml)))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-pytest-3.0" ,python-pytest-3.0)
 | 
					     `(("python-pytest" ,python-pytest)
 | 
				
			||||||
       ("python-flask" ,python-flask)
 | 
					       ("python-flask" ,python-flask)
 | 
				
			||||||
       ("python-marshmallow" ,python-marshmallow)
 | 
					       ("python-marshmallow" ,python-marshmallow)
 | 
				
			||||||
       ("python-tornado" ,python-tornado)
 | 
					       ("python-tornado" ,python-tornado)
 | 
				
			||||||
| 
						 | 
					@ -16175,7 +16194,7 @@ Swagger 2.0).")
 | 
				
			||||||
       ("python-flake8" ,python-flake8)
 | 
					       ("python-flake8" ,python-flake8)
 | 
				
			||||||
       ("python-flask-restful" ,python-flask-restful)
 | 
					       ("python-flask-restful" ,python-flask-restful)
 | 
				
			||||||
       ("python-flex" ,python-flex)
 | 
					       ("python-flex" ,python-flex)
 | 
				
			||||||
       ("python-pytest-3.0" ,python-pytest-3.0)
 | 
					       ("python-pytest" ,python-pytest)
 | 
				
			||||||
       ("python-pytest-cov" ,python-pytest-cov)
 | 
					       ("python-pytest-cov" ,python-pytest-cov)
 | 
				
			||||||
       ("python-marshmallow" ,python-marshmallow)
 | 
					       ("python-marshmallow" ,python-marshmallow)
 | 
				
			||||||
       ("python-apispec" ,python-apispec)))
 | 
					       ("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.
 | 
					     `(;; The tests depend on unittest2, and our version is a bit too old.
 | 
				
			||||||
       #:tests? #f))
 | 
					       #:tests? #f))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-pbr" ,python-pbr)))
 | 
					     `(("python-pbr" ,python-pbr-minimal)))
 | 
				
			||||||
    (home-page
 | 
					    (home-page
 | 
				
			||||||
      "https://github.com/testing-cabal/linecache2")
 | 
					      "https://github.com/testing-cabal/linecache2")
 | 
				
			||||||
    (synopsis "Backports of the linecache module")
 | 
					    (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.
 | 
					     `(;; python-traceback2 and python-unittest2 depend on one another.
 | 
				
			||||||
       #:tests? #f))
 | 
					       #:tests? #f))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-pbr" ,python-pbr)))
 | 
					     `(("python-pbr" ,python-pbr-minimal)))
 | 
				
			||||||
    (propagated-inputs
 | 
					    (propagated-inputs
 | 
				
			||||||
      `(("python-linecache2" ,python-linecache2)))
 | 
					      `(("python-linecache2" ,python-linecache2)))
 | 
				
			||||||
    (home-page
 | 
					    (home-page
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -515,7 +515,7 @@ netcat implementation that supports TLS.")
 | 
				
			||||||
               #t))))))
 | 
					               #t))))))
 | 
				
			||||||
    ;; TODO: Add optional inputs for testing.
 | 
					    ;; TODO: Add optional inputs for testing.
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-mock" ,python-mock-2)
 | 
					     `(("python-mock" ,python-mock)
 | 
				
			||||||
       ;; For documentation
 | 
					       ;; For documentation
 | 
				
			||||||
       ("python-sphinx" ,python-sphinx)
 | 
					       ("python-sphinx" ,python-sphinx)
 | 
				
			||||||
       ("python-sphinxcontrib-programoutput" ,python-sphinxcontrib-programoutput)
 | 
					       ("python-sphinxcontrib-programoutput" ,python-sphinxcontrib-programoutput)
 | 
				
			||||||
| 
						 | 
					@ -564,7 +564,7 @@ netcat implementation that supports TLS.")
 | 
				
			||||||
    ;; TODO: Add optional inputs for testing.
 | 
					    ;; TODO: Add optional inputs for testing.
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-nose" ,python-nose)
 | 
					     `(("python-nose" ,python-nose)
 | 
				
			||||||
       ("python-mock" ,python-mock-2)
 | 
					       ("python-mock" ,python-mock)
 | 
				
			||||||
       ;; For documentation
 | 
					       ;; For documentation
 | 
				
			||||||
       ("python-sphinx" ,python-sphinx)
 | 
					       ("python-sphinx" ,python-sphinx)
 | 
				
			||||||
       ("python-sphinx-rtd-theme" ,python-sphinx-rtd-theme)
 | 
					       ("python-sphinx-rtd-theme" ,python-sphinx-rtd-theme)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5154,7 +5154,7 @@ command-line arguments or read from stdin.")
 | 
				
			||||||
       ("python-schema" ,python-schema-0.5)
 | 
					       ("python-schema" ,python-schema-0.5)
 | 
				
			||||||
       ("python-backports-csv" ,python-backports-csv)))
 | 
					       ("python-backports-csv" ,python-backports-csv)))
 | 
				
			||||||
    (native-inputs
 | 
					    (native-inputs
 | 
				
			||||||
     `(("python-pytest-3.0" ,python-pytest-3.0)
 | 
					     `(("python-pytest" ,python-pytest)
 | 
				
			||||||
       ("python-pytest-capturelog" ,python-pytest-capturelog)
 | 
					       ("python-pytest-capturelog" ,python-pytest-capturelog)
 | 
				
			||||||
       ("python-responses" ,python-responses)))
 | 
					       ("python-responses" ,python-responses)))
 | 
				
			||||||
    (home-page "https://github.com/jjjake/internetarchive")
 | 
					    (home-page "https://github.com/jjjake/internetarchive")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Reference in a new issue