diff options
Diffstat (limited to 'python')
-rw-r--r-- | python/subunit/v2.py | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/python/subunit/v2.py b/python/subunit/v2.py index f649895..9ff139c 100644 --- a/python/subunit/v2.py +++ b/python/subunit/v2.py @@ -21,6 +21,7 @@ from io import UnsupportedOperation import os import select import struct +import sys import zlib from extras import safe_hasattr, try_imports @@ -52,6 +53,7 @@ EPOCH = datetime.datetime.utcfromtimestamp(0).replace(tzinfo=iso8601.Utc()) NUL_ELEMENT = b'\0'[0] # Contains True for types for which 'nul in thing' falsely returns false. _nul_test_broken = {} +_PY3 = (sys.version_info >= (3,)) def has_nul(buffer_or_bytes): @@ -206,12 +208,24 @@ class StreamResultToBytes(object): raise ValueError("Length too long: %r" % base_length) packet[2:3] = self._encode_number(base_length + length_length) # We could either do a partial application of crc32 over each chunk - # or a single join to a temp variable then a final join + # or a single join to a temp variable then a final join # or two writes (that python might then split). # For now, simplest code: join, crc32, join, output content = b''.join(packet) - self.output_stream.write(content + struct.pack( - FMT_32, zlib.crc32(content) & 0xffffffff)) + data = content + struct.pack(FMT_32, zlib.crc32(content) & 0xffffffff) + if _PY3: + # On eventlet 0.17.3, GreenIO.write() can make partial write. + # Use a loop to ensure that all bytes are written. + # See also the eventlet issue: + # https://github.com/eventlet/eventlet/issues/248 + view = memoryview(data) + datalen = len(data) + offset = 0 + while offset < datalen: + written = self.output_stream.write(view[offset:]) + offset += written + else: + self.output_stream.write(data) self.output_stream.flush() |