Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 95b2146

Browse files
committed
Issue #18756: Improve error reporting in os.urandom() when the failure is due to something else than /dev/urandom not existing.
2 parents 00731e2 + ec34ab5 commit 95b2146

3 files changed

Lines changed: 30 additions & 2 deletions

File tree

Lib/test/test_os.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
import threading
3131
except ImportError:
3232
threading = None
33+
try:
34+
import resource
35+
except ImportError:
36+
resource = None
37+
3338
from test.script_helper import assert_python_ok
3439

3540
with warnings.catch_warnings():
@@ -1010,6 +1015,21 @@ def test_urandom_subprocess(self):
10101015
data2 = self.get_urandom_subprocess(16)
10111016
self.assertNotEqual(data1, data2)
10121017

1018+
@unittest.skipUnless(resource, "test requires the resource module")
1019+
def test_urandom_failure(self):
1020+
soft_limit, hard_limit = resource.getrlimit(resource.RLIMIT_NOFILE)
1021+
resource.setrlimit(resource.RLIMIT_NOFILE, (1, hard_limit))
1022+
try:
1023+
with self.assertRaises(OSError) as cm:
1024+
os.urandom(16)
1025+
self.assertEqual(cm.exception.errno, errno.EMFILE)
1026+
finally:
1027+
# We restore the old limit as soon as possible. If doing it
1028+
# using addCleanup(), code running in between would fail
1029+
# creating any file descriptor.
1030+
resource.setrlimit(resource.RLIMIT_NOFILE, (soft_limit, hard_limit))
1031+
1032+
10131033
@contextlib.contextmanager
10141034
def _execvpe_mockup(defpath=None):
10151035
"""

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ Core and Builtins
2828
Library
2929
-------
3030

31+
- Issue #18756: Improve error reporting in os.urandom() when the failure
32+
is due to something else than /dev/urandom not existing (for example,
33+
exhausting the file descriptor limit).
34+
3135
- Issue #18673: Add O_TMPFILE to os module. O_TMPFILE requires Linux kernel
3236
3.11 or newer. It's only defined on system with 3.11 uapi headers, too.
3337

Python/random.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,12 @@ dev_urandom_python(char *buffer, Py_ssize_t size)
138138
Py_END_ALLOW_THREADS
139139
if (fd < 0)
140140
{
141-
PyErr_SetString(PyExc_NotImplementedError,
142-
"/dev/urandom (or equivalent) not found");
141+
if (errno == ENOENT || errno == ENXIO ||
142+
errno == ENODEV || errno == EACCES)
143+
PyErr_SetString(PyExc_NotImplementedError,
144+
"/dev/urandom (or equivalent) not found");
145+
else
146+
PyErr_SetFromErrno(PyExc_OSError);
143147
return -1;
144148
}
145149

0 commit comments

Comments
 (0)