2016-07-29 15:31 GMT+02:00 Barry Warsaw <barry@python.org>:
I agree that os.getrandom() should be added on platforms that support it regardless of the outcome of the various PEPs, and that it should be a thin layer above the C function.
Yes, in my PEP 524, os.getrandom() is a thin wrapper to getrandom(). Well, "thin" wrapper... An interesting question is if the function should be implemented using a loop or only do exactly one call to getrandom()? Examples: - getrandom() is limited to 1024 bytes on Solaris - getrandom() can return less bytes than requested on Linux if the call is interrupted by a signal. If os.getrandom() only do a single call, the function must be called in a loop at the Python level: result = bytearray() while size: data = os.getrandom(size) result += data size -= len(data) return bytes(result) Currently, _PyOS_URandom() implements the loop at the C level. The implementation of os.getrandom() must respect the PEP 475 (retry syscall on EINTR), so maybe we should implement the loop at the C level. Ok, but imagine that you use the "expensive" GRNG_RANDOM (/dev/random rather than /dev/urandom). A first call returns 4000 bytes of "high quality" random bytes, but user requested 4096 bytes and the second call fails. Is it ok to "drop" the 4000 collected bytes? Entropy is a limited resource... The strict minimum is to implement os.getrandom() with a single call, *but* retry the getrandom() call if it fails with EINTR and the Python signal handler doesn't raise any exception. With this design, we don't drop any collected byte. But os.getrandom() should be used with a loop at the Python level. Victor