We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
GET Requests to link-local IPv6 addresses don't work on Python 3.7+
🐞 **Describe the bug**
The aiohttp resolver loses information related to linklocal IPv6 addresses on Python 3.7+ due to a changes in the representation returned by `socket.getaddrinfo()`

💡 **To Reproduce**
Try to get an URL like `http://[fe80::1%eth0]:8080/`, it will result in an OSError (Invalid argument) exception.

This seems to be due to the way that scopeid's are handled in [resolver.py](https://github.com/aio-libs/aiohttp/blob/72c2acd4850b1cbc638b413a7c28d96882b4d7e8/aiohttp/resolver.py#L31-L37):

Run `socket.getaddrinfo('fe80::1%eth0', 8080, family=socket.AF_INET6, proto=socket.IPPROTO_TCP)[0][4]` on python 3.6:
```python
socket.getaddrinfo('fe80::1%eth0', 8080, family=socket.AF_INET6, proto=socket.IPPROTO_TCP)[0][4]
>>> socket.getaddrinfo('fe80::1%eth0', 8080, family=socket.AF_INET6, proto=socket.IPPROTO_TCP)[0][4]
('fe80::1%eth0', 8080, 0, 4)
```

Run it on python 3.7:
```python
>>> socket.getaddrinfo('fe80::1%eth0', 8080, family=socket.AF_INET6, proto=socket.IPPROTO_TCP)[0][4]
('fe80::1', 8080, 0, 4)y
```

The `address` element of the tuple no longer includes the textual representation of the scope id, it's only contained in the matching scope_id element of the tuple - which then is missing when later callings _loop.create_connection().

💡 **Expected behavior**
The URL is successfully retrieved for link local IPv6 addresses.


📋 **Logs/tracebacks**
```python-traceback (paste your traceback in the next line)
N/A
```

📋 **Your version of the Python**
```console
$ python3 --version
Python 3.6.6
$ python3.7 --version
Python 3.7.5
```

📋 **Your version of the aiohttp/yarl/multidict distributions**
```console
$ python -m pip show aiohttp
python -m pip show aiohttp
Name: aiohttp
Version: 3.6.2
```
```console
$ python -m pip show multidict
Name: multidict
Version: 4.7.4
```
```console
$ python -m pip show yarl
Name: yarl
Version: 1.4.2
```

📋 **Additional context**
OS: Centos7 Linux
Proxy Server: No
Related to: client

--- 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 socket
2 from typing import Any, Dict, List
3 
4 from .abc import AbstractResolver
5 from .helpers import get_running_loop
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     """Use Executor for synchronous getaddrinfo() calls, which defaults to
21     concurrent.futures.ThreadPoolExecutor.
22     """
23 
24     def __init__(self) -> None:
25         self._loop = get_running_loop()
26 
27     async def resolve(self, host: str, port: int=0,
28                       family: int=socket.AF_INET) -> List[Dict[str, Any]]:
29         infos = await self._loop.getaddrinfo(
30             host, port, type=socket.SOCK_STREAM, family=family)
31 
32         hosts = []
33         for family, _, proto, _, address in infos:
34             hosts.append(
35                 {'hostname': host,
36                  'host': address[0], 'port': address[1],
37                  'family': family, 'proto': proto,
38                  'flags': socket.AI_NUMERICHOST})
39 
40         return hosts
41 
42     async def close(self) -> None:
43         pass
44 
45 
46 class AsyncResolver(AbstractResolver):
47     """Use the `aiodns` package to make asynchronous DNS lookups"""
48 
49     def __init__(self, *args: Any, **kwargs: Any) -> None:
50         if aiodns is None:
51             raise RuntimeError("Resolver requires aiodns library")
52 
53         self._loop = get_running_loop()
54         self._resolver = aiodns.DNSResolver(*args, loop=self._loop, **kwargs)
55 
56     async def resolve(self, host: str, port: int=0,
57                       family: int=socket.AF_INET) -> List[Dict[str, Any]]:
58         try:
59             resp = await self._resolver.gethostbyname(host, family)
60         except aiodns.error.DNSError as exc:
61             msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed"
62             raise OSError(msg) from exc
63         hosts = []
64         for address in resp.addresses:
65             hosts.append(
66                 {'hostname': host,
67                  'host': address, 'port': port,
68                  'family': family, 'proto': 0,
69                  'flags': socket.AI_NUMERICHOST})
70 
71         if not hosts:
72             raise OSError("DNS lookup failed")
73 
74         return hosts
75 
76     async def close(self) -> None:
77         return self._resolver.cancel()
78 
79 
80 DefaultResolver = AsyncResolver if aiodns_default else ThreadedResolver
81
```
--- 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
@@ -31,11 +31,23 @@
 
         hosts = []
         for family, _, proto, _, address in infos:
-            hosts.append(
-                {'hostname': host,
-                 'host': address[0], 'port': address[1],
-                 'family': family, 'proto': proto,
-                 'flags': socket.AI_NUMERICHOST})
+            if family == socket.AF_INET6 and address[3]:  # type: ignore
+                # 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]
+            hosts.append({
+                'hostname': host,
+                'host': host,
+                'port': port,
+                'family': family,
+                'proto': proto,
+                'flags': socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,
+            })
 
         return hosts
 
@@ -62,11 +74,14 @@
             raise OSError(msg) from exc
         hosts = []
         for address in resp.addresses:
-            hosts.append(
-                {'hostname': host,
-                 'host': address, 'port': port,
-                 'family': family, 'proto': 0,
-                 'flags': socket.AI_NUMERICHOST})
+            hosts.append({
+                'hostname': host,
+                'host': address,
+                'port': port,
+                'family': family,
+                'proto': 0,
+                'flags': socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,
+            })
 
         if not hosts:
             raise OSError("DNS lookup failed")

{"golden_diff": "diff --git a/aiohttp/resolver.py b/aiohttp/resolver.py\n--- a/aiohttp/resolver.py\n+++ b/aiohttp/resolver.py\n@@ -31,11 +31,23 @@\n \n         hosts = []\n         for family, _, proto, _, address in infos:\n-            hosts.append(\n-                {'hostname': host,\n-                 'host': address[0], 'port': address[1],\n-                 'family': family, 'proto': proto,\n-                 'flags': socket.AI_NUMERICHOST})\n+            if family == socket.AF_INET6 and address[3]:  # type: ignore\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+                port = int(_port)\n+            else:\n+                host, port = address[:2]\n+            hosts.append({\n+                'hostname': host,\n+                'host': host,\n+                'port': port,\n+                'family': family,\n+                'proto': proto,\n+                'flags': socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,\n+            })\n \n         return hosts\n \n@@ -62,11 +74,14 @@\n             raise OSError(msg) from exc\n         hosts = []\n         for address in resp.addresses:\n-            hosts.append(\n-                {'hostname': host,\n-                 'host': address, 'port': port,\n-                 'family': family, 'proto': 0,\n-                 'flags': socket.AI_NUMERICHOST})\n+            hosts.append({\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         if not hosts:\n             raise OSError(\"DNS lookup failed\")\n", "issue": "GET Requests to link-local IPv6 addresses don't work on Python 3.7+\n\ud83d\udc1e **Describe the bug**\r\nThe aiohttp resolver loses information related to linklocal IPv6 addresses on Python 3.7+ due to a changes in the representation returned by `socket.getaddrinfo()`\r\n\r\n\ud83d\udca1 **To Reproduce**\r\nTry to get an URL like `http://[fe80::1%eth0]:8080/`, it will result in an OSError (Invalid argument) exception.\r\n\r\nThis seems to be due to the way that scopeid's are handled in [resolver.py](https://github.com/aio-libs/aiohttp/blob/72c2acd4850b1cbc638b413a7c28d96882b4d7e8/aiohttp/resolver.py#L31-L37):\r\n\r\nRun `socket.getaddrinfo('fe80::1%eth0', 8080, family=socket.AF_INET6, proto=socket.IPPROTO_TCP)[0][4]` on python 3.6:\r\n```python\r\nsocket.getaddrinfo('fe80::1%eth0', 8080, family=socket.AF_INET6, proto=socket.IPPROTO_TCP)[0][4]\r\n>>> socket.getaddrinfo('fe80::1%eth0', 8080, family=socket.AF_INET6, proto=socket.IPPROTO_TCP)[0][4]\r\n('fe80::1%eth0', 8080, 0, 4)\r\n```\r\n\r\nRun it on python 3.7:\r\n```python\r\n>>> socket.getaddrinfo('fe80::1%eth0', 8080, family=socket.AF_INET6, proto=socket.IPPROTO_TCP)[0][4]\r\n('fe80::1', 8080, 0, 4)y\r\n```\r\n\r\nThe `address` element of the tuple no longer includes the textual representation of the scope id, it's only contained in the matching scope_id element of the tuple - which then is missing when later callings _loop.create_connection().\r\n\r\n\ud83d\udca1 **Expected behavior**\r\nThe URL is successfully retrieved for link local IPv6 addresses.\r\n\r\n\r\n\ud83d\udccb **Logs/tracebacks**\r\n```python-traceback (paste your traceback in the next line)\r\nN/A\r\n```\r\n\r\n\ud83d\udccb **Your version of the Python**\r\n```console\r\n$ python3 --version\r\nPython 3.6.6\r\n$ python3.7 --version\r\nPython 3.7.5\r\n```\r\n\r\n\ud83d\udccb **Your version of the aiohttp/yarl/multidict distributions**\r\n```console\r\n$ python -m pip show aiohttp\r\npython -m pip show aiohttp\r\nName: aiohttp\r\nVersion: 3.6.2\r\n```\r\n```console\r\n$ python -m pip show multidict\r\nName: multidict\r\nVersion: 4.7.4\r\n```\r\n```console\r\n$ python -m pip show yarl\r\nName: yarl\r\nVersion: 1.4.2\r\n```\r\n\r\n\ud83d\udccb **Additional context**\r\nOS: Centos7 Linux\r\nProxy Server: No\r\nRelated to: client\n", "before_files": [{"content": "import socket\nfrom typing import Any, Dict, List\n\nfrom .abc import AbstractResolver\nfrom .helpers import get_running_loop\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    \"\"\"Use Executor for synchronous getaddrinfo() calls, which defaults to\n    concurrent.futures.ThreadPoolExecutor.\n    \"\"\"\n\n    def __init__(self) -> None:\n        self._loop = get_running_loop()\n\n    async def resolve(self, host: str, port: int=0,\n                      family: int=socket.AF_INET) -> List[Dict[str, Any]]:\n        infos = await self._loop.getaddrinfo(\n            host, port, type=socket.SOCK_STREAM, family=family)\n\n        hosts = []\n        for family, _, proto, _, address in infos:\n            hosts.append(\n                {'hostname': host,\n                 'host': address[0], 'port': address[1],\n                 'family': family, 'proto': proto,\n                 'flags': socket.AI_NUMERICHOST})\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 = get_running_loop()\n        self._resolver = aiodns.DNSResolver(*args, loop=self._loop, **kwargs)\n\n    async def resolve(self, host: str, port: int=0,\n                      family: int=socket.AF_INET) -> 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                {'hostname': host,\n                 'host': address, 'port': port,\n                 'family': family, 'proto': 0,\n                 'flags': socket.AI_NUMERICHOST})\n\n        if not hosts:\n            raise OSError(\"DNS lookup failed\")\n\n        return hosts\n\n    async def close(self) -> None:\n        return self._resolver.cancel()\n\n\nDefaultResolver = AsyncResolver if aiodns_default else ThreadedResolver\n", "path": "aiohttp/resolver.py"}], "after_files": [{"content": "import socket\nfrom typing import Any, Dict, List\n\nfrom .abc import AbstractResolver\nfrom .helpers import get_running_loop\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    \"\"\"Use Executor for synchronous getaddrinfo() calls, which defaults to\n    concurrent.futures.ThreadPoolExecutor.\n    \"\"\"\n\n    def __init__(self) -> None:\n        self._loop = get_running_loop()\n\n    async def resolve(self, host: str, port: int=0,\n                      family: int=socket.AF_INET) -> List[Dict[str, Any]]:\n        infos = await self._loop.getaddrinfo(\n            host, port, type=socket.SOCK_STREAM, family=family)\n\n        hosts = []\n        for family, _, proto, _, address in infos:\n            if family == socket.AF_INET6 and address[3]:  # type: ignore\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                port = int(_port)\n            else:\n                host, port = address[:2]\n            hosts.append({\n                'hostname': host,\n                'host': host,\n                'port': port,\n                'family': family,\n                'proto': proto,\n                'flags': socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,\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 = get_running_loop()\n        self._resolver = aiodns.DNSResolver(*args, loop=self._loop, **kwargs)\n\n    async def resolve(self, host: str, port: int=0,\n                      family: int=socket.AF_INET) -> 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                '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        if not hosts:\n            raise OSError(\"DNS lookup failed\")\n\n        return hosts\n\n    async def close(self) -> None:\n        return self._resolver.cancel()\n\n\nDefaultResolver = AsyncResolver if aiodns_default else ThreadedResolver\n", "path": "aiohttp/resolver.py"}]}