summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/subunit/v2.py20
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()