Merge the windows fixes

This commit is contained in:
Dave Halter
2018-03-23 00:55:23 +01:00
3 changed files with 43 additions and 7 deletions

View File

@@ -1,4 +1,4 @@
Main Authors Main Authors
============ ============
David Halter (@davidhalter) <davidhalter88@gmail.com> David Halter (@davidhalter) <davidhalter88@gmail.com>
@@ -48,5 +48,6 @@ Robin Roth (@robinro)
Malte Plath (@langsamer) Malte Plath (@langsamer)
Anton Zub (@zabulazza) Anton Zub (@zabulazza)
Maksim Novikov (@m-novikov) <mnovikov.work@gmail.com> Maksim Novikov (@m-novikov) <mnovikov.work@gmail.com>
Tobias Rzepka (@TobiasRzepka)
Note: (@user) means a github user name. Note: (@user) means a github user name.

View File

@@ -2,6 +2,8 @@
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 sys import sys
import os import os
import re import re
@@ -446,17 +448,52 @@ 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_py3: if is_windows:
return pickle.load(file, encoding='bytes') 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: else:
return pickle.load(file) if is_py3:
return pickle.load(file, encoding='bytes')
else:
return pickle.load(file)
def pickle_dump(data, file): def pickle_dump(data, file):
pickle.dump(data, file, protocol=_PICKLE_PROTOCOL) if is_windows:
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)
else:
pickle.dump(data, file, protocol=_PICKLE_PROTOCOL)
file.flush()
try: try:

View File

@@ -187,7 +187,6 @@ class _CompiledSubprocess(object):
data = evaluator_id, function, args, kwargs data = evaluator_id, function, args, kwargs
try: try:
pickle_dump(data, self._process.stdin) pickle_dump(data, self._process.stdin)
self._process.stdin.flush()
except (socket.error, IOError) as e: except (socket.error, IOError) as e:
# Once Python2 will be removed we can just use `BrokenPipeError`. # Once Python2 will be removed we can just use `BrokenPipeError`.
if e.errno != errno.EPIPE: if e.errno != errno.EPIPE:
@@ -288,7 +287,6 @@ class Listener(object):
result = True, traceback.format_exc(), e result = True, traceback.format_exc(), e
pickle_dump(result, file=stdout) pickle_dump(result, file=stdout)
stdout.flush()
class AccessHandle(object): class AccessHandle(object):