
Closes https://github.com/eventlet/eventlet/issues/295 (in the wsgi module we use a custom writelines implementation now). Those write() calls might write only part of the data (and even if they don't - it's more readable to make sure all data is written explicitly). I changed the test code so that the write() implementation returns the number of characters logged and it cooperates nicely with writeall() now.
73 lines
1.8 KiB
Python
73 lines
1.8 KiB
Python
import sys
|
|
from contextlib import contextmanager
|
|
|
|
from eventlet.support import greenlets, six
|
|
|
|
|
|
def get_errno(exc):
|
|
""" Get the error code out of socket.error objects.
|
|
socket.error in <2.5 does not have errno attribute
|
|
socket.error in 3.x does not allow indexing access
|
|
e.args[0] works for all.
|
|
There are cases when args[0] is not errno.
|
|
i.e. http://bugs.python.org/issue6471
|
|
Maybe there are cases when errno is set, but it is not the first argument?
|
|
"""
|
|
|
|
try:
|
|
if exc.errno is not None:
|
|
return exc.errno
|
|
except AttributeError:
|
|
pass
|
|
try:
|
|
return exc.args[0]
|
|
except IndexError:
|
|
return None
|
|
|
|
|
|
if sys.version_info[0] < 3 and not greenlets.preserves_excinfo:
|
|
from sys import exc_clear as clear_sys_exc_info
|
|
else:
|
|
def clear_sys_exc_info():
|
|
"""No-op In py3k.
|
|
Exception information is not visible outside of except statements.
|
|
sys.exc_clear became obsolete and removed."""
|
|
pass
|
|
|
|
if sys.version_info[0] < 3:
|
|
def bytes_to_str(b, encoding='ascii'):
|
|
return b
|
|
else:
|
|
def bytes_to_str(b, encoding='ascii'):
|
|
return b.decode(encoding)
|
|
|
|
PY33 = sys.version_info[:2] == (3, 3)
|
|
|
|
@contextmanager
|
|
def capture_stderr():
|
|
stream = six.StringIO()
|
|
original = sys.stderr
|
|
try:
|
|
sys.stderr = stream
|
|
yield stream
|
|
finally:
|
|
sys.stderr = original
|
|
stream.seek(0)
|
|
|
|
|
|
def safe_writelines(fd, to_write):
|
|
# Standard Python 3 writelines() is not reliable because it doesn't care if it
|
|
# loses data. See CPython bug report: http://bugs.python.org/issue26292
|
|
for item in to_write:
|
|
writeall(fd, item)
|
|
|
|
|
|
if six.PY2:
|
|
def writeall(fd, buf):
|
|
fd.write(buf)
|
|
else:
|
|
def writeall(fd, buf):
|
|
written = 0
|
|
while written < len(buf):
|
|
written += fd.write(buf[written:])
|