Bump aiohttp to 3.10.0b1 (#122409)

This commit is contained in:
J. Nick Koston 2024-07-23 12:10:22 -05:00 committed by GitHub
parent d78327a72f
commit 6bdc5be433
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 6 additions and 132 deletions

View File

@ -22,7 +22,6 @@ from aiohttp.streams import StreamReader
from aiohttp.typedefs import JSONDecoder, StrOrURL from aiohttp.typedefs import JSONDecoder, StrOrURL
from aiohttp.web_exceptions import HTTPMovedPermanently, HTTPRedirection from aiohttp.web_exceptions import HTTPMovedPermanently, HTTPRedirection
from aiohttp.web_protocol import RequestHandler from aiohttp.web_protocol import RequestHandler
from aiohttp_fast_url_dispatcher import FastUrlDispatcher, attach_fast_url_dispatcher
from cryptography import x509 from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives.asymmetric import rsa
@ -335,10 +334,6 @@ class HomeAssistantHTTP:
"max_field_size": MAX_LINE_SIZE, "max_field_size": MAX_LINE_SIZE,
}, },
) )
# By default aiohttp does a linear search for routing rules,
# we have a lot of routes, so use a dict lookup with a fallback
# to the linear search.
attach_fast_url_dispatcher(self.app, FastUrlDispatcher())
self.hass = hass self.hass = hass
self.ssl_certificate = ssl_certificate self.ssl_certificate = ssl_certificate
self.ssl_peer_certificate = ssl_peer_certificate self.ssl_peer_certificate = ssl_peer_certificate

View File

@ -14,6 +14,7 @@ from typing import TYPE_CHECKING, Any
import aiohttp import aiohttp
from aiohttp import web from aiohttp import web
from aiohttp.hdrs import CONTENT_TYPE, USER_AGENT from aiohttp.hdrs import CONTENT_TYPE, USER_AGENT
from aiohttp.resolver import AsyncResolver
from aiohttp.web_exceptions import HTTPBadGateway, HTTPGatewayTimeout from aiohttp.web_exceptions import HTTPBadGateway, HTTPGatewayTimeout
from homeassistant import config_entries from homeassistant import config_entries
@ -24,7 +25,6 @@ from homeassistant.util import ssl as ssl_util
from homeassistant.util.hass_dict import HassKey from homeassistant.util.hass_dict import HassKey
from homeassistant.util.json import json_loads from homeassistant.util.json import json_loads
from .backports.aiohttp_resolver import AsyncResolver
from .frame import warn_use from .frame import warn_use
from .json import json_dumps from .json import json_dumps

View File

@ -1 +0,0 @@
"""Backports for helpers."""

View File

@ -1,116 +0,0 @@
"""Backport of aiohttp's AsyncResolver for Home Assistant.
This is a backport of the AsyncResolver class from aiohttp 3.10.
Before aiohttp 3.10, on system with IPv6 support, AsyncResolver would not fallback
to providing A records when AAAA records were not available.
Additionally, unlike the ThreadedResolver, AsyncResolver
did not handle link-local addresses correctly.
"""
from __future__ import annotations
import asyncio
import socket
import sys
from typing import Any, TypedDict
import aiodns
from aiohttp.abc import AbstractResolver
# This is a backport of https://github.com/aio-libs/aiohttp/pull/8270
# This can be removed once aiohttp 3.10 is the minimum supported version.
_NUMERIC_SOCKET_FLAGS = socket.AI_NUMERICHOST | socket.AI_NUMERICSERV
_SUPPORTS_SCOPE_ID = sys.version_info >= (3, 9, 0)
class ResolveResult(TypedDict):
"""Resolve result.
This is the result returned from an AbstractResolver's
resolve method.
:param hostname: The hostname that was provided.
:param host: The IP address that was resolved.
:param port: The port that was resolved.
:param family: The address family that was resolved.
:param proto: The protocol that was resolved.
:param flags: The flags that were resolved.
"""
hostname: str
host: str
port: int
family: int
proto: int
flags: int
class AsyncResolver(AbstractResolver):
"""Use the `aiodns` package to make asynchronous DNS lookups."""
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""Initialize the resolver."""
if aiodns is None:
raise RuntimeError("Resolver requires aiodns library")
self._loop = asyncio.get_running_loop()
self._resolver = aiodns.DNSResolver(*args, loop=self._loop, **kwargs) # type: ignore[misc]
async def resolve( # type: ignore[override]
self, host: str, port: int = 0, family: int = socket.AF_INET
) -> list[ResolveResult]:
"""Resolve a host name to an IP address."""
try:
resp = await self._resolver.getaddrinfo(
host,
port=port,
type=socket.SOCK_STREAM,
family=family, # type: ignore[arg-type]
flags=socket.AI_ADDRCONFIG,
)
except aiodns.error.DNSError as exc:
msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed"
raise OSError(msg) from exc
hosts: list[ResolveResult] = []
for node in resp.nodes:
address: tuple[bytes, int] | tuple[bytes, int, int, int] = node.addr
family = node.family
if family == socket.AF_INET6:
if len(address) > 3 and address[3] and _SUPPORTS_SCOPE_ID:
# 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.
result = await self._resolver.getnameinfo(
(address[0].decode("ascii"), *address[1:]),
_NUMERIC_SOCKET_FLAGS,
)
resolved_host = result.node
else:
resolved_host = address[0].decode("ascii")
port = address[1]
else: # IPv4
assert family == socket.AF_INET
resolved_host = address[0].decode("ascii")
port = address[1]
hosts.append(
ResolveResult(
hostname=host,
host=resolved_host,
port=port,
family=family,
proto=0,
flags=_NUMERIC_SOCKET_FLAGS,
)
)
if not hosts:
raise OSError("DNS lookup failed")
return hosts
async def close(self) -> None:
"""Close the resolver."""
self._resolver.cancel()

View File

@ -3,9 +3,8 @@
aiodhcpwatcher==1.0.2 aiodhcpwatcher==1.0.2
aiodiscover==2.1.0 aiodiscover==2.1.0
aiodns==3.2.0 aiodns==3.2.0
aiohttp-fast-url-dispatcher==0.3.0
aiohttp-fast-zlib==0.1.1 aiohttp-fast-zlib==0.1.1
aiohttp==3.9.5 aiohttp==3.10.0b1
aiohttp_cors==0.7.0 aiohttp_cors==0.7.0
aiozoneinfo==0.2.1 aiozoneinfo==0.2.1
astral==2.2 astral==2.2

View File

@ -24,9 +24,8 @@ classifiers = [
requires-python = ">=3.12.0" requires-python = ">=3.12.0"
dependencies = [ dependencies = [
"aiodns==3.2.0", "aiodns==3.2.0",
"aiohttp==3.9.5", "aiohttp==3.10.0b1",
"aiohttp_cors==0.7.0", "aiohttp_cors==0.7.0",
"aiohttp-fast-url-dispatcher==0.3.0",
"aiohttp-fast-zlib==0.1.1", "aiohttp-fast-zlib==0.1.1",
"aiozoneinfo==0.2.1", "aiozoneinfo==0.2.1",
"astral==2.2", "astral==2.2",

View File

@ -4,9 +4,8 @@
# Home Assistant Core # Home Assistant Core
aiodns==3.2.0 aiodns==3.2.0
aiohttp==3.9.5 aiohttp==3.10.0b1
aiohttp_cors==0.7.0 aiohttp_cors==0.7.0
aiohttp-fast-url-dispatcher==0.3.0
aiohttp-fast-zlib==0.1.1 aiohttp-fast-zlib==0.1.1
aiozoneinfo==0.2.1 aiozoneinfo==0.2.1
astral==2.2 astral==2.2

View File

@ -125,7 +125,6 @@ EXCEPTIONS = {
"aiocomelit", # https://github.com/chemelli74/aiocomelit/pull/138 "aiocomelit", # https://github.com/chemelli74/aiocomelit/pull/138
"aioecowitt", # https://github.com/home-assistant-libs/aioecowitt/pull/180 "aioecowitt", # https://github.com/home-assistant-libs/aioecowitt/pull/180
"aiohappyeyeballs", # PSF-2.0 license "aiohappyeyeballs", # PSF-2.0 license
"aiohttp-fast-url-dispatcher", # https://github.com/bdraco/aiohttp-fast-url-dispatcher/pull/10
"aioopenexchangerates", # https://github.com/MartinHjelmare/aioopenexchangerates/pull/94 "aioopenexchangerates", # https://github.com/MartinHjelmare/aioopenexchangerates/pull/94
"aiooui", # https://github.com/Bluetooth-Devices/aiooui/pull/8 "aiooui", # https://github.com/Bluetooth-Devices/aiooui/pull/8
"aioruuvigateway", # https://github.com/akx/aioruuvigateway/pull/6 "aioruuvigateway", # https://github.com/akx/aioruuvigateway/pull/6

View File

@ -5,7 +5,7 @@ from datetime import timedelta
from typing import Any, cast from typing import Any, cast
from unittest.mock import patch from unittest.mock import patch
from aiohttp import ServerDisconnectedError, WSMsgType, web from aiohttp import WSMsgType, WSServerHandshakeError, web
import pytest import pytest
from homeassistant.components.websocket_api import ( from homeassistant.components.websocket_api import (
@ -374,7 +374,7 @@ async def test_prepare_fail(
"homeassistant.components.websocket_api.http.web.WebSocketResponse.prepare", "homeassistant.components.websocket_api.http.web.WebSocketResponse.prepare",
side_effect=(TimeoutError, web.WebSocketResponse.prepare), side_effect=(TimeoutError, web.WebSocketResponse.prepare),
), ),
pytest.raises(ServerDisconnectedError), pytest.raises(WSServerHandshakeError),
): ):
await hass_ws_client(hass) await hass_ws_client(hass)