Merge remote-tracking branch 'origin/python-updates' into core-updates
This commit is contained in:
commit
eda8a841ac
|
@ -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)
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in New Issue