diff options
author | Victor Stinner <vstinner@redhat.com> | 2015-09-24 21:58:01 +0200 |
---|---|---|
committer | Victor Stinner <vstinner@redhat.com> | 2015-10-20 09:20:29 +0200 |
commit | bbf534d90c4f8590f30b0ae2b372f3bf7e02975d (patch) | |
tree | 43ece885696093d3b1fde27f877b836ebfdb1165 /python | |
parent | 22ef32a2cd0c32723030169470b84c71b598b2e6 (diff) | |
download | subunit-git-bbf534d90c4f8590f30b0ae2b372f3bf7e02975d.tar.gz |
Fix StreamResultToBytes._write_packet()
Call write() in a loop until all bytes are written. The write()
method doesn't ensure that all bytes are written.
This change should workaround the eventlet bug:
https://github.com/eventlet/eventlet/issues/248
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() |