Set stdout and stdin to binary mode on Python 2 and Windows

This commit is contained in:
micbou
2018-06-19 23:49:39 +02:00
committed by Dave Halter
parent f9e90e863b
commit 106b11f1af
2 changed files with 23 additions and 37 deletions
+17 -37
View File
@@ -2,7 +2,6 @@
To ensure compatibility from Python ``2.7`` - ``3.x``, a module has been To ensure compatibility from Python ``2.7`` - ``3.x``, a module has been
created. Clearly there is huge need to use conforming syntax. created. Clearly there is huge need to use conforming syntax.
""" """
import binascii
import errno import errno
import sys import sys
import os import os
@@ -448,52 +447,33 @@ if sys.version_info[:2] == (3, 3):
_PICKLE_PROTOCOL = 2 _PICKLE_PROTOCOL = 2
is_windows = sys.platform == 'win32'
# The Windows shell on Python 2 consumes all control characters (below 32) and expand on
# all Python versions \n to \r\n.
# pickle starting from protocol version 1 uses binary data, which could not be escaped by
# any normal unicode encoder. Therefore, the only bytes encoder which doesn't produce
# control characters is binascii.hexlify.
def pickle_load(file): def pickle_load(file):
if is_windows: try:
try:
data = file.readline()
data = binascii.unhexlify(data.strip())
if is_py3:
return pickle.loads(data, encoding='bytes')
else:
return pickle.loads(data)
# Python on Windows don't throw EOF errors for pipes. So reraise them with
# the correct type, which is cought upwards.
except OSError:
raise EOFError()
else:
if is_py3: if is_py3:
return pickle.load(file, encoding='bytes') return pickle.load(file, encoding='bytes')
else: return pickle.load(file)
return pickle.load(file) # Python on Windows don't throw EOF errors for pipes. So reraise them with
# the correct type, which is caught upwards.
except OSError:
if sys.platform == 'win32':
raise EOFError()
raise
def pickle_dump(data, file): def pickle_dump(data, file):
if is_windows: try:
try:
data = pickle.dumps(data, protocol=_PICKLE_PROTOCOL)
data = binascii.hexlify(data)
file.write(data)
file.write(b'\n')
# On Python 3.3 flush throws sometimes an error even if the two file writes
# should done it already before. This could be also computer / speed depending.
file.flush()
# Python on Windows don't throw EPIPE errors for pipes. So reraise them with
# the correct type and error number.
except OSError:
raise IOError(errno.EPIPE, "Broken pipe")
else:
pickle.dump(data, file, protocol=_PICKLE_PROTOCOL) pickle.dump(data, file, protocol=_PICKLE_PROTOCOL)
# On Python 3.3 flush throws sometimes an error even though the writing
# operation should be completed.
file.flush() file.flush()
# Python on Windows don't throw EPIPE errors for pipes. So reraise them with
# the correct type and error number.
except OSError:
if sys.platform == 'win32':
raise IOError(errno.EPIPE, "Broken pipe")
raise
try: try:
@@ -278,6 +278,12 @@ class Listener(object):
if sys.version_info[0] > 2: if sys.version_info[0] > 2:
stdout = stdout.buffer stdout = stdout.buffer
stdin = stdin.buffer stdin = stdin.buffer
# Python 2 opens streams in text mode on Windows. Set stdout and stdin
# to binary mode.
elif sys.platform == 'win32':
import msvcrt
msvcrt.setmode(stdout.fileno(), os.O_BINARY)
msvcrt.setmode(stdin.fileno(), os.O_BINARY)
while True: while True:
try: try: