changeset 96:59253a1e6ef2

Employ .readinto() on Python 3
author Franz Glasner <f.glasner@feldmann-mg.com>
date Thu, 21 Apr 2022 18:53:38 +0200
parents fc2dd6afd594
children 10785998be38
files cutils/shasum.py
diffstat 1 files changed, 33 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/cutils/shasum.py	Thu Apr 21 18:52:53 2022 +0200
+++ b/cutils/shasum.py	Thu Apr 21 18:53:38 2022 +0200
@@ -600,17 +600,39 @@
             fadvise = getattr(os, "posix_fadvise", None)
             if fadvise:
                 fadvise(fd, 0, 0, os.POSIX_FADV_SEQUENTIAL)
-            while True:
-                try:
-                    buf = os.read(fd, READ_CHUNK_SIZE)
-                except OSError as e:
-                    if e.errno not in (errno.EAGAIN, errno.EWOULDBLOCK,
-                                       errno.EINTR):
-                        raise
-                else:
-                    if len(buf) == 0:
-                        break
-                    h.update(buf)
+            if not PY2:
+                fileobj = io.FileIO(fd, mode="r", closefd=False)
+                buf = bytearray(READ_CHUNK_SIZE)
+                with memoryview(buf) as full_view:
+                    while True:
+                        try:
+                            n = fileobj.readinto(buf)
+                        except OSError as e:
+                            if e.errno not in (errno.EAGAIN,
+                                               errno.EWOULDBLOCK,
+                                               errno.EINTR):
+                                raise
+                        else:
+                            if n == 0:
+                                break
+                            if n == READ_CHUNK_SIZE:
+                                h.update(buf)
+                            else:
+                                with full_view[:n] as partial_view:
+                                    h.update(partial_view)
+            else:
+                while True:
+                    try:
+                        buf = os.read(fd, READ_CHUNK_SIZE)
+                    except OSError as e:
+                        if e.errno not in (errno.EAGAIN,
+                                           errno.EWOULDBLOCK,
+                                           errno.EINTR):
+                            raise
+                    else:
+                        if len(buf) == 0:
+                            break
+                        h.update(buf)
         else:
             #
             # Use mmap