Skip to content

hashlib.file_digest() can't handle non-blocking I/O #122179

Closed
@srittau

Description

@srittau

Bug report

Bug description:

This came up in python/typeshed#12414.

The current implementation of file_digest() does not check the return value of fileobj.readinto() for None:

cpython/Lib/hashlib.py

Lines 232 to 236 in 2a5d1eb

while True:
size = fileobj.readinto(buf)
if size == 0:
break # EOF
digestobj.update(view[:size])

While buffered file objects can't return None, unbuffered ones can when they are doing non-blocking I/O. Specifically, file_digest() is documented to take SocketIO objects, which can very much return None:

cpython/Lib/socket.py

Lines 694 to 714 in 2a5d1eb

def readinto(self, b):
"""Read up to len(b) bytes into the writable buffer *b* and return
the number of bytes read. If the socket is non-blocking and no bytes
are available, None is returned.
If *b* is non-empty, a 0 return value indicates that the connection
was shutdown at the other end.
"""
self._checkClosed()
self._checkReadable()
if self._timeout_occurred:
raise OSError("cannot read from timed out object")
try:
return self._sock.recv_into(b)
except timeout:
self._timeout_occurred = True
raise
except error as e:
if e.errno in _blocking_errnos:
return None
raise

CPython versions tested on:

CPython main branch

Operating systems tested on:

Other

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions