Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/aiohttp/resolver.py
7763 views
import asyncio1import socket2from typing import Any, Dict, List, Optional, Type, Union34from .abc import AbstractResolver5from .helpers import get_running_loop67__all__ = ("ThreadedResolver", "AsyncResolver", "DefaultResolver")89try:10import aiodns1112# aiodns_default = hasattr(aiodns.DNSResolver, 'gethostbyname')13except ImportError: # pragma: no cover14aiodns = None1516aiodns_default = False171819class ThreadedResolver(AbstractResolver):20"""Threaded resolver.2122Uses an Executor for synchronous getaddrinfo() calls.23concurrent.futures.ThreadPoolExecutor is used by default.24"""2526def __init__(self, loop: Optional[asyncio.AbstractEventLoop] = None) -> None:27self._loop = get_running_loop(loop)2829async def resolve(30self, hostname: str, port: int = 0, family: int = socket.AF_INET31) -> List[Dict[str, Any]]:32infos = await self._loop.getaddrinfo(33hostname,34port,35type=socket.SOCK_STREAM,36family=family,37flags=socket.AI_ADDRCONFIG,38)3940hosts = []41for family, _, proto, _, address in infos:42if family == socket.AF_INET6:43if len(address) < 3:44# IPv6 is not supported by Python build,45# or IPv6 is not enabled in the host46continue47if address[3]: # type: ignore[misc]48# This is essential for link-local IPv6 addresses.49# LL IPv6 is a VERY rare case. Strictly speaking, we should use50# getnameinfo() unconditionally, but performance makes sense.51host, _port = socket.getnameinfo(52address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV53)54port = int(_port)55else:56host, port = address[:2]57else: # IPv458assert family == socket.AF_INET59host, port = address # type: ignore[misc]60hosts.append(61{62"hostname": hostname,63"host": host,64"port": port,65"family": family,66"proto": proto,67"flags": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,68}69)7071return hosts7273async def close(self) -> None:74pass757677class AsyncResolver(AbstractResolver):78"""Use the `aiodns` package to make asynchronous DNS lookups"""7980def __init__(81self,82loop: Optional[asyncio.AbstractEventLoop] = None,83*args: Any,84**kwargs: Any85) -> None:86if aiodns is None:87raise RuntimeError("Resolver requires aiodns library")8889self._loop = get_running_loop(loop)90self._resolver = aiodns.DNSResolver(*args, loop=loop, **kwargs)9192if not hasattr(self._resolver, "gethostbyname"):93# aiodns 1.1 is not available, fallback to DNSResolver.query94self.resolve = self._resolve_with_query # type: ignore9596async def resolve(97self, host: str, port: int = 0, family: int = socket.AF_INET98) -> List[Dict[str, Any]]:99try:100resp = await self._resolver.gethostbyname(host, family)101except aiodns.error.DNSError as exc:102msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed"103raise OSError(msg) from exc104hosts = []105for address in resp.addresses:106hosts.append(107{108"hostname": host,109"host": address,110"port": port,111"family": family,112"proto": 0,113"flags": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,114}115)116117if not hosts:118raise OSError("DNS lookup failed")119120return hosts121122async def _resolve_with_query(123self, host: str, port: int = 0, family: int = socket.AF_INET124) -> List[Dict[str, Any]]:125if family == socket.AF_INET6:126qtype = "AAAA"127else:128qtype = "A"129130try:131resp = await self._resolver.query(host, qtype)132except aiodns.error.DNSError as exc:133msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed"134raise OSError(msg) from exc135136hosts = []137for rr in resp:138hosts.append(139{140"hostname": host,141"host": rr.host,142"port": port,143"family": family,144"proto": 0,145"flags": socket.AI_NUMERICHOST,146}147)148149if not hosts:150raise OSError("DNS lookup failed")151152return hosts153154async def close(self) -> None:155self._resolver.cancel()156157158_DefaultType = Type[Union[AsyncResolver, ThreadedResolver]]159DefaultResolver: _DefaultType = AsyncResolver if aiodns_default else ThreadedResolver160161162