From ddb786742626cfb6741eb17bb81498f777ce286b Mon Sep 17 00:00:00 2001 From: Erwan Le Pape Date: Fri, 21 Dec 2018 00:16:17 +0100 Subject: [PATCH 1/2] Proposal for BPO-35545 --- Lib/asyncio/base_events.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 60a189bdfb7ec9..973e49da803502 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -99,7 +99,7 @@ def _set_reuseport(sock): 'SO_REUSEPORT defined but not implemented.') -def _ipaddr_info(host, port, family, type, proto): +def _ipaddr_info(host, port, family, type, proto, flowinfo=0, scopeid=0): # Try to skip getaddrinfo if "host" is already an IP. Users might have # handled name resolution in their own code and pass in resolved IPs. if not hasattr(socket, 'inet_pton'): @@ -148,7 +148,7 @@ def _ipaddr_info(host, port, family, type, proto): socket.inet_pton(af, host) # The host has already been resolved. if _HAS_IPv6 and af == socket.AF_INET6: - return af, type, proto, '', (host, port, 0, 0) + return af, type, proto, '', (host, port, flowinfo, scopeid) else: return af, type, proto, '', (host, port) except OSError: @@ -1281,7 +1281,7 @@ async def _ensure_resolved(self, address, *, family=0, type=socket.SOCK_STREAM, proto=0, flags=0, loop): host, port = address[:2] - info = _ipaddr_info(host, port, family, type, proto) + info = _ipaddr_info(host, port, family, type, proto, *address[2:]) if info is not None: # "host" is already a resolved IP. return [info] From 9cc13fa40f3e37d0742c592b062fb3cf1b2ad7c4 Mon Sep 17 00:00:00 2001 From: Erwan Le Pape Date: Mon, 13 May 2019 22:28:48 +0200 Subject: [PATCH 2/2] Fix tests to use a numeric scope ID so tests may work on MS --- Lib/test/test_asyncio/test_base_events.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 29f8c079236bd1..8b46ce7e220c63 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -1315,25 +1315,15 @@ def test_create_connection_ipv6_scope(self, m_socket): sock = m_socket.socket.return_value sock.family = socket.AF_INET6 - # I'm not certain the loopback interface is always scope ID 1 so I'm - # relying on the socket module to provide it. If anyone knows - # otherwise, feel free to remove this. - for _, sock_kind, _, _, sock_addr in socket.getaddrinfo("fe80::1%lo", 80): - if sock_kind == socket.SOCK_STREAM: - scope_id = sock_addr[3] - break - else: - self.fail("couldn't find lo's scope id") - self.loop._add_reader = mock.Mock() self.loop._add_reader._is_coroutine = False self.loop._add_writer = mock.Mock() self.loop._add_writer._is_coroutine = False - coro = self.loop.create_connection(asyncio.Protocol, 'fe80::1%lo', 80) + coro = self.loop.create_connection(asyncio.Protocol, 'fe80::1%1', 80) t, p = self.loop.run_until_complete(coro) try: - sock.connect.assert_called_with(('fe80::1', 80, 0, scope_id)) + sock.connect.assert_called_with(('fe80::1', 80, 0, 1)) _, kwargs = m_socket.socket.call_args self.assertEqual(kwargs['family'], m_socket.AF_INET6) self.assertEqual(kwargs['type'], m_socket.SOCK_STREAM)