mirror of
https://github.com/python/cpython.git
synced 2026-01-06 15:32:22 +00:00
gh-122179: Fix hashlib.file_digest and non-blocking I/O (GH-122183)
* Fix hashlib.file_digest and non-blocking I/O * Add documentation around this behavior * Add versionchanged
This commit is contained in:
parent
fa70bf8593
commit
2b47f46d7d
4 changed files with 22 additions and 1 deletions
|
|
@ -270,7 +270,10 @@ a file or file-like object.
|
|||
*fileobj* must be a file-like object opened for reading in binary mode.
|
||||
It accepts file objects from builtin :func:`open`, :class:`~io.BytesIO`
|
||||
instances, SocketIO objects from :meth:`socket.socket.makefile`, and
|
||||
similar. The function may bypass Python's I/O and use the file descriptor
|
||||
similar. *fileobj* must be opened in blocking mode, otherwise a
|
||||
:exc:`BlockingIOError` may be raised.
|
||||
|
||||
The function may bypass Python's I/O and use the file descriptor
|
||||
from :meth:`~io.IOBase.fileno` directly. *fileobj* must be assumed to be
|
||||
in an unknown state after this function returns or raises. It is up to
|
||||
the caller to close *fileobj*.
|
||||
|
|
@ -299,6 +302,10 @@ a file or file-like object.
|
|||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
.. versionchanged:: next
|
||||
Now raises a :exc:`BlockingIOError` if the file is opened in blocking
|
||||
mode. Previously, spurious null bytes were added to the digest.
|
||||
|
||||
|
||||
Key derivation
|
||||
--------------
|
||||
|
|
|
|||
|
|
@ -231,6 +231,8 @@ def file_digest(fileobj, digest, /, *, _bufsize=2**18):
|
|||
view = memoryview(buf)
|
||||
while True:
|
||||
size = fileobj.readinto(buf)
|
||||
if size is None:
|
||||
raise BlockingIOError("I/O operation would block.")
|
||||
if size == 0:
|
||||
break # EOF
|
||||
digestobj.update(view[:size])
|
||||
|
|
|
|||
|
|
@ -1199,6 +1199,15 @@ def test_file_digest(self):
|
|||
with self.assertRaises(ValueError):
|
||||
hashlib.file_digest(None, "sha256")
|
||||
|
||||
class NonBlocking:
|
||||
def readinto(self, buf):
|
||||
return None
|
||||
def readable(self):
|
||||
return True
|
||||
|
||||
with self.assertRaises(BlockingIOError):
|
||||
hashlib.file_digest(NonBlocking(), hashlib.sha256)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
:func:`hashlib.file_digest` now raises :exc:`BlockingIOError` when no data
|
||||
is available during non-blocking I/O. Before, it added spurious null bytes
|
||||
to the digest.
|
||||
Loading…
Add table
Add a link
Reference in a new issue