diff --git a/CHANGES/6195.bugfix b/CHANGES/6195.bugfix new file mode 100644 index 0000000000..dec44169e2 --- /dev/null +++ b/CHANGES/6195.bugfix @@ -0,0 +1 @@ +Restored ability to connect IPv6-only host. diff --git a/aiohttp/resolver.py b/aiohttp/resolver.py index 66a49731fe..d20c9194da 100644 --- a/aiohttp/resolver.py +++ b/aiohttp/resolver.py @@ -40,17 +40,23 @@ async def resolve( hosts = [] for family, _, proto, _, address in infos: if family == socket.AF_INET6: - if not (socket.has_ipv6 and address[3]): # type: ignore[misc] + if len(address) < 3: + # IPv6 is not supported by Python build, + # or IPv6 is not enabled in the host continue - # This is essential for link-local IPv6 addresses. - # LL IPv6 is a VERY rare case. Strictly speaking, we should use - # getnameinfo() unconditionally, but performance makes sense. - host, _port = socket.getnameinfo( - address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV - ) - port = int(_port) - else: - host, port = address[:2] + if address[3]: # type: ignore[misc] + # This is essential for link-local IPv6 addresses. + # LL IPv6 is a VERY rare case. Strictly speaking, we should use + # getnameinfo() unconditionally, but performance makes sense. + host, _port = socket.getnameinfo( + address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV + ) + port = int(_port) + else: + host, port = address[:2] + else: # IPv4 + assert family == socket.AF_INET + host, port = address # type: ignore[misc] hosts.append( { "hostname": hostname, diff --git a/tests/test_resolver.py b/tests/test_resolver.py index e84733ff4f..c68120b5c0 100644 --- a/tests/test_resolver.py +++ b/tests/test_resolver.py @@ -44,7 +44,7 @@ async def fake(*args: Any, **kwargs: Any) -> List[Any]: if not hosts: raise socket.gaierror - return [(None, None, None, None, [h, 0]) for h in hosts] + return [(socket.AF_INET, None, socket.SOCK_STREAM, None, [h, 0]) for h in hosts] return fake