aboutsummaryrefslogtreecommitdiffstats
path: root/python/gevent/_socket3.py
diff options
context:
space:
mode:
authorJames Taylor <user234683@users.noreply.github.com>2019-09-06 16:31:13 -0700
committerJames Taylor <user234683@users.noreply.github.com>2019-09-06 16:31:13 -0700
commit3d57e14df7ba5f14a634295caf3b2e60da50bfe2 (patch)
tree4903bcb79a49ad714a1a9129765b9545405c9978 /python/gevent/_socket3.py
parentac32b24b2a011292b704a3f27e8fd08a7ae9424b (diff)
downloadyt-local-3d57e14df7ba5f14a634295caf3b2e60da50bfe2.tar.lz
yt-local-3d57e14df7ba5f14a634295caf3b2e60da50bfe2.tar.xz
yt-local-3d57e14df7ba5f14a634295caf3b2e60da50bfe2.zip
Remove windows python distribution from repo and add requirements.txt
Diffstat (limited to 'python/gevent/_socket3.py')
-rw-r--r--python/gevent/_socket3.py756
1 files changed, 0 insertions, 756 deletions
diff --git a/python/gevent/_socket3.py b/python/gevent/_socket3.py
deleted file mode 100644
index 973b5a9..0000000
--- a/python/gevent/_socket3.py
+++ /dev/null
@@ -1,756 +0,0 @@
-# Port of Python 3.3's socket module to gevent
-"""
-Python 3 socket module.
-"""
-# Our import magic sadly makes this warning useless
-# pylint: disable=undefined-variable
-# pylint: disable=too-many-statements,too-many-branches
-# pylint: disable=too-many-public-methods,unused-argument
-from __future__ import absolute_import
-import io
-import os
-import sys
-
-from gevent import _socketcommon
-from gevent._util import copy_globals
-from gevent._compat import PYPY
-from gevent.timeout import Timeout
-import _socket
-from os import dup
-
-
-copy_globals(_socketcommon, globals(),
- names_to_ignore=_socketcommon.__extensions__,
- dunder_names_to_keep=())
-
-try:
- from errno import EHOSTUNREACH
- from errno import ECONNREFUSED
-except ImportError:
- EHOSTUNREACH = -1
- ECONNREFUSED = -1
-
-
-__socket__ = _socketcommon.__socket__
-__implements__ = _socketcommon._implements
-__extensions__ = _socketcommon.__extensions__
-__imports__ = _socketcommon.__imports__
-__dns__ = _socketcommon.__dns__
-
-
-SocketIO = __socket__.SocketIO # pylint:disable=no-member
-
-
-def _get_memory(data):
- mv = memoryview(data)
- if mv.shape:
- return mv
- # No shape, probably working with a ctypes object,
- # or something else exotic that supports the buffer interface
- return mv.tobytes()
-
-timeout_default = object()
-
-
-class _wrefsocket(_socket.socket):
- # Plain stdlib socket.socket objects subclass _socket.socket
- # and add weakref ability. The ssl module, for one, counts on this.
- # We don't create socket.socket objects (because they may have been
- # monkey patched to be the object from this module), but we still
- # need to make sure what we do create can be weakrefd.
-
- __slots__ = ("__weakref__", )
-
- if PYPY:
- # server.py unwraps the socket object to get the raw _sock;
- # it depends on having a timeout property alias, which PyPy does not
- # provide.
- timeout = property(lambda s: s.gettimeout(),
- lambda s, nv: s.settimeout(nv))
-
-from gevent._hub_primitives import wait_on_socket as _wait_on_socket
-
-class socket(object):
- """
- gevent `socket.socket <https://docs.python.org/3/library/socket.html#socket-objects>`_
- for Python 3.
-
- This object should have the same API as the standard library socket linked to above. Not all
- methods are specifically documented here; when they are they may point out a difference
- to be aware of or may document a method the standard library does not.
- """
-
- # Subclasses can set this to customize the type of the
- # native _socket.socket we create. It MUST be a subclass
- # of _wrefsocket. (gevent internal usage only)
- _gevent_sock_class = _wrefsocket
-
- _io_refs = 0
- _closed = False
- _read_event = None
- _write_event = None
-
-
- # Take the same approach as socket2: wrap a real socket object,
- # don't subclass it. This lets code that needs the raw _sock (not tied to the hub)
- # get it. This shows up in tests like test__example_udp_server.
-
- if sys.version_info[:2] < (3, 7):
- def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None):
- self._sock = self._gevent_sock_class(family, type, proto, fileno)
- self.timeout = None
- self.__init_common()
- else:
- # In 3.7, socket changed to auto-detecting family, type, and proto
- # when given a fileno.
- def __init__(self, family=-1, type=-1, proto=-1, fileno=None):
- if fileno is None:
- if family == -1:
- family = AF_INET
- if type == -1:
- type = SOCK_STREAM
- if proto == -1:
- proto = 0
- self._sock = self._gevent_sock_class(family, type, proto, fileno)
- self.timeout = None
- self.__init_common()
-
- def __init_common(self):
- _socket.socket.setblocking(self._sock, False)
- fileno = _socket.socket.fileno(self._sock)
- self.hub = get_hub()
- io_class = self.hub.loop.io
- self._read_event = io_class(fileno, 1)
- self._write_event = io_class(fileno, 2)
- self.timeout = _socket.getdefaulttimeout()
-
- def __getattr__(self, name):
- return getattr(self._sock, name)
-
- if hasattr(_socket, 'SOCK_NONBLOCK'):
- # Only defined under Linux
- @property
- def type(self):
- # See https://github.com/gevent/gevent/pull/399
- if self.timeout != 0.0:
- return self._sock.type & ~_socket.SOCK_NONBLOCK # pylint:disable=no-member
- return self._sock.type
-
- def getblocking(self):
- """
- Returns whether the socket will approximate blocking
- behaviour.
-
- .. versionadded:: 1.3a2
- Added in Python 3.7.
- """
- return self.timeout != 0.0
-
- def __enter__(self):
- return self
-
- def __exit__(self, *args):
- if not self._closed:
- self.close()
-
- def __repr__(self):
- """Wrap __repr__() to reveal the real class name."""
- try:
- s = _socket.socket.__repr__(self._sock)
- except Exception as ex: # pylint:disable=broad-except
- # Observed on Windows Py3.3, printing the repr of a socket
- # that just suffered a ConnectionResetError [WinError 10054]:
- # "OverflowError: no printf formatter to display the socket descriptor in decimal"
- # Not sure what the actual cause is or if there's a better way to handle this
- s = '<socket [%r]>' % ex
-
- if s.startswith("<socket object"):
- s = "<%s.%s%s%s" % (self.__class__.__module__,
- self.__class__.__name__,
- getattr(self, '_closed', False) and " [closed] " or "",
- s[7:])
- return s
-
- def __getstate__(self):
- raise TypeError("Cannot serialize socket object")
-
- def _get_ref(self):
- return self._read_event.ref or self._write_event.ref
-
- def _set_ref(self, value):
- self._read_event.ref = value
- self._write_event.ref = value
-
- ref = property(_get_ref, _set_ref)
-
- _wait = _wait_on_socket
-
- def dup(self):
- """dup() -> socket object
-
- Return a new socket object connected to the same system resource.
- """
- fd = dup(self.fileno())
- sock = self.__class__(self.family, self.type, self.proto, fileno=fd)
- sock.settimeout(self.gettimeout())
- return sock
-
- def accept(self):
- """accept() -> (socket object, address info)
-
- Wait for an incoming connection. Return a new socket
- representing the connection, and the address of the client.
- For IP sockets, the address info is a pair (hostaddr, port).
- """
- while True:
- try:
- fd, addr = self._accept()
- break
- except BlockingIOError:
- if self.timeout == 0.0:
- raise
- self._wait(self._read_event)
- sock = socket(self.family, self.type, self.proto, fileno=fd)
- # Python Issue #7995: if no default timeout is set and the listening
- # socket had a (non-zero) timeout, force the new socket in blocking
- # mode to override platform-specific socket flags inheritance.
- # XXX do we need to do this?
- if getdefaulttimeout() is None and self.gettimeout():
- sock.setblocking(True)
- return sock, addr
-
- def makefile(self, mode="r", buffering=None, *,
- encoding=None, errors=None, newline=None):
- """Return an I/O stream connected to the socket
-
- The arguments are as for io.open() after the filename,
- except the only mode characters supported are 'r', 'w' and 'b'.
- The semantics are similar too.
- """
- # (XXX refactor to share code?)
- for c in mode:
- if c not in {"r", "w", "b"}:
- raise ValueError("invalid mode %r (only r, w, b allowed)")
- writing = "w" in mode
- reading = "r" in mode or not writing
- assert reading or writing
- binary = "b" in mode
- rawmode = ""
- if reading:
- rawmode += "r"
- if writing:
- rawmode += "w"
- raw = SocketIO(self, rawmode)
- self._io_refs += 1
- if buffering is None:
- buffering = -1
- if buffering < 0:
- buffering = io.DEFAULT_BUFFER_SIZE
- if buffering == 0:
- if not binary:
- raise ValueError("unbuffered streams must be binary")
- return raw
- if reading and writing:
- buffer = io.BufferedRWPair(raw, raw, buffering)
- elif reading:
- buffer = io.BufferedReader(raw, buffering)
- else:
- assert writing
- buffer = io.BufferedWriter(raw, buffering)
- if binary:
- return buffer
- text = io.TextIOWrapper(buffer, encoding, errors, newline)
- text.mode = mode
- return text
-
- def _decref_socketios(self):
- # Called by SocketIO when it is closed.
- if self._io_refs > 0:
- self._io_refs -= 1
- if self._closed:
- self.close()
-
- def _drop_events(self):
- if self._read_event is not None:
- self.hub.cancel_wait(self._read_event, cancel_wait_ex, True)
- self._read_event = None
- if self._write_event is not None:
- self.hub.cancel_wait(self._write_event, cancel_wait_ex, True)
- self._write_event = None
-
- def _real_close(self, _ss=_socket.socket, cancel_wait_ex=cancel_wait_ex):
- # This function should not reference any globals. See Python issue #808164.
-
- # Break any reference to the loop.io objects. Our fileno,
- # which they were tied to, is now free to be reused, so these
- # objects are no longer functional.
- self._drop_events()
-
- _ss.close(self._sock)
-
- # Break any references to the underlying socket object. Tested
- # by test__refcount. (Why does this matter?). Be sure to
- # preserve our same family/type/proto if possible (if we
- # don't, we can get TypeError instead of OSError; see
- # test_socket.SendmsgUDP6Test.testSendmsgAfterClose)... but
- # this isn't always possible (see test_socket.test_unknown_socket_family_repr)
- # TODO: Can we use a simpler proxy, like _socket2 does?
- try:
- self._sock = self._gevent_sock_class(self.family, self.type, self.proto)
- except OSError:
- pass
- else:
- _ss.close(self._sock)
-
-
- def close(self):
- # This function should not reference any globals. See Python issue #808164.
- self._closed = True
- if self._io_refs <= 0:
- self._real_close()
-
- @property
- def closed(self):
- return self._closed
-
- def detach(self):
- """detach() -> file descriptor
-
- Close the socket object without closing the underlying file descriptor.
- The object cannot be used after this call, but the file descriptor
- can be reused for other purposes. The file descriptor is returned.
- """
- self._closed = True
- return self._sock.detach()
-
- def connect(self, address):
- if self.timeout == 0.0:
- return _socket.socket.connect(self._sock, address)
- address = _socketcommon._resolve_addr(self._sock, address)
-
- with Timeout._start_new_or_dummy(self.timeout, timeout("timed out")):
- while True:
- err = self.getsockopt(SOL_SOCKET, SO_ERROR)
- if err:
- raise error(err, strerror(err))
- result = _socket.socket.connect_ex(self._sock, address)
-
- if not result or result == EISCONN:
- break
- elif (result in (EWOULDBLOCK, EINPROGRESS, EALREADY)) or (result == EINVAL and is_windows):
- self._wait(self._write_event)
- else:
- if (isinstance(address, tuple)
- and address[0] == 'fe80::1'
- and result == EHOSTUNREACH):
- # On Python 3.7 on mac, we see EHOSTUNREACH
- # returned for this link-local address, but it really is
- # supposed to be ECONNREFUSED according to the standard library
- # tests (test_socket.NetworkConnectionNoServer.test_create_connection)
- # (On previous versions, that code passed the '127.0.0.1' IPv4 address, so
- # ipv6 link locals were never a factor; 3.7 passes 'localhost'.)
- # It is something of a mystery how the stdlib socket code doesn't
- # produce EHOSTUNREACH---I (JAM) can't see how socketmodule.c would avoid
- # that. The normal connect just calls connect_ex much like we do.
- result = ECONNREFUSED
- raise error(result, strerror(result))
-
- def connect_ex(self, address):
- try:
- return self.connect(address) or 0
- except timeout:
- return EAGAIN
- except gaierror: # pylint:disable=try-except-raise
- # gaierror/overflowerror/typerror is not silenced by connect_ex;
- # gaierror extends OSError (aka error) so catch it first
- raise
- except error as ex:
- # error is now OSError and it has various subclasses.
- # Only those that apply to actually connecting are silenced by
- # connect_ex.
- if ex.errno:
- return ex.errno
- raise # pragma: no cover
-
- def recv(self, *args):
- while True:
- try:
- return _socket.socket.recv(self._sock, *args)
- except error as ex:
- if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
- raise
- self._wait(self._read_event)
-
- if hasattr(_socket.socket, 'recvmsg'):
- # Only on Unix; PyPy 3.5 5.10.0 provides sendmsg and recvmsg, but not
- # recvmsg_into (at least on os x)
-
- def recvmsg(self, *args):
- while True:
- try:
- return _socket.socket.recvmsg(self._sock, *args)
- except error as ex:
- if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
- raise
- self._wait(self._read_event)
-
- if hasattr(_socket.socket, 'recvmsg_into'):
-
- def recvmsg_into(self, *args):
- while True:
- try:
- return _socket.socket.recvmsg_into(self._sock, *args)
- except error as ex:
- if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
- raise
- self._wait(self._read_event)
-
- def recvfrom(self, *args):
- while True:
- try:
- return _socket.socket.recvfrom(self._sock, *args)
- except error as ex:
- if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
- raise
- self._wait(self._read_event)
-
- def recvfrom_into(self, *args):
- while True:
- try:
- return _socket.socket.recvfrom_into(self._sock, *args)
- except error as ex:
- if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
- raise
- self._wait(self._read_event)
-
- def recv_into(self, *args):
- while True:
- try:
- return _socket.socket.recv_into(self._sock, *args)
- except error as ex:
- if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
- raise
- self._wait(self._read_event)
-
- def send(self, data, flags=0, timeout=timeout_default):
- if timeout is timeout_default:
- timeout = self.timeout
- try:
- return _socket.socket.send(self._sock, data, flags)
- except error as ex:
- if ex.args[0] not in _socketcommon.GSENDAGAIN or timeout == 0.0:
- raise
- self._wait(self._write_event)
- try:
- return _socket.socket.send(self._sock, data, flags)
- except error as ex2:
- if ex2.args[0] == EWOULDBLOCK:
- return 0
- raise
-
- def sendall(self, data, flags=0):
- # XXX Now that we run on PyPy3, see the notes in _socket2.py's sendall()
- # and implement that here if needed.
- # PyPy3 is not optimized for performance yet, and is known to be slower than
- # PyPy2, so it's possibly premature to do this. However, there is a 3.5 test case that
- # possibly exposes this in a severe way.
- data_memory = _get_memory(data)
- return _socketcommon._sendall(self, data_memory, flags)
-
- def sendto(self, *args):
- try:
- return _socket.socket.sendto(self._sock, *args)
- except error as ex:
- if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
- raise
- self._wait(self._write_event)
- try:
- return _socket.socket.sendto(self._sock, *args)
- except error as ex2:
- if ex2.args[0] == EWOULDBLOCK:
- return 0
- raise
-
- if hasattr(_socket.socket, 'sendmsg'):
- # Only on Unix
- def sendmsg(self, buffers, ancdata=(), flags=0, address=None):
- try:
- return _socket.socket.sendmsg(self._sock, buffers, ancdata, flags, address)
- except error as ex:
- if flags & getattr(_socket, 'MSG_DONTWAIT', 0):
- # Enable non-blocking behaviour
- # XXX: Do all platforms that have sendmsg have MSG_DONTWAIT?
- raise
-
- if ex.args[0] != EWOULDBLOCK or self.timeout == 0.0:
- raise
- self._wait(self._write_event)
- try:
- return _socket.socket.sendmsg(self._sock, buffers, ancdata, flags, address)
- except error as ex2:
- if ex2.args[0] == EWOULDBLOCK:
- return 0
- raise
-
- def setblocking(self, flag):
- # Beginning in 3.6.0b3 this is supposed to raise
- # if the file descriptor is closed, but the test for it
- # involves closing the fileno directly. Since we
- # don't touch the fileno here, it doesn't make sense for
- # us.
- if flag:
- self.timeout = None
- else:
- self.timeout = 0.0
-
- def settimeout(self, howlong):
- if howlong is not None:
- try:
- f = howlong.__float__
- except AttributeError:
- raise TypeError('a float is required')
- howlong = f()
- if howlong < 0.0:
- raise ValueError('Timeout value out of range')
- self.__dict__['timeout'] = howlong
-
- def gettimeout(self):
- return self.__dict__['timeout']
-
- def shutdown(self, how):
- if how == 0: # SHUT_RD
- self.hub.cancel_wait(self._read_event, cancel_wait_ex)
- elif how == 1: # SHUT_WR
- self.hub.cancel_wait(self._write_event, cancel_wait_ex)
- else:
- self.hub.cancel_wait(self._read_event, cancel_wait_ex)
- self.hub.cancel_wait(self._write_event, cancel_wait_ex)
- self._sock.shutdown(how)
-
- # sendfile: new in 3.5. But there's no real reason to not
- # support it everywhere. Note that we can't use os.sendfile()
- # because it's not cooperative.
- def _sendfile_use_sendfile(self, file, offset=0, count=None):
- # This is called directly by tests
- raise __socket__._GiveupOnSendfile() # pylint:disable=no-member
-
- def _sendfile_use_send(self, file, offset=0, count=None):
- self._check_sendfile_params(file, offset, count)
- if self.gettimeout() == 0:
- raise ValueError("non-blocking sockets are not supported")
- if offset:
- file.seek(offset)
- blocksize = min(count, 8192) if count else 8192
- total_sent = 0
- # localize variable access to minimize overhead
- file_read = file.read
- sock_send = self.send
- try:
- while True:
- if count:
- blocksize = min(count - total_sent, blocksize)
- if blocksize <= 0:
- break
- data = memoryview(file_read(blocksize))
- if not data:
- break # EOF
- while True:
- try:
- sent = sock_send(data)
- except BlockingIOError:
- continue
- else:
- total_sent += sent
- if sent < len(data):
- data = data[sent:]
- else:
- break
- return total_sent
- finally:
- if total_sent > 0 and hasattr(file, 'seek'):
- file.seek(offset + total_sent)
-
- def _check_sendfile_params(self, file, offset, count):
- if 'b' not in getattr(file, 'mode', 'b'):
- raise ValueError("file should be opened in binary mode")
- if not self.type & SOCK_STREAM:
- raise ValueError("only SOCK_STREAM type sockets are supported")
- if count is not None:
- if not isinstance(count, int):
- raise TypeError(
- "count must be a positive integer (got {!r})".format(count))
- if count <= 0:
- raise ValueError(
- "count must be a positive integer (got {!r})".format(count))
-
- def sendfile(self, file, offset=0, count=None):
- """sendfile(file[, offset[, count]]) -> sent
-
- Send a file until EOF is reached by using high-performance
- os.sendfile() and return the total number of bytes which
- were sent.
- *file* must be a regular file object opened in binary mode.
- If os.sendfile() is not available (e.g. Windows) or file is
- not a regular file socket.send() will be used instead.
- *offset* tells from where to start reading the file.
- If specified, *count* is the total number of bytes to transmit
- as opposed to sending the file until EOF is reached.
- File position is updated on return or also in case of error in
- which case file.tell() can be used to figure out the number of
- bytes which were sent.
- The socket must be of SOCK_STREAM type.
- Non-blocking sockets are not supported.
-
- .. versionadded:: 1.1rc4
- Added in Python 3.5, but available under all Python 3 versions in
- gevent.
- """
- return self._sendfile_use_send(file, offset, count)
-
- # get/set_inheritable new in 3.4
- if hasattr(os, 'get_inheritable') or hasattr(os, 'get_handle_inheritable'):
- # pylint:disable=no-member
- if os.name == 'nt':
- def get_inheritable(self):
- return os.get_handle_inheritable(self.fileno())
-
- def set_inheritable(self, inheritable):
- os.set_handle_inheritable(self.fileno(), inheritable)
- else:
- def get_inheritable(self):
- return os.get_inheritable(self.fileno())
-
- def set_inheritable(self, inheritable):
- os.set_inheritable(self.fileno(), inheritable)
- _added = "\n\n.. versionadded:: 1.1rc4 Added in Python 3.4"
- get_inheritable.__doc__ = "Get the inheritable flag of the socket" + _added
- set_inheritable.__doc__ = "Set the inheritable flag of the socket" + _added
- del _added
-
-
-if sys.version_info[:2] == (3, 4) and sys.version_info[:3] <= (3, 4, 2):
- # Python 3.4, up to and including 3.4.2, had a bug where the
- # SocketType enumeration overwrote the SocketType class imported
- # from _socket. This was fixed in 3.4.3 (http://bugs.python.org/issue20386
- # and https://github.com/python/cpython/commit/0d2f85f38a9691efdfd1e7285c4262cab7f17db7).
- # Prior to that, if we replace SocketType with our own class, the implementation
- # of socket.type breaks with "OSError: [Errno 97] Address family not supported by protocol".
- # Therefore, on these old versions, we must preserve it as an enum; while this
- # seems like it could lead to non-green behaviour, code on those versions
- # cannot possibly be using SocketType as a class anyway.
- SocketType = __socket__.SocketType # pylint:disable=no-member
- # Fixup __all__; note that we get exec'd multiple times during unit tests
- if 'SocketType' in __implements__:
- __implements__.remove('SocketType')
- if 'SocketType' not in __imports__:
- __imports__.append('SocketType')
-else:
- SocketType = socket
-
-
-def fromfd(fd, family, type, proto=0):
- """ fromfd(fd, family, type[, proto]) -> socket object
-
- Create a socket object from a duplicate of the given file
- descriptor. The remaining arguments are the same as for socket().
- """
- nfd = dup(fd)
- return socket(family, type, proto, nfd)
-
-
-if hasattr(_socket.socket, "share"):
- def fromshare(info):
- """ fromshare(info) -> socket object
-
- Create a socket object from a the bytes object returned by
- socket.share(pid).
- """
- return socket(0, 0, 0, info)
-
- __implements__.append('fromshare')
-
-if hasattr(_socket, "socketpair"):
-
- def socketpair(family=None, type=SOCK_STREAM, proto=0):
- """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
-
- Create a pair of socket objects from the sockets returned by the platform
- socketpair() function.
- The arguments are the same as for socket() except the default family is
- AF_UNIX if defined on the platform; otherwise, the default is AF_INET.
-
- .. versionchanged:: 1.2
- All Python 3 versions on Windows supply this function (natively
- supplied by Python 3.5 and above).
- """
- if family is None:
- try:
- family = AF_UNIX
- except NameError:
- family = AF_INET
- a, b = _socket.socketpair(family, type, proto)
- a = socket(family, type, proto, a.detach())
- b = socket(family, type, proto, b.detach())
- return a, b
-
-else: # pragma: no cover
- # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain.
-
- # gevent: taken from 3.6 release. Expected to be used only on Win. Added to Win/3.5
- # gevent: for < 3.5, pass the default value of 128 to lsock.listen()
- # (3.5+ uses this as a default and the original code passed no value)
-
- _LOCALHOST = '127.0.0.1'
- _LOCALHOST_V6 = '::1'
-
- def socketpair(family=AF_INET, type=SOCK_STREAM, proto=0):
- if family == AF_INET:
- host = _LOCALHOST
- elif family == AF_INET6:
- host = _LOCALHOST_V6
- else:
- raise ValueError("Only AF_INET and AF_INET6 socket address families "
- "are supported")
- if type != SOCK_STREAM:
- raise ValueError("Only SOCK_STREAM socket type is supported")
- if proto != 0:
- raise ValueError("Only protocol zero is supported")
-
- # We create a connected TCP socket. Note the trick with
- # setblocking(False) that prevents us from having to create a thread.
- lsock = socket(family, type, proto)
- try:
- lsock.bind((host, 0))
- lsock.listen(128)
- # On IPv6, ignore flow_info and scope_id
- addr, port = lsock.getsockname()[:2]
- csock = socket(family, type, proto)
- try:
- csock.setblocking(False)
- try:
- csock.connect((addr, port))
- except (BlockingIOError, InterruptedError):
- pass
- csock.setblocking(True)
- ssock, _ = lsock.accept()
- except:
- csock.close()
- raise
- finally:
- lsock.close()
- return (ssock, csock)
-
- if sys.version_info[:2] < (3, 5):
- # Not provided natively
- if 'socketpair' in __implements__:
- # Multiple imports can cause this to be missing if _socketcommon
- # was successfully imported, leading to subsequent imports to cause
- # ValueError
- __implements__.remove('socketpair')
-
-
-if hasattr(__socket__, 'close'): # Python 3.7b1+
- close = __socket__.close # pylint:disable=no-member
- __imports__ += ['close']
-
-__all__ = __implements__ + __extensions__ + __imports__