mirror of https://github.com/python/cpython.git
bpo-32154: Remove asyncio.windows_utils.socketpair (#4609)
This commit is contained in:
parent
4d193bcc25
commit
ac577d7d0b
|
@ -967,10 +967,7 @@ Wait until a file descriptor received some data using the
|
||||||
:meth:`AbstractEventLoop.add_reader` method and then close the event loop::
|
:meth:`AbstractEventLoop.add_reader` method and then close the event loop::
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
try:
|
from socket import socketpair
|
||||||
from socket import socketpair
|
|
||||||
except ImportError:
|
|
||||||
from asyncio.windows_utils import socketpair
|
|
||||||
|
|
||||||
# Create a pair of connected file descriptors
|
# Create a pair of connected file descriptors
|
||||||
rsock, wsock = socketpair()
|
rsock, wsock = socketpair()
|
||||||
|
|
|
@ -690,10 +690,7 @@ Wait until a socket receives data using the
|
||||||
the event loop ::
|
the event loop ::
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
try:
|
from socket import socketpair
|
||||||
from socket import socketpair
|
|
||||||
except ImportError:
|
|
||||||
from asyncio.windows_utils import socketpair
|
|
||||||
|
|
||||||
# Create a pair of connected sockets
|
# Create a pair of connected sockets
|
||||||
rsock, wsock = socketpair()
|
rsock, wsock = socketpair()
|
||||||
|
|
|
@ -426,10 +426,7 @@ Coroutine waiting until a socket receives data using the
|
||||||
:func:`open_connection` function::
|
:func:`open_connection` function::
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
try:
|
from socket import socketpair
|
||||||
from socket import socketpair
|
|
||||||
except ImportError:
|
|
||||||
from asyncio.windows_utils import socketpair
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def wait_for_data(loop):
|
def wait_for_data(loop):
|
||||||
|
|
|
@ -686,6 +686,12 @@ Changes in Python behavior
|
||||||
Changes in the Python API
|
Changes in the Python API
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
* The ``asyncio.windows_utils.socketpair()`` function has been
|
||||||
|
removed: use directly :func:`socket.socketpair` which is available on all
|
||||||
|
platforms since Python 3.5 (before, it wasn't available on Windows).
|
||||||
|
``asyncio.windows_utils.socketpair()`` was just an alias to
|
||||||
|
``socket.socketpair`` on Python 3.5 and newer.
|
||||||
|
|
||||||
* :mod:`asyncio`: The module doesn't export :mod:`selectors` and
|
* :mod:`asyncio`: The module doesn't export :mod:`selectors` and
|
||||||
:mod:`_overlapped` modules as ``asyncio.selectors`` and
|
:mod:`_overlapped` modules as ``asyncio.selectors`` and
|
||||||
``asyncio._overlapped``. Replace ``from asyncio import selectors`` with
|
``asyncio._overlapped``. Replace ``from asyncio import selectors`` with
|
||||||
|
|
|
@ -35,12 +35,6 @@
|
||||||
from test import support
|
from test import support
|
||||||
|
|
||||||
|
|
||||||
if sys.platform == 'win32': # pragma: no cover
|
|
||||||
from .windows_utils import socketpair
|
|
||||||
else:
|
|
||||||
from socket import socketpair # pragma: no cover
|
|
||||||
|
|
||||||
|
|
||||||
def dummy_ssl_context():
|
def dummy_ssl_context():
|
||||||
if ssl is None:
|
if ssl is None:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['socketpair', 'pipe', 'Popen', 'PIPE', 'PipeHandle']
|
__all__ = ['pipe', 'Popen', 'PIPE', 'PipeHandle']
|
||||||
|
|
||||||
|
|
||||||
# Constants/globals
|
# Constants/globals
|
||||||
|
@ -29,54 +29,6 @@
|
||||||
_mmap_counter = itertools.count()
|
_mmap_counter = itertools.count()
|
||||||
|
|
||||||
|
|
||||||
if hasattr(socket, 'socketpair'):
|
|
||||||
# Since Python 3.5, socket.socketpair() is now also available on Windows
|
|
||||||
socketpair = socket.socketpair
|
|
||||||
else:
|
|
||||||
# Replacement for socket.socketpair()
|
|
||||||
def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
|
|
||||||
"""A socket pair usable as a self-pipe, for Windows.
|
|
||||||
|
|
||||||
Origin: https://gist.github.com/4325783, by Geert Jansen.
|
|
||||||
Public domain.
|
|
||||||
"""
|
|
||||||
if family == socket.AF_INET:
|
|
||||||
host = '127.0.0.1'
|
|
||||||
elif family == socket.AF_INET6:
|
|
||||||
host = '::1'
|
|
||||||
else:
|
|
||||||
raise ValueError("Only AF_INET and AF_INET6 socket address "
|
|
||||||
"families are supported")
|
|
||||||
if type != socket.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(0)
|
|
||||||
# that prevents us from having to create a thread.
|
|
||||||
lsock = socket.socket(family, type, proto)
|
|
||||||
try:
|
|
||||||
lsock.bind((host, 0))
|
|
||||||
lsock.listen(1)
|
|
||||||
# On IPv6, ignore flow_info and scope_id
|
|
||||||
addr, port = lsock.getsockname()[:2]
|
|
||||||
csock = socket.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)
|
|
||||||
|
|
||||||
|
|
||||||
# Replacement for os.pipe() using handles instead of fds
|
# Replacement for os.pipe() using handles instead of fds
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -363,7 +363,7 @@ def run(arg):
|
||||||
self.assertNotEqual(thread_id, threading.get_ident())
|
self.assertNotEqual(thread_id, threading.get_ident())
|
||||||
|
|
||||||
def test_reader_callback(self):
|
def test_reader_callback(self):
|
||||||
r, w = test_utils.socketpair()
|
r, w = socket.socketpair()
|
||||||
r.setblocking(False)
|
r.setblocking(False)
|
||||||
bytes_read = bytearray()
|
bytes_read = bytearray()
|
||||||
|
|
||||||
|
@ -391,7 +391,7 @@ def reader():
|
||||||
self.assertEqual(bytes_read, b'abcdef')
|
self.assertEqual(bytes_read, b'abcdef')
|
||||||
|
|
||||||
def test_writer_callback(self):
|
def test_writer_callback(self):
|
||||||
r, w = test_utils.socketpair()
|
r, w = socket.socketpair()
|
||||||
w.setblocking(False)
|
w.setblocking(False)
|
||||||
|
|
||||||
def writer(data):
|
def writer(data):
|
||||||
|
@ -1568,7 +1568,7 @@ def reader(data):
|
||||||
@unittest.skipUnless(sys.platform != 'win32',
|
@unittest.skipUnless(sys.platform != 'win32',
|
||||||
"Don't support pipes for Windows")
|
"Don't support pipes for Windows")
|
||||||
def test_write_pipe_disconnect_on_close(self):
|
def test_write_pipe_disconnect_on_close(self):
|
||||||
rsock, wsock = test_utils.socketpair()
|
rsock, wsock = socket.socketpair()
|
||||||
rsock.setblocking(False)
|
rsock.setblocking(False)
|
||||||
pipeobj = io.open(wsock.detach(), 'wb', 1024)
|
pipeobj = io.open(wsock.detach(), 'wb', 1024)
|
||||||
|
|
||||||
|
@ -1706,7 +1706,7 @@ def reader(data):
|
||||||
self.assertEqual('CLOSED', write_proto.state)
|
self.assertEqual('CLOSED', write_proto.state)
|
||||||
|
|
||||||
def test_prompt_cancellation(self):
|
def test_prompt_cancellation(self):
|
||||||
r, w = test_utils.socketpair()
|
r, w = socket.socketpair()
|
||||||
r.setblocking(False)
|
r.setblocking(False)
|
||||||
f = self.loop.sock_recv(r, 1)
|
f = self.loop.sock_recv(r, 1)
|
||||||
ov = getattr(f, 'ov', None)
|
ov = getattr(f, 'ov', None)
|
||||||
|
@ -1771,7 +1771,7 @@ def wait():
|
||||||
def test_remove_fds_after_closing(self):
|
def test_remove_fds_after_closing(self):
|
||||||
loop = self.create_event_loop()
|
loop = self.create_event_loop()
|
||||||
callback = lambda: None
|
callback = lambda: None
|
||||||
r, w = test_utils.socketpair()
|
r, w = socket.socketpair()
|
||||||
self.addCleanup(r.close)
|
self.addCleanup(r.close)
|
||||||
self.addCleanup(w.close)
|
self.addCleanup(w.close)
|
||||||
loop.add_reader(r, callback)
|
loop.add_reader(r, callback)
|
||||||
|
@ -1783,7 +1783,7 @@ def test_remove_fds_after_closing(self):
|
||||||
def test_add_fds_after_closing(self):
|
def test_add_fds_after_closing(self):
|
||||||
loop = self.create_event_loop()
|
loop = self.create_event_loop()
|
||||||
callback = lambda: None
|
callback = lambda: None
|
||||||
r, w = test_utils.socketpair()
|
r, w = socket.socketpair()
|
||||||
self.addCleanup(r.close)
|
self.addCleanup(r.close)
|
||||||
self.addCleanup(w.close)
|
self.addCleanup(w.close)
|
||||||
loop.close()
|
loop.close()
|
||||||
|
|
|
@ -19,56 +19,6 @@
|
||||||
from asyncio import test_support as support
|
from asyncio import test_support as support
|
||||||
|
|
||||||
|
|
||||||
class WinsocketpairTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def check_winsocketpair(self, ssock, csock):
|
|
||||||
csock.send(b'xxx')
|
|
||||||
self.assertEqual(b'xxx', ssock.recv(1024))
|
|
||||||
csock.close()
|
|
||||||
ssock.close()
|
|
||||||
|
|
||||||
def test_winsocketpair(self):
|
|
||||||
ssock, csock = windows_utils.socketpair()
|
|
||||||
self.check_winsocketpair(ssock, csock)
|
|
||||||
|
|
||||||
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 not supported or enabled')
|
|
||||||
def test_winsocketpair_ipv6(self):
|
|
||||||
ssock, csock = windows_utils.socketpair(family=socket.AF_INET6)
|
|
||||||
self.check_winsocketpair(ssock, csock)
|
|
||||||
|
|
||||||
@unittest.skipIf(hasattr(socket, 'socketpair'),
|
|
||||||
'socket.socketpair is available')
|
|
||||||
@mock.patch('asyncio.windows_utils.socket')
|
|
||||||
def test_winsocketpair_exc(self, m_socket):
|
|
||||||
m_socket.AF_INET = socket.AF_INET
|
|
||||||
m_socket.SOCK_STREAM = socket.SOCK_STREAM
|
|
||||||
m_socket.socket.return_value.getsockname.return_value = ('', 12345)
|
|
||||||
m_socket.socket.return_value.accept.return_value = object(), object()
|
|
||||||
m_socket.socket.return_value.connect.side_effect = OSError()
|
|
||||||
|
|
||||||
self.assertRaises(OSError, windows_utils.socketpair)
|
|
||||||
|
|
||||||
def test_winsocketpair_invalid_args(self):
|
|
||||||
self.assertRaises(ValueError,
|
|
||||||
windows_utils.socketpair, family=socket.AF_UNSPEC)
|
|
||||||
self.assertRaises(ValueError,
|
|
||||||
windows_utils.socketpair, type=socket.SOCK_DGRAM)
|
|
||||||
self.assertRaises(ValueError,
|
|
||||||
windows_utils.socketpair, proto=1)
|
|
||||||
|
|
||||||
@unittest.skipIf(hasattr(socket, 'socketpair'),
|
|
||||||
'socket.socketpair is available')
|
|
||||||
@mock.patch('asyncio.windows_utils.socket')
|
|
||||||
def test_winsocketpair_close(self, m_socket):
|
|
||||||
m_socket.AF_INET = socket.AF_INET
|
|
||||||
m_socket.SOCK_STREAM = socket.SOCK_STREAM
|
|
||||||
sock = mock.Mock()
|
|
||||||
m_socket.socket.return_value = sock
|
|
||||||
sock.bind.side_effect = OSError
|
|
||||||
self.assertRaises(OSError, windows_utils.socketpair)
|
|
||||||
self.assertTrue(sock.close.called)
|
|
||||||
|
|
||||||
|
|
||||||
class PipeTests(unittest.TestCase):
|
class PipeTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_pipe_overlapped(self):
|
def test_pipe_overlapped(self):
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
The ``asyncio.windows_utils.socketpair()`` function has been removed: use
|
||||||
|
directly :func:`socket.socketpair` which is available on all platforms since
|
||||||
|
Python 3.5 (before, it wasn't available on Windows).
|
||||||
|
``asyncio.windows_utils.socketpair()`` was just an alias to
|
||||||
|
``socket.socketpair`` on Python 3.5 and newer.
|
Loading…
Reference in New Issue