Voice et bot modif

This commit is contained in:
pi 2026-06-16 17:09:34 +00:00
parent 189d56026b
commit 7333a22bcd
10774 changed files with 634644 additions and 933308 deletions

View file

@ -6,30 +6,13 @@ import sys
import traceback
import warnings
from collections import OrderedDict, defaultdict, deque
from collections.abc import Awaitable, Callable, Iterator, Sequence
from contextlib import suppress
from http import HTTPStatus
from itertools import chain, cycle, islice
from time import monotonic
from types import TracebackType
from typing import (
TYPE_CHECKING,
Any,
Awaitable,
Callable,
DefaultDict,
Deque,
Dict,
Iterator,
List,
Literal,
Optional,
Sequence,
Set,
Tuple,
Type,
Union,
cast,
)
from typing import TYPE_CHECKING, Any, Literal, Optional, Union, cast
import aiohappyeyeballs
from aiohappyeyeballs import AddrInfoType, SocketFactoryType
@ -44,6 +27,7 @@ from .client_exceptions import (
ClientConnectorSSLError,
ClientHttpProxyError,
ClientProxyConnectionError,
InvalidUrlClientError,
ServerFingerprintMismatch,
UnixClientConnectorError,
cert_errors,
@ -54,6 +38,7 @@ from .client_reqrep import ClientRequest, Fingerprint, _merge_ssl_params
from .helpers import (
_SENTINEL,
ceil_timeout,
is_canonical_ipv4_address,
is_ip_address,
noop,
sentinel,
@ -92,9 +77,9 @@ NEEDS_CLEANUP_CLOSED = (3, 13, 0) <= sys.version_info < (
3,
13,
1,
) or sys.version_info < (3, 12, 7)
) or sys.version_info < (3, 12, 8)
# Cleanup closed is no longer needed after https://github.com/python/cpython/pull/118960
# which first appeared in Python 3.12.7 and 3.13.1
# which first appeared in Python 3.12.8 and 3.13.1
__all__ = (
@ -133,7 +118,7 @@ class _DeprecationWaiter:
)
async def _wait_for_close(waiters: List[Awaitable[object]]) -> None:
async def _wait_for_close(waiters: list[Awaitable[object]]) -> None:
"""Wait for all waiters to finish closing."""
results = await asyncio.gather(*waiters, return_exceptions=True)
for res in results:
@ -155,8 +140,8 @@ class Connection:
self._key = key
self._connector = connector
self._loop = loop
self._protocol: Optional[ResponseHandler] = protocol
self._callbacks: List[Callable[[], None]] = []
self._protocol: ResponseHandler | None = protocol
self._callbacks: list[Callable[[], None]] = []
if loop.get_debug():
self._source_traceback = traceback.extract_stack(sys._getframe(1))
@ -190,13 +175,13 @@ class Connection:
return self._loop
@property
def transport(self) -> Optional[asyncio.Transport]:
def transport(self) -> asyncio.Transport | None:
if self._protocol is None:
return None
return self._protocol.transport
@property
def protocol(self) -> Optional[ResponseHandler]:
def protocol(self) -> ResponseHandler | None:
return self._protocol
def add_callback(self, callback: Callable[[], None]) -> None:
@ -254,7 +239,7 @@ class _TransportPlaceholder:
__slots__ = ("closed", "transport")
def __init__(self, closed_future: asyncio.Future[Optional[Exception]]) -> None:
def __init__(self, closed_future: asyncio.Future[Exception | None]) -> None:
"""Initialize a placeholder for a transport."""
self.closed = closed_future
self.transport = None
@ -292,12 +277,12 @@ class BaseConnector:
def __init__(
self,
*,
keepalive_timeout: Union[object, None, float] = sentinel,
keepalive_timeout: object | None | float = sentinel,
force_close: bool = False,
limit: int = 100,
limit_per_host: int = 0,
enable_cleanup_closed: bool = False,
loop: Optional[asyncio.AbstractEventLoop] = None,
loop: asyncio.AbstractEventLoop | None = None,
timeout_ceil_threshold: float = 5,
) -> None:
@ -320,13 +305,13 @@ class BaseConnector:
# Connection pool of reusable connections.
# We use a deque to store connections because it has O(1) popleft()
# and O(1) append() operations to implement a FIFO queue.
self._conns: DefaultDict[
ConnectionKey, Deque[Tuple[ResponseHandler, float]]
self._conns: defaultdict[
ConnectionKey, deque[tuple[ResponseHandler, float]]
] = defaultdict(deque)
self._limit = limit
self._limit_per_host = limit_per_host
self._acquired: Set[ResponseHandler] = set()
self._acquired_per_host: DefaultDict[ConnectionKey, Set[ResponseHandler]] = (
self._acquired: set[ResponseHandler] = set()
self._acquired_per_host: defaultdict[ConnectionKey, set[ResponseHandler]] = (
defaultdict(set)
)
self._keepalive_timeout = cast(float, keepalive_timeout)
@ -335,7 +320,7 @@ class BaseConnector:
# {host_key: FIFO list of waiters}
# The FIFO is implemented with an OrderedDict with None keys because
# python does not have an ordered set.
self._waiters: DefaultDict[
self._waiters: defaultdict[
ConnectionKey, OrderedDict[asyncio.Future[None], None]
] = defaultdict(OrderedDict)
@ -343,10 +328,10 @@ class BaseConnector:
self._factory = functools.partial(ResponseHandler, loop=loop)
# start keep-alive connection cleanup task
self._cleanup_handle: Optional[asyncio.TimerHandle] = None
self._cleanup_handle: asyncio.TimerHandle | None = None
# start cleanup closed transports task
self._cleanup_closed_handle: Optional[asyncio.TimerHandle] = None
self._cleanup_closed_handle: asyncio.TimerHandle | None = None
if enable_cleanup_closed and not NEEDS_CLEANUP_CLOSED:
warnings.warn(
@ -359,8 +344,8 @@ class BaseConnector:
enable_cleanup_closed = False
self._cleanup_closed_disabled = not enable_cleanup_closed
self._cleanup_closed_transports: List[Optional[asyncio.Transport]] = []
self._placeholder_future: asyncio.Future[Optional[Exception]] = (
self._cleanup_closed_transports: list[asyncio.Transport | None] = []
self._placeholder_future: asyncio.Future[Exception | None] = (
loop.create_future()
)
self._placeholder_future.set_result(None)
@ -403,9 +388,9 @@ class BaseConnector:
async def __aexit__(
self,
exc_type: Optional[Type[BaseException]] = None,
exc_value: Optional[BaseException] = None,
exc_traceback: Optional[TracebackType] = None,
exc_type: type[BaseException] | None = None,
exc_value: BaseException | None = None,
exc_traceback: TracebackType | None = None,
) -> None:
await self.close()
@ -447,7 +432,7 @@ class BaseConnector:
connections = defaultdict(deque)
deadline = now - timeout
for key, conns in self._conns.items():
alive: Deque[Tuple[ResponseHandler, float]] = deque()
alive: deque[tuple[ResponseHandler, float]] = deque()
for proto, use_time in conns:
if proto.is_connected() and use_time - deadline >= 0:
alive.append((proto, use_time))
@ -514,8 +499,8 @@ class BaseConnector:
task = self._loop.create_task(coro)
return _DeprecationWaiter(task)
def _close(self, *, abort_ssl: bool = False) -> List[Awaitable[object]]:
waiters: List[Awaitable[object]] = []
def _close(self, *, abort_ssl: bool = False) -> list[Awaitable[object]]:
waiters: list[Awaitable[object]] = []
if self._closed:
return waiters
@ -615,7 +600,7 @@ class BaseConnector:
"""Set Proxy-Authorization header for non-SSL proxy requests and builds the proxy request for SSL proxy requests."""
url = req.proxy
assert url is not None
headers: Dict[str, str] = {}
headers: dict[str, str] = {}
if req.proxy_headers is not None:
headers = req.proxy_headers # type: ignore[assignment]
headers[hdrs.HOST] = req.headers[hdrs.HOST]
@ -636,7 +621,7 @@ class BaseConnector:
return proxy_req
async def connect(
self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout"
self, req: ClientRequest, traces: list["Trace"], timeout: "ClientTimeout"
) -> Connection:
"""Get from pool or create new connection."""
key = req.connection_key
@ -695,7 +680,7 @@ class BaseConnector:
return Connection(self, key, proto, self._loop)
async def _wait_for_available_connection(
self, key: "ConnectionKey", traces: List["Trace"]
self, key: "ConnectionKey", traces: list["Trace"]
) -> None:
"""Wait for an available connection slot."""
# We loop here because there is a race between
@ -737,8 +722,8 @@ class BaseConnector:
attempts += 1
async def _get(
self, key: "ConnectionKey", traces: List["Trace"]
) -> Optional[Connection]:
self, key: "ConnectionKey", traces: list["Trace"]
) -> Connection | None:
"""Get next reusable connection for the key or None.
The connection will be marked as acquired.
@ -850,44 +835,53 @@ class BaseConnector:
)
async def _create_connection(
self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout"
self, req: ClientRequest, traces: list["Trace"], timeout: "ClientTimeout"
) -> ResponseHandler:
raise NotImplementedError()
class _DNSCacheTable:
def __init__(self, ttl: Optional[float] = None) -> None:
self._addrs_rr: Dict[Tuple[str, int], Tuple[Iterator[ResolveResult], int]] = {}
self._timestamps: Dict[Tuple[str, int], float] = {}
def __init__(self, ttl: float | None = None, max_size: int = 1000) -> None:
self._addrs_rr: OrderedDict[
tuple[str, int], tuple[Iterator[ResolveResult], int]
] = OrderedDict()
self._timestamps: dict[tuple[str, int], float] = {}
self._ttl = ttl
self._max_size = max_size
def __contains__(self, host: object) -> bool:
return host in self._addrs_rr
def add(self, key: Tuple[str, int], addrs: List[ResolveResult]) -> None:
def add(self, key: tuple[str, int], addrs: list[ResolveResult]) -> None:
if key in self._addrs_rr:
self._addrs_rr.move_to_end(key)
self._addrs_rr[key] = (cycle(addrs), len(addrs))
if self._ttl is not None:
self._timestamps[key] = monotonic()
def remove(self, key: Tuple[str, int]) -> None:
self._addrs_rr.pop(key, None)
if len(self._addrs_rr) > self._max_size:
oldest_key, _ = self._addrs_rr.popitem(last=False)
self._timestamps.pop(oldest_key, None)
if self._ttl is not None:
self._timestamps.pop(key, None)
def remove(self, key: tuple[str, int]) -> None:
self._addrs_rr.pop(key, None)
self._timestamps.pop(key, None)
def clear(self) -> None:
self._addrs_rr.clear()
self._timestamps.clear()
def next_addrs(self, key: Tuple[str, int]) -> List[ResolveResult]:
def next_addrs(self, key: tuple[str, int]) -> list[ResolveResult]:
loop, length = self._addrs_rr[key]
addrs = list(islice(loop, length))
# Consume one more element to shift internal state of `cycle`
next(loop)
self._addrs_rr.move_to_end(key)
return addrs
def expired(self, key: Tuple[str, int]) -> bool:
def expired(self, key: tuple[str, int]) -> bool:
if self._ttl is None:
return False
@ -970,25 +964,26 @@ class TCPConnector(BaseConnector):
self,
*,
verify_ssl: bool = True,
fingerprint: Optional[bytes] = None,
fingerprint: bytes | None = None,
use_dns_cache: bool = True,
ttl_dns_cache: Optional[int] = 10,
ttl_dns_cache: int | None = 10,
dns_cache_max_size: int = 1000,
family: socket.AddressFamily = socket.AddressFamily.AF_UNSPEC,
ssl_context: Optional[SSLContext] = None,
ssl: Union[bool, Fingerprint, SSLContext] = True,
local_addr: Optional[Tuple[str, int]] = None,
resolver: Optional[AbstractResolver] = None,
keepalive_timeout: Union[None, float, object] = sentinel,
ssl_context: SSLContext | None = None,
ssl: bool | Fingerprint | SSLContext = True,
local_addr: tuple[str, int] | None = None,
resolver: AbstractResolver | None = None,
keepalive_timeout: None | float | object = sentinel,
force_close: bool = False,
limit: int = 100,
limit_per_host: int = 0,
enable_cleanup_closed: bool = False,
loop: Optional[asyncio.AbstractEventLoop] = None,
loop: asyncio.AbstractEventLoop | None = None,
timeout_ceil_threshold: float = 5,
happy_eyeballs_delay: Optional[float] = 0.25,
interleave: Optional[int] = None,
socket_factory: Optional[SocketFactoryType] = None,
ssl_shutdown_timeout: Union[_SENTINEL, None, float] = sentinel,
happy_eyeballs_delay: float | None = 0.25,
interleave: int | None = None,
socket_factory: SocketFactoryType | None = None,
ssl_shutdown_timeout: _SENTINEL | None | float = sentinel,
):
super().__init__(
keepalive_timeout=keepalive_timeout,
@ -1011,17 +1006,19 @@ class TCPConnector(BaseConnector):
self._resolver_owner = False
self._use_dns_cache = use_dns_cache
self._cached_hosts = _DNSCacheTable(ttl=ttl_dns_cache)
self._throttle_dns_futures: Dict[
Tuple[str, int], Set["asyncio.Future[None]"]
] = {}
self._cached_hosts = _DNSCacheTable(
ttl=ttl_dns_cache, max_size=dns_cache_max_size
)
self._throttle_dns_futures: dict[tuple[str, int], set[asyncio.Future[None]]] = (
{}
)
self._family = family
self._local_addr_infos = aiohappyeyeballs.addr_to_addr_infos(local_addr)
self._happy_eyeballs_delay = happy_eyeballs_delay
self._interleave = interleave
self._resolve_host_tasks: Set["asyncio.Task[List[ResolveResult]]"] = set()
self._resolve_host_tasks: set[asyncio.Task[list[ResolveResult]]] = set()
self._socket_factory = socket_factory
self._ssl_shutdown_timeout: Optional[float]
self._ssl_shutdown_timeout: float | None
# Handle ssl_shutdown_timeout with warning for Python < 3.11
if ssl_shutdown_timeout is sentinel:
self._ssl_shutdown_timeout = 0
@ -1045,7 +1042,7 @@ class TCPConnector(BaseConnector):
)
self._ssl_shutdown_timeout = ssl_shutdown_timeout
def _close(self, *, abort_ssl: bool = False) -> List[Awaitable[object]]:
def _close(self, *, abort_ssl: bool = False) -> list[Awaitable[object]]:
"""Close all ongoing DNS calls."""
for fut in chain.from_iterable(self._throttle_dns_futures.values()):
fut.cancel()
@ -1068,10 +1065,10 @@ class TCPConnector(BaseConnector):
- If ssl_shutdown_timeout=0: connections are aborted
- If ssl_shutdown_timeout>0: graceful shutdown is performed
"""
if self._resolver_owner:
await self._resolver.close()
# Use abort_ssl param if explicitly set, otherwise use ssl_shutdown_timeout default
await super().close(abort_ssl=abort_ssl or self._ssl_shutdown_timeout == 0)
if self._resolver_owner:
await self._resolver.close()
@property
def family(self) -> int:
@ -1083,9 +1080,7 @@ class TCPConnector(BaseConnector):
"""True if local DNS caching is enabled."""
return self._use_dns_cache
def clear_dns_cache(
self, host: Optional[str] = None, port: Optional[int] = None
) -> None:
def clear_dns_cache(self, host: str | None = None, port: int | None = None) -> None:
"""Remove specified host/port or clear all dns local cache."""
if host is not None and port is not None:
self._cached_hosts.remove((host, port))
@ -1095,10 +1090,15 @@ class TCPConnector(BaseConnector):
self._cached_hosts.clear()
async def _resolve_host(
self, host: str, port: int, traces: Optional[Sequence["Trace"]] = None
) -> List[ResolveResult]:
self, host: str, port: int, traces: Sequence["Trace"] | None = None
) -> list[ResolveResult]:
"""Resolve host and return list of addresses."""
if is_ip_address(host):
# Reject legacy numeric IPv4 forms (e.g. 2130706433, 127.1) that
# socket would map onto an address, slipping past a connector-level
# policy that only sees the raw host.
if ":" not in host and not is_canonical_ipv4_address(host):
raise InvalidUrlClientError(host, "is not a canonical IPv4 address")
return [
{
"hostname": host,
@ -1116,6 +1116,9 @@ class TCPConnector(BaseConnector):
for trace in traces:
await trace.send_dns_resolvehost_start(host)
if self._closed:
raise ClientConnectionError("Connector is closed")
res = await self._resolver.resolve(host, port, family=self._family)
if traces:
@ -1134,7 +1137,7 @@ class TCPConnector(BaseConnector):
await trace.send_dns_cache_hit(host)
return result
futures: Set["asyncio.Future[None]"]
futures: set[asyncio.Future[None]]
#
# If multiple connectors are resolving the same host, we wait
# for the first one to resolve and then use the result for all of them.
@ -1178,7 +1181,7 @@ class TCPConnector(BaseConnector):
return await asyncio.shield(resolved_host_task)
except asyncio.CancelledError:
def drop_exception(fut: "asyncio.Future[List[ResolveResult]]") -> None:
def drop_exception(fut: "asyncio.Future[list[ResolveResult]]") -> None:
with suppress(Exception, asyncio.CancelledError):
fut.result()
@ -1187,12 +1190,12 @@ class TCPConnector(BaseConnector):
async def _resolve_host_with_throttle(
self,
key: Tuple[str, int],
key: tuple[str, int],
host: str,
port: int,
futures: Set["asyncio.Future[None]"],
traces: Optional[Sequence["Trace"]],
) -> List[ResolveResult]:
futures: set["asyncio.Future[None]"],
traces: Sequence["Trace"] | None,
) -> list[ResolveResult]:
"""Resolve host and set result for all waiters.
This method must be run in a task and shielded from cancellation
@ -1227,7 +1230,7 @@ class TCPConnector(BaseConnector):
return self._cached_hosts.next_addrs(key)
async def _create_connection(
self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout"
self, req: ClientRequest, traces: list["Trace"], timeout: "ClientTimeout"
) -> ResponseHandler:
"""Create connection.
@ -1240,7 +1243,7 @@ class TCPConnector(BaseConnector):
return proto
def _get_ssl_context(self, req: ClientRequest) -> Optional[SSLContext]:
def _get_ssl_context(self, req: ClientRequest) -> SSLContext | None:
"""Logic to get the correct SSL context
0. if req.ssl is false, return None
@ -1285,12 +1288,12 @@ class TCPConnector(BaseConnector):
async def _wrap_create_connection(
self,
*args: Any,
addr_infos: List[AddrInfoType],
addr_infos: list[AddrInfoType],
req: ClientRequest,
timeout: "ClientTimeout",
client_error: Type[Exception] = ClientConnectorError,
client_error: type[Exception] = ClientConnectorError,
**kwargs: Any,
) -> Tuple[asyncio.Transport, ResponseHandler]:
) -> tuple[asyncio.Transport, ResponseHandler]:
try:
async with ceil_timeout(
timeout.sock_connect, ceil_threshold=timeout.ceil_threshold
@ -1325,9 +1328,9 @@ class TCPConnector(BaseConnector):
*args: Any,
req: ClientRequest,
timeout: "ClientTimeout",
client_error: Type[Exception] = ClientConnectorError,
client_error: type[Exception] = ClientConnectorError,
**kwargs: Any,
) -> Tuple[asyncio.Transport, ResponseHandler]:
) -> tuple[asyncio.Transport, ResponseHandler]:
try:
async with ceil_timeout(
timeout.sock_connect, ceil_threshold=timeout.ceil_threshold
@ -1394,6 +1397,12 @@ class TCPConnector(BaseConnector):
if req.request_info.url.scheme != "https":
return
# TLS-in-TLS only applies when the proxy itself is HTTPS.
# When the proxy is HTTP, start_tls upgrades a plain TCP connection,
# which is standard TLS and works on all event loops and Python versions.
if req.proxy is None or req.proxy.scheme != "https":
return
# Check if uvloop is being used, which supports TLS in TLS,
# otherwise assume that asyncio's native transport is being used.
if type(underlying_transport).__module__.startswith("uvloop"):
@ -1433,8 +1442,8 @@ class TCPConnector(BaseConnector):
underlying_transport: asyncio.Transport,
req: ClientRequest,
timeout: "ClientTimeout",
client_error: Type[Exception] = ClientConnectorError,
) -> Tuple[asyncio.BaseTransport, ResponseHandler]:
client_error: type[Exception] = ClientConnectorError,
) -> tuple[asyncio.BaseTransport, ResponseHandler]:
"""Wrap the raw TCP transport with TLS."""
tls_proto = self._factory() # Create a brand new proto for TLS
sslcontext = self._get_ssl_context(req)
@ -1455,7 +1464,7 @@ class TCPConnector(BaseConnector):
tls_proto,
sslcontext,
server_hostname=req.server_hostname or req.host,
ssl_handshake_timeout=timeout.total,
ssl_handshake_timeout=timeout.total or None,
ssl_shutdown_timeout=self._ssl_shutdown_timeout,
)
else:
@ -1464,7 +1473,7 @@ class TCPConnector(BaseConnector):
tls_proto,
sslcontext,
server_hostname=req.server_hostname or req.host,
ssl_handshake_timeout=timeout.total,
ssl_handshake_timeout=timeout.total or None,
)
except BaseException:
# We need to close the underlying transport since
@ -1515,14 +1524,14 @@ class TCPConnector(BaseConnector):
return tls_transport, tls_proto
def _convert_hosts_to_addr_infos(
self, hosts: List[ResolveResult]
) -> List[AddrInfoType]:
self, hosts: list[ResolveResult]
) -> list[AddrInfoType]:
"""Converts the list of hosts to a list of addr_infos.
The list of hosts is the result of a DNS lookup. The list of
addr_infos is the result of a call to `socket.getaddrinfo()`.
"""
addr_infos: List[AddrInfoType] = []
addr_infos: list[AddrInfoType] = []
for hinfo in hosts:
host = hinfo["host"]
is_ipv6 = ":" in host
@ -1538,11 +1547,11 @@ class TCPConnector(BaseConnector):
async def _create_direct_connection(
self,
req: ClientRequest,
traces: List["Trace"],
traces: list["Trace"],
timeout: "ClientTimeout",
*,
client_error: Type[Exception] = ClientConnectorError,
) -> Tuple[asyncio.Transport, ResponseHandler]:
client_error: type[Exception] = ClientConnectorError,
) -> tuple[asyncio.Transport, ResponseHandler]:
sslcontext = self._get_ssl_context(req)
fingerprint = self._get_fingerprint(req)
@ -1567,7 +1576,7 @@ class TCPConnector(BaseConnector):
# it is problem of resolving proxy ip itself
raise ClientConnectorDNSError(req.connection_key, exc) from exc
last_exc: Optional[Exception] = None
last_exc: Exception | None = None
addr_infos = self._convert_hosts_to_addr_infos(hosts)
while addr_infos:
# Strip trailing dots, certificates contain FQDN without dots.
@ -1611,8 +1620,8 @@ class TCPConnector(BaseConnector):
raise last_exc
async def _create_proxy_connection(
self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout"
) -> Tuple[asyncio.BaseTransport, ResponseHandler]:
self, req: ClientRequest, traces: list["Trace"], timeout: "ClientTimeout"
) -> tuple[asyncio.BaseTransport, ResponseHandler]:
self._fail_on_no_start_tls(req)
runtime_has_start_tls = self._loop_supports_start_tls()
proxy_req = self._update_proxy_auth_header_and_build_proxy_req(req)
@ -1733,10 +1742,10 @@ class UnixConnector(BaseConnector):
self,
path: str,
force_close: bool = False,
keepalive_timeout: Union[object, float, None] = sentinel,
keepalive_timeout: object | float | None = sentinel,
limit: int = 100,
limit_per_host: int = 0,
loop: Optional[asyncio.AbstractEventLoop] = None,
loop: asyncio.AbstractEventLoop | None = None,
) -> None:
super().__init__(
force_close=force_close,
@ -1753,7 +1762,7 @@ class UnixConnector(BaseConnector):
return self._path
async def _create_connection(
self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout"
self, req: ClientRequest, traces: list["Trace"], timeout: "ClientTimeout"
) -> ResponseHandler:
try:
async with ceil_timeout(
@ -1791,10 +1800,10 @@ class NamedPipeConnector(BaseConnector):
self,
path: str,
force_close: bool = False,
keepalive_timeout: Union[object, float, None] = sentinel,
keepalive_timeout: object | float | None = sentinel,
limit: int = 100,
limit_per_host: int = 0,
loop: Optional[asyncio.AbstractEventLoop] = None,
loop: asyncio.AbstractEventLoop | None = None,
) -> None:
super().__init__(
force_close=force_close,
@ -1818,7 +1827,7 @@ class NamedPipeConnector(BaseConnector):
return self._path
async def _create_connection(
self, req: ClientRequest, traces: List["Trace"], timeout: "ClientTimeout"
self, req: ClientRequest, traces: list["Trace"], timeout: "ClientTimeout"
) -> ResponseHandler:
try:
async with ceil_timeout(