mercurial/worker.py
changeset 49238 13dfad0f9f7a
parent 49037 642e31cb55f0
parent 48870 2fe4efaa59af
child 49245 cdb85d0512b8
--- a/mercurial/worker.py	Tue May 24 19:09:24 2022 +0400
+++ b/mercurial/worker.py	Wed May 25 13:28:24 2022 +0200
@@ -68,6 +68,52 @@
     return threading.current_thread() == threading.main_thread()
 
 
+class _blockingreader(object):
+    def __init__(self, wrapped):
+        self._wrapped = wrapped
+
+    # Do NOT implement readinto() by making it delegate to
+    # _wrapped.readinto(), since that is unbuffered. The unpickler is fine
+    # with just read() and readline(), so we don't need to implement it.
+
+    if (3, 8, 0) <= sys.version_info[:3] < (3, 8, 2):
+
+        # This is required for python 3.8, prior to 3.8.2.  See issue6444.
+        def readinto(self, b):
+            pos = 0
+            size = len(b)
+
+            while pos < size:
+                ret = self._wrapped.readinto(b[pos:])
+                if not ret:
+                    break
+                pos += ret
+
+            return pos
+
+    def readline(self):
+        return self._wrapped.readline()
+
+    # issue multiple reads until size is fulfilled
+    def read(self, size=-1):
+        if size < 0:
+            return self._wrapped.readall()
+
+        buf = bytearray(size)
+        view = memoryview(buf)
+        pos = 0
+
+        while pos < size:
+            ret = self._wrapped.readinto(view[pos:])
+            if not ret:
+                break
+            pos += ret
+
+        del view
+        del buf[pos:]
+        return bytes(buf)
+
+
 class _blockingreader:
     def __init__(self, wrapped):
         self._wrapped = wrapped