We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Connecting to IPv6-only hosts fails with a `RuntimeError`
### Describe the bug

When aiohttp tries to connect to a host with only IPv6 address (with no IPv4 address), the exception `RuntimeError: coroutine raised StopIteration` is raised in [`TCPConnector._create_direct_connection`](https://github.com/aio-libs/aiohttp/blob/v3.8.0/aiohttp/connector.py#L1153) caused by the `StopIteration` in [`_DNSCacheTable.next_addrs`](https://github.com/aio-libs/aiohttp/blob/v3.8.0/aiohttp/connector.py#L716).

### To Reproduce

1. Create `aiohttp.ClientSession`.
2. Try to request an URL with IPv6-only host, e.g. `ipv6.google.com`.
E.g: `await ClientSession().get('https://ipv6.google.com')`

### Expected behavior

`await ClientSession().get('https://ipv6.google.com')` does not fail and returns a response.

### Logs/tracebacks

```python-traceback
$ python -m asyncio
asyncio REPL 3.9.7 (default, Oct 10 2021, 15:13:22)
[GCC 11.1.0] on linux
>>> import asyncio
>>> from aiohttp import ClientSession
>>> await ClientSession().get('https://ipv6.google.com')
Traceback (most recent call last):
  File "/home/***/.local/lib/python3.9/site-packages/aiohttp/connector.py", line 894, in _resolve_host
    return self._cached_hosts.next_addrs(key)
  File "/home/***/.local/lib/python3.9/site-packages/aiohttp/connector.py", line 716, in next_addrs
    next(loop)
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 445, in result
    return self.__get_result()
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 390, in __get_result
    raise self._exception
  File "<console>", line 1, in <module>
  File "/home/***/.local/lib/python3.9/site-packages/aiohttp/client.py", line 535, in _request
    conn = await self._connector.connect(
  File "/home/***/.local/lib/python3.9/site-packages/aiohttp/connector.py", line 543, in connect
    proto = await self._create_connection(req, traces, timeout)
  File "/home/***/.local/lib/python3.9/site-packages/aiohttp/connector.py", line 906, in _create_connection
    _, proto = await self._create_direct_connection(req, traces, timeout)
  File "/home/***/.local/lib/python3.9/site-packages/aiohttp/connector.py", line 1153, in _create_direct_connection
    hosts = await asyncio.shield(host_resolved)
RuntimeError: coroutine raised StopIteration
```


### Python Version

```console
$ python --version
Python 3.9.7
```


### aiohttp Version

```console
$ python -m pip show aiohttp
Name: aiohttp
Version: 3.8.0
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author:
Author-email:
License: Apache 2
Location: /home/***/.local/lib/python3.9/site-packages
Requires: aiosignal, async-timeout, attrs, charset-normalizer, frozenlist, multidict, yarl
Required-by:
```


### multidict Version

```console
$ python -m pip show multidict
Name: multidict
Version: 5.1.0
Summary: multidict implementation
Home-page: https://github.com/aio-libs/multidict
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: Apache 2
Location: /home/***/.local/lib/python3.9/site-packages
Requires:
Required-by: aiohttp, grpclib, yarl
```


### yarl Version

```console
$ python -m pip show yarl
Name: yarl
Version: 1.6.3
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl/
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: Apache 2
Location: /home/***/.local/lib/python3.9/site-packages
Requires: idna, multidict
Required-by: aiohttp
```


### OS

Linux

### Related component

Client

### Additional context

_No response_

### Code of Conduct

- [X] I agree to follow the aio-libs Code of Conduct

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `aiohttp/resolver.py`
Content:
```
1 import asyncio
2 import socket
3 from typing import Any, Dict, List, Type, Union
4 
5 from .abc import AbstractResolver
6 
7 __all__ = ("ThreadedResolver", "AsyncResolver", "DefaultResolver")
8 
9 try:
10     import aiodns
11 
12     # aiodns_default = hasattr(aiodns.DNSResolver, 'gethostbyname')
13 except ImportError:  # pragma: no cover
14     aiodns = None
15 
16 aiodns_default = False
17 
18 
19 class ThreadedResolver(AbstractResolver):
20     """Threaded resolver.
21 
22     Uses an Executor for synchronous getaddrinfo() calls.
23     concurrent.futures.ThreadPoolExecutor is used by default.
24     """
25 
26     def __init__(self) -> None:
27         self._loop = asyncio.get_running_loop()
28 
29     async def resolve(
30         self, hostname: str, port: int = 0, family: int = socket.AF_INET
31     ) -> List[Dict[str, Any]]:
32         infos = await self._loop.getaddrinfo(
33             hostname,
34             port,
35             type=socket.SOCK_STREAM,
36             family=family,
37             flags=socket.AI_ADDRCONFIG,
38         )
39 
40         hosts = []
41         for family, _, proto, _, address in infos:
42             if family == socket.AF_INET6:
43                 if not (socket.has_ipv6 and address[3]):  # type: ignore[misc]
44                     continue
45                 # This is essential for link-local IPv6 addresses.
46                 # LL IPv6 is a VERY rare case. Strictly speaking, we should use
47                 # getnameinfo() unconditionally, but performance makes sense.
48                 host, _port = socket.getnameinfo(
49                     address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV
50                 )
51                 port = int(_port)
52             else:
53                 host, port = address[:2]
54             hosts.append(
55                 {
56                     "hostname": hostname,
57                     "host": host,
58                     "port": port,
59                     "family": family,
60                     "proto": proto,
61                     "flags": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,
62                 }
63             )
64 
65         return hosts
66 
67     async def close(self) -> None:
68         pass
69 
70 
71 class AsyncResolver(AbstractResolver):
72     """Use the `aiodns` package to make asynchronous DNS lookups"""
73 
74     def __init__(self, *args: Any, **kwargs: Any) -> None:
75         if aiodns is None:
76             raise RuntimeError("Resolver requires aiodns library")
77 
78         self._loop = asyncio.get_running_loop()
79         self._resolver = aiodns.DNSResolver(*args, loop=self._loop, **kwargs)
80 
81     async def resolve(
82         self, host: str, port: int = 0, family: int = socket.AF_INET
83     ) -> List[Dict[str, Any]]:
84         try:
85             resp = await self._resolver.gethostbyname(host, family)
86         except aiodns.error.DNSError as exc:
87             msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed"
88             raise OSError(msg) from exc
89         hosts = []
90         for address in resp.addresses:
91             hosts.append(
92                 {
93                     "hostname": host,
94                     "host": address,
95                     "port": port,
96                     "family": family,
97                     "proto": 0,
98                     "flags": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,
99                 }
100             )
101 
102         if not hosts:
103             raise OSError("DNS lookup failed")
104 
105         return hosts
106 
107     async def close(self) -> None:
108         self._resolver.cancel()
109 
110 
111 _DefaultType = Type[Union[AsyncResolver, ThreadedResolver]]
112 DefaultResolver: _DefaultType = AsyncResolver if aiodns_default else ThreadedResolver
113
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/aiohttp/resolver.py b/aiohttp/resolver.py
--- a/aiohttp/resolver.py
+++ b/aiohttp/resolver.py
@@ -40,17 +40,23 @@
         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,

{"golden_diff": "diff --git a/aiohttp/resolver.py b/aiohttp/resolver.py\n--- a/aiohttp/resolver.py\n+++ b/aiohttp/resolver.py\n@@ -40,17 +40,23 @@\n         hosts = []\n         for family, _, proto, _, address in infos:\n             if family == socket.AF_INET6:\n-                if not (socket.has_ipv6 and address[3]):  # type: ignore[misc]\n+                if len(address) < 3:\n+                    # IPv6 is not supported by Python build,\n+                    # or IPv6 is not enabled in the host\n                     continue\n-                # This is essential for link-local IPv6 addresses.\n-                # LL IPv6 is a VERY rare case. Strictly speaking, we should use\n-                # getnameinfo() unconditionally, but performance makes sense.\n-                host, _port = socket.getnameinfo(\n-                    address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV\n-                )\n-                port = int(_port)\n-            else:\n-                host, port = address[:2]\n+                if address[3]:  # type: ignore[misc]\n+                    # This is essential for link-local IPv6 addresses.\n+                    # LL IPv6 is a VERY rare case. Strictly speaking, we should use\n+                    # getnameinfo() unconditionally, but performance makes sense.\n+                    host, _port = socket.getnameinfo(\n+                        address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV\n+                    )\n+                    port = int(_port)\n+                else:\n+                    host, port = address[:2]\n+            else:  # IPv4\n+                assert family == socket.AF_INET\n+                host, port = address  # type: ignore[misc]\n             hosts.append(\n                 {\n                     \"hostname\": hostname,\n", "issue": "Connecting to IPv6-only hosts fails with a `RuntimeError`\n### Describe the bug\r\n\r\nWhen aiohttp tries to connect to a host with only IPv6 address (with no IPv4 address), the exception `RuntimeError: coroutine raised StopIteration` is raised in [`TCPConnector._create_direct_connection`](https://github.com/aio-libs/aiohttp/blob/v3.8.0/aiohttp/connector.py#L1153) caused by the `StopIteration` in [`_DNSCacheTable.next_addrs`](https://github.com/aio-libs/aiohttp/blob/v3.8.0/aiohttp/connector.py#L716).\r\n\r\n### To Reproduce\r\n\r\n1. Create `aiohttp.ClientSession`.\r\n2. Try to request an URL with IPv6-only host, e.g. `ipv6.google.com`.\r\nE.g: `await ClientSession().get('https://ipv6.google.com')`\r\n\r\n### Expected behavior\r\n\r\n`await ClientSession().get('https://ipv6.google.com')` does not fail and returns a response.\r\n\r\n### Logs/tracebacks\r\n\r\n```python-traceback\r\n$ python -m asyncio\r\nasyncio REPL 3.9.7 (default, Oct 10 2021, 15:13:22)\r\n[GCC 11.1.0] on linux\r\n>>> import asyncio\r\n>>> from aiohttp import ClientSession\r\n>>> await ClientSession().get('https://ipv6.google.com')\r\nTraceback (most recent call last):\r\n  File \"/home/***/.local/lib/python3.9/site-packages/aiohttp/connector.py\", line 894, in _resolve_host\r\n    return self._cached_hosts.next_addrs(key)\r\n  File \"/home/***/.local/lib/python3.9/site-packages/aiohttp/connector.py\", line 716, in next_addrs\r\n    next(loop)\r\nStopIteration\r\n\r\nThe above exception was the direct cause of the following exception:\r\n\r\nTraceback (most recent call last):\r\n  File \"/usr/lib/python3.9/concurrent/futures/_base.py\", line 445, in result\r\n    return self.__get_result()\r\n  File \"/usr/lib/python3.9/concurrent/futures/_base.py\", line 390, in __get_result\r\n    raise self._exception\r\n  File \"<console>\", line 1, in <module>\r\n  File \"/home/***/.local/lib/python3.9/site-packages/aiohttp/client.py\", line 535, in _request\r\n    conn = await self._connector.connect(\r\n  File \"/home/***/.local/lib/python3.9/site-packages/aiohttp/connector.py\", line 543, in connect\r\n    proto = await self._create_connection(req, traces, timeout)\r\n  File \"/home/***/.local/lib/python3.9/site-packages/aiohttp/connector.py\", line 906, in _create_connection\r\n    _, proto = await self._create_direct_connection(req, traces, timeout)\r\n  File \"/home/***/.local/lib/python3.9/site-packages/aiohttp/connector.py\", line 1153, in _create_direct_connection\r\n    hosts = await asyncio.shield(host_resolved)\r\nRuntimeError: coroutine raised StopIteration\r\n```\r\n\r\n\r\n### Python Version\r\n\r\n```console\r\n$ python --version\r\nPython 3.9.7\r\n```\r\n\r\n\r\n### aiohttp Version\r\n\r\n```console\r\n$ python -m pip show aiohttp\r\nName: aiohttp\r\nVersion: 3.8.0\r\nSummary: Async http client/server framework (asyncio)\r\nHome-page: https://github.com/aio-libs/aiohttp\r\nAuthor:\r\nAuthor-email:\r\nLicense: Apache 2\r\nLocation: /home/***/.local/lib/python3.9/site-packages\r\nRequires: aiosignal, async-timeout, attrs, charset-normalizer, frozenlist, multidict, yarl\r\nRequired-by:\r\n```\r\n\r\n\r\n### multidict Version\r\n\r\n```console\r\n$ python -m pip show multidict\r\nName: multidict\r\nVersion: 5.1.0\r\nSummary: multidict implementation\r\nHome-page: https://github.com/aio-libs/multidict\r\nAuthor: Andrew Svetlov\r\nAuthor-email: andrew.svetlov@gmail.com\r\nLicense: Apache 2\r\nLocation: /home/***/.local/lib/python3.9/site-packages\r\nRequires:\r\nRequired-by: aiohttp, grpclib, yarl\r\n```\r\n\r\n\r\n### yarl Version\r\n\r\n```console\r\n$ python -m pip show yarl\r\nName: yarl\r\nVersion: 1.6.3\r\nSummary: Yet another URL library\r\nHome-page: https://github.com/aio-libs/yarl/\r\nAuthor: Andrew Svetlov\r\nAuthor-email: andrew.svetlov@gmail.com\r\nLicense: Apache 2\r\nLocation: /home/***/.local/lib/python3.9/site-packages\r\nRequires: idna, multidict\r\nRequired-by: aiohttp\r\n```\r\n\r\n\r\n### OS\r\n\r\nLinux\r\n\r\n### Related component\r\n\r\nClient\r\n\r\n### Additional context\r\n\r\n_No response_\r\n\r\n### Code of Conduct\r\n\r\n- [X] I agree to follow the aio-libs Code of Conduct\n", "before_files": [{"content": "import asyncio\nimport socket\nfrom typing import Any, Dict, List, Type, Union\n\nfrom .abc import AbstractResolver\n\n__all__ = (\"ThreadedResolver\", \"AsyncResolver\", \"DefaultResolver\")\n\ntry:\n    import aiodns\n\n    # aiodns_default = hasattr(aiodns.DNSResolver, 'gethostbyname')\nexcept ImportError:  # pragma: no cover\n    aiodns = None\n\naiodns_default = False\n\n\nclass ThreadedResolver(AbstractResolver):\n    \"\"\"Threaded resolver.\n\n    Uses an Executor for synchronous getaddrinfo() calls.\n    concurrent.futures.ThreadPoolExecutor is used by default.\n    \"\"\"\n\n    def __init__(self) -> None:\n        self._loop = asyncio.get_running_loop()\n\n    async def resolve(\n        self, hostname: str, port: int = 0, family: int = socket.AF_INET\n    ) -> List[Dict[str, Any]]:\n        infos = await self._loop.getaddrinfo(\n            hostname,\n            port,\n            type=socket.SOCK_STREAM,\n            family=family,\n            flags=socket.AI_ADDRCONFIG,\n        )\n\n        hosts = []\n        for family, _, proto, _, address in infos:\n            if family == socket.AF_INET6:\n                if not (socket.has_ipv6 and address[3]):  # type: ignore[misc]\n                    continue\n                # This is essential for link-local IPv6 addresses.\n                # LL IPv6 is a VERY rare case. Strictly speaking, we should use\n                # getnameinfo() unconditionally, but performance makes sense.\n                host, _port = socket.getnameinfo(\n                    address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV\n                )\n                port = int(_port)\n            else:\n                host, port = address[:2]\n            hosts.append(\n                {\n                    \"hostname\": hostname,\n                    \"host\": host,\n                    \"port\": port,\n                    \"family\": family,\n                    \"proto\": proto,\n                    \"flags\": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,\n                }\n            )\n\n        return hosts\n\n    async def close(self) -> None:\n        pass\n\n\nclass AsyncResolver(AbstractResolver):\n    \"\"\"Use the `aiodns` package to make asynchronous DNS lookups\"\"\"\n\n    def __init__(self, *args: Any, **kwargs: Any) -> None:\n        if aiodns is None:\n            raise RuntimeError(\"Resolver requires aiodns library\")\n\n        self._loop = asyncio.get_running_loop()\n        self._resolver = aiodns.DNSResolver(*args, loop=self._loop, **kwargs)\n\n    async def resolve(\n        self, host: str, port: int = 0, family: int = socket.AF_INET\n    ) -> List[Dict[str, Any]]:\n        try:\n            resp = await self._resolver.gethostbyname(host, family)\n        except aiodns.error.DNSError as exc:\n            msg = exc.args[1] if len(exc.args) >= 1 else \"DNS lookup failed\"\n            raise OSError(msg) from exc\n        hosts = []\n        for address in resp.addresses:\n            hosts.append(\n                {\n                    \"hostname\": host,\n                    \"host\": address,\n                    \"port\": port,\n                    \"family\": family,\n                    \"proto\": 0,\n                    \"flags\": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,\n                }\n            )\n\n        if not hosts:\n            raise OSError(\"DNS lookup failed\")\n\n        return hosts\n\n    async def close(self) -> None:\n        self._resolver.cancel()\n\n\n_DefaultType = Type[Union[AsyncResolver, ThreadedResolver]]\nDefaultResolver: _DefaultType = AsyncResolver if aiodns_default else ThreadedResolver\n", "path": "aiohttp/resolver.py"}], "after_files": [{"content": "import asyncio\nimport socket\nfrom typing import Any, Dict, List, Type, Union\n\nfrom .abc import AbstractResolver\n\n__all__ = (\"ThreadedResolver\", \"AsyncResolver\", \"DefaultResolver\")\n\ntry:\n    import aiodns\n\n    # aiodns_default = hasattr(aiodns.DNSResolver, 'gethostbyname')\nexcept ImportError:  # pragma: no cover\n    aiodns = None\n\naiodns_default = False\n\n\nclass ThreadedResolver(AbstractResolver):\n    \"\"\"Threaded resolver.\n\n    Uses an Executor for synchronous getaddrinfo() calls.\n    concurrent.futures.ThreadPoolExecutor is used by default.\n    \"\"\"\n\n    def __init__(self) -> None:\n        self._loop = asyncio.get_running_loop()\n\n    async def resolve(\n        self, hostname: str, port: int = 0, family: int = socket.AF_INET\n    ) -> List[Dict[str, Any]]:\n        infos = await self._loop.getaddrinfo(\n            hostname,\n            port,\n            type=socket.SOCK_STREAM,\n            family=family,\n            flags=socket.AI_ADDRCONFIG,\n        )\n\n        hosts = []\n        for family, _, proto, _, address in infos:\n            if family == socket.AF_INET6:\n                if len(address) < 3:\n                    # IPv6 is not supported by Python build,\n                    # or IPv6 is not enabled in the host\n                    continue\n                if address[3]:  # type: ignore[misc]\n                    # This is essential for link-local IPv6 addresses.\n                    # LL IPv6 is a VERY rare case. Strictly speaking, we should use\n                    # getnameinfo() unconditionally, but performance makes sense.\n                    host, _port = socket.getnameinfo(\n                        address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV\n                    )\n                    port = int(_port)\n                else:\n                    host, port = address[:2]\n            else:  # IPv4\n                assert family == socket.AF_INET\n                host, port = address  # type: ignore[misc]\n            hosts.append(\n                {\n                    \"hostname\": hostname,\n                    \"host\": host,\n                    \"port\": port,\n                    \"family\": family,\n                    \"proto\": proto,\n                    \"flags\": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,\n                }\n            )\n\n        return hosts\n\n    async def close(self) -> None:\n        pass\n\n\nclass AsyncResolver(AbstractResolver):\n    \"\"\"Use the `aiodns` package to make asynchronous DNS lookups\"\"\"\n\n    def __init__(self, *args: Any, **kwargs: Any) -> None:\n        if aiodns is None:\n            raise RuntimeError(\"Resolver requires aiodns library\")\n\n        self._loop = asyncio.get_running_loop()\n        self._resolver = aiodns.DNSResolver(*args, loop=self._loop, **kwargs)\n\n    async def resolve(\n        self, host: str, port: int = 0, family: int = socket.AF_INET\n    ) -> List[Dict[str, Any]]:\n        try:\n            resp = await self._resolver.gethostbyname(host, family)\n        except aiodns.error.DNSError as exc:\n            msg = exc.args[1] if len(exc.args) >= 1 else \"DNS lookup failed\"\n            raise OSError(msg) from exc\n        hosts = []\n        for address in resp.addresses:\n            hosts.append(\n                {\n                    \"hostname\": host,\n                    \"host\": address,\n                    \"port\": port,\n                    \"family\": family,\n                    \"proto\": 0,\n                    \"flags\": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,\n                }\n            )\n\n        if not hosts:\n            raise OSError(\"DNS lookup failed\")\n\n        return hosts\n\n    async def close(self) -> None:\n        self._resolver.cancel()\n\n\n_DefaultType = Type[Union[AsyncResolver, ThreadedResolver]]\nDefaultResolver: _DefaultType = AsyncResolver if aiodns_default else ThreadedResolver\n", "path": "aiohttp/resolver.py"}]}