Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cdabbc1

Browse filesBrowse files
gpsheadsrittau
andauthored
[3.13] gh-122179: Fix hashlib.file_digest and non-blocking I/O (GH-132787)
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 (cherry picked from commit 2b47f46) Co-authored-by: Sebastian Rittau <srittau@rittau.biz>
1 parent bb59fde commit cdabbc1
Copy full SHA for cdabbc1

File tree

Expand file treeCollapse file tree

4 files changed

+22
-1
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+22
-1
lines changed

‎Doc/library/hashlib.rst

Copy file name to clipboardExpand all lines: Doc/library/hashlib.rst
+8-1Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,10 @@ a file or file-like object.
270270
*fileobj* must be a file-like object opened for reading in binary mode.
271271
It accepts file objects from builtin :func:`open`, :class:`~io.BytesIO`
272272
instances, SocketIO objects from :meth:`socket.socket.makefile`, and
273-
similar. The function may bypass Python's I/O and use the file descriptor
273+
similar. *fileobj* must be opened in blocking mode, otherwise a
274+
:exc:`BlockingIOError` may be raised.
275+
276+
The function may bypass Python's I/O and use the file descriptor
274277
from :meth:`~io.IOBase.fileno` directly. *fileobj* must be assumed to be
275278
in an unknown state after this function returns or raises. It is up to
276279
the caller to close *fileobj*.
@@ -299,6 +302,10 @@ a file or file-like object.
299302

300303
.. versionadded:: 3.11
301304

305+
.. versionchanged:: next
306+
Now raises a :exc:`BlockingIOError` if the file is opened in blocking
307+
mode. Previously, spurious null bytes were added to the digest.
308+
302309

303310
Key derivation
304311
--------------

‎Lib/hashlib.py

Copy file name to clipboardExpand all lines: Lib/hashlib.py
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ def file_digest(fileobj, digest, /, *, _bufsize=2**18):
231231
view = memoryview(buf)
232232
while True:
233233
size = fileobj.readinto(buf)
234+
if size is None:
235+
raise BlockingIOError("I/O operation would block.")
234236
if size == 0:
235237
break # EOF
236238
digestobj.update(view[:size])

‎Lib/test/test_hashlib.py

Copy file name to clipboardExpand all lines: Lib/test/test_hashlib.py
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,15 @@ def test_file_digest(self):
11901190
with open(os_helper.TESTFN, "wb") as f:
11911191
hashlib.file_digest(f, "sha256")
11921192

1193+
class NonBlocking:
1194+
def readinto(self, buf):
1195+
return None
1196+
def readable(self):
1197+
return True
1198+
1199+
with self.assertRaises(BlockingIOError):
1200+
hashlib.file_digest(NonBlocking(), hashlib.sha256)
1201+
11931202

11941203
if __name__ == "__main__":
11951204
unittest.main()
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:func:`hashlib.file_digest` now raises :exc:`BlockingIOError` when no data
2+
is available during non-blocking I/O. Before, it added spurious null bytes
3+
to the digest.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.