Mini Shell
"""Internal module for Python 2 backwards compatibility."""
# flake8: noqa
import errno
import socket
import sys
def sendall(sock, *args, **kwargs):
return sock.sendall(*args, **kwargs)
def shutdown(sock, *args, **kwargs):
return sock.shutdown(*args, **kwargs)
def ssl_wrap_socket(context, sock, *args, **kwargs):
return context.wrap_socket(sock, *args, **kwargs)
# For Python older than 3.5, retry EINTR.
if sys.version_info[0] < 3 or (sys.version_info[0] == 3 and
sys.version_info[1] < 5):
# Adapted from https://bugs.python.org/review/23863/patch/14532/54418
import time
# Wrapper for handling interruptable system calls.
def _retryable_call(s, func, *args, **kwargs):
# Some modules (SSL) use the _fileobject wrapper directly and
# implement a smaller portion of the socket interface, thus we
# need to let them continue to do so.
timeout, deadline = None, 0.0
attempted = False
try:
timeout = s.gettimeout()
except AttributeError:
pass
if timeout:
deadline = time.time() + timeout
try:
while True:
if attempted and timeout:
now = time.time()
if now >= deadline:
raise socket.error(errno.EWOULDBLOCK, "timed out")
else:
# Overwrite the timeout on the socket object
# to take into account elapsed time.
s.settimeout(deadline - now)
try:
attempted = True
return func(*args, **kwargs)
except socket.error as e:
if e.args[0] == errno.EINTR:
continue
raise
finally:
# Set the existing timeout back for future
# calls.
if timeout:
s.settimeout(timeout)
def recv(sock, *args, **kwargs):
return _retryable_call(sock, sock.recv, *args, **kwargs)
def recv_into(sock, *args, **kwargs):
return _retryable_call(sock, sock.recv_into, *args, **kwargs)
else: # Python 3.5 and above automatically retry EINTR
def recv(sock, *args, **kwargs):
return sock.recv(*args, **kwargs)
def recv_into(sock, *args, **kwargs):
return sock.recv_into(*args, **kwargs)
if sys.version_info[0] < 3:
# In Python 3, the ssl module raises socket.timeout whereas it raises
# SSLError in Python 2. For compatibility between versions, ensure
# socket.timeout is raised for both.
import functools
try:
from ssl import SSLError as _SSLError
except ImportError:
class _SSLError(Exception):
"""A replacement in case ssl.SSLError is not available."""
pass
_EXPECTED_SSL_TIMEOUT_MESSAGES = (
"The handshake operation timed out",
"The read operation timed out",
"The write operation timed out",
)
def _handle_ssl_timeout(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except _SSLError as e:
message = len(e.args) == 1 and unicode(e.args[0]) or ''
if any(x in message for x in _EXPECTED_SSL_TIMEOUT_MESSAGES):
# Raise socket.timeout for compatibility with Python 3.
raise socket.timeout(*e.args)
raise
return wrapper
recv = _handle_ssl_timeout(recv)
recv_into = _handle_ssl_timeout(recv_into)
sendall = _handle_ssl_timeout(sendall)
shutdown = _handle_ssl_timeout(shutdown)
ssl_wrap_socket = _handle_ssl_timeout(ssl_wrap_socket)
if sys.version_info[0] < 3:
from urllib import unquote
from urlparse import parse_qs, urlparse
from itertools import imap, izip
from string import letters as ascii_letters
from Queue import Queue
# special unicode handling for python2 to avoid UnicodeDecodeError
def safe_unicode(obj, *args):
""" return the unicode representation of obj """
try:
return unicode(obj, *args)
except UnicodeDecodeError:
# obj is byte string
ascii_text = str(obj).encode('string_escape')
return unicode(ascii_text)
def iteritems(x):
return x.iteritems()
def iterkeys(x):
return x.iterkeys()
def itervalues(x):
return x.itervalues()
def nativestr(x):
return x if isinstance(x, str) else x.encode('utf-8', 'replace')
def next(x):
return x.next()
unichr = unichr
xrange = xrange
basestring = basestring
unicode = unicode
long = long
BlockingIOError = socket.error
else:
from urllib.parse import parse_qs, unquote, urlparse
from string import ascii_letters
from queue import Queue
def iteritems(x):
return iter(x.items())
def iterkeys(x):
return iter(x.keys())
def itervalues(x):
return iter(x.values())
def nativestr(x):
return x if isinstance(x, str) else x.decode('utf-8', 'replace')
def safe_unicode(value):
if isinstance(value, bytes):
value = value.decode('utf-8', 'replace')
return str(value)
next = next
unichr = chr
imap = map
izip = zip
xrange = range
basestring = str
unicode = str
long = int
BlockingIOError = BlockingIOError
try: # Python 3
from queue import LifoQueue, Empty, Full
except ImportError: # Python 2
from Queue import LifoQueue, Empty, Full
Zerion Mini Shell 1.0