diff --git a/aiohttp/abc.py b/aiohttp/abc.py index a21e6b5d0bd..bd448ed8abd 100644 --- a/aiohttp/abc.py +++ b/aiohttp/abc.py @@ -147,16 +147,10 @@ async def close(self) -> None: """Release resolver""" -if TYPE_CHECKING: - IterableBase = Iterable[Morsel[str]] -else: - IterableBase = Iterable - - -ClearCookiePredicate = Callable[["Morsel[str]"], bool] +ClearCookiePredicate = Callable[[Morsel[str]], bool] -class AbstractCookieJar(Sized, IterableBase): +class AbstractCookieJar(Sized, Iterable[Morsel[str]]): """Abstract Cookie Jar.""" @property diff --git a/aiohttp/client.py b/aiohttp/client.py index dcbdd23dfd4..059f1adc401 100644 --- a/aiohttp/client.py +++ b/aiohttp/client.py @@ -24,7 +24,7 @@ from typing import TYPE_CHECKING, Any, Final, Generic, TypedDict, TypeVar, final from multidict import CIMultiDict, MultiDict, MultiDictProxy, istr -from yarl import URL +from yarl import URL, Query from . import hdrs, http, payload from ._websocket.reader import WebSocketDataQueue @@ -96,7 +96,7 @@ from .http import WS_KEY, HttpVersion, WebSocketReader, WebSocketWriter from .http_websocket import WSHandshakeError, ws_ext_gen, ws_ext_parse from .tracing import Trace, TraceConfig -from .typedefs import JSONEncoder, LooseCookies, LooseHeaders, Query, StrOrURL +from .typedefs import JSONEncoder, LooseCookies, LooseHeaders, StrOrURL __all__ = ( # client_exceptions diff --git a/aiohttp/client_exceptions.py b/aiohttp/client_exceptions.py index 7bff03171b2..af83a42705e 100644 --- a/aiohttp/client_exceptions.py +++ b/aiohttp/client_exceptions.py @@ -7,17 +7,12 @@ from .typedefs import StrOrURL -if TYPE_CHECKING: +try: import ssl SSLContext = ssl.SSLContext -else: - try: - import ssl - - SSLContext = ssl.SSLContext - except ImportError: # pragma: no cover - ssl = SSLContext = None # type: ignore[assignment] +except ImportError: # pragma: no cover + ssl = SSLContext = None # type: ignore[assignment] if TYPE_CHECKING: from .client_reqrep import ClientResponse, ConnectionKey, Fingerprint, RequestInfo diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py index 0d6f435b6e5..551b3374c6a 100644 --- a/aiohttp/client_reqrep.py +++ b/aiohttp/client_reqrep.py @@ -14,7 +14,7 @@ from typing import TYPE_CHECKING, Any, NamedTuple, TypedDict from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy -from yarl import URL +from yarl import URL, Query from . import hdrs, multipart, payload from ._cookie_helpers import ( @@ -57,18 +57,14 @@ StreamWriter, ) from .streams import StreamReader -from .typedefs import DEFAULT_JSON_DECODER, JSONDecoder, Query, RawHeaders +from .typedefs import DEFAULT_JSON_DECODER, JSONDecoder, RawHeaders -if TYPE_CHECKING: +try: import ssl from ssl import SSLContext -else: - try: - import ssl - from ssl import SSLContext - except ImportError: # pragma: no cover - ssl = None # type: ignore[assignment] - SSLContext = object # type: ignore[misc,assignment] +except ImportError: # pragma: no cover + ssl = None # type: ignore[assignment] + SSLContext = object # type: ignore[misc,assignment] __all__ = ("ClientRequest", "ClientResponse", "RequestInfo", "Fingerprint") diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 0b6081f8e08..b1820358bae 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -56,18 +56,13 @@ else: Buffer = "bytes | bytearray | memoryview[int] | memoryview[bytes]" -if TYPE_CHECKING: +try: import ssl SSLContext = ssl.SSLContext -else: - try: - import ssl - - SSLContext = ssl.SSLContext - except ImportError: # pragma: no cover - ssl = None # type: ignore[assignment] - SSLContext = object # type: ignore[misc,assignment] +except ImportError: # pragma: no cover + ssl = None # type: ignore[assignment] + SSLContext = object # type: ignore[misc,assignment] EMPTY_SCHEMA_SET = frozenset({""}) HTTP_SCHEMA_SET = frozenset({"http", "https"}) diff --git a/aiohttp/http_exceptions.py b/aiohttp/http_exceptions.py index 200cfeb3c68..544e1d03a25 100644 --- a/aiohttp/http_exceptions.py +++ b/aiohttp/http_exceptions.py @@ -2,7 +2,7 @@ from textwrap import indent -from .typedefs import _CIMultiDict +from multidict import CIMultiDict __all__ = ("HttpProcessingError",) @@ -26,7 +26,7 @@ def __init__( *, code: int | None = None, message: str = "", - headers: _CIMultiDict | None = None, + headers: CIMultiDict[str] | None = None, ) -> None: if code is not None: self.code = code @@ -45,7 +45,9 @@ class BadHttpMessage(HttpProcessingError): code = 400 message = "Bad Request" - def __init__(self, message: str, *, headers: _CIMultiDict | None = None) -> None: + def __init__( + self, message: str, *, headers: CIMultiDict[str] | None = None + ) -> None: super().__init__(message=message, headers=headers) self.args = (message,) diff --git a/aiohttp/payload.py b/aiohttp/payload.py index 2bce326ccb4..d5996a0e915 100644 --- a/aiohttp/payload.py +++ b/aiohttp/payload.py @@ -7,9 +7,9 @@ import sys import warnings from abc import ABC, abstractmethod -from collections.abc import Iterable +from collections.abc import AsyncIterable, AsyncIterator, Iterable from itertools import chain -from typing import IO, TYPE_CHECKING, Any, Final, TextIO +from typing import IO, Any, Final, TextIO from multidict import CIMultiDict @@ -23,7 +23,7 @@ sentinel, ) from .streams import StreamReader -from .typedefs import JSONEncoder, _CIMultiDict +from .typedefs import JSONEncoder __all__ = ( "PAYLOAD_REGISTRY", @@ -145,7 +145,7 @@ def __init__( self, value: Any, headers: ( - _CIMultiDict | dict[str, str] | Iterable[tuple[str, str]] | None + CIMultiDict[str] | dict[str, str] | Iterable[tuple[str, str]] | None ) = None, content_type: None | str | _SENTINEL = sentinel, filename: str | None = None, @@ -154,7 +154,7 @@ def __init__( ) -> None: self._encoding = encoding self._filename = filename - self._headers: _CIMultiDict = CIMultiDict() + self._headers = CIMultiDict[str]() self._value = value if content_type is not sentinel and content_type is not None: assert isinstance(content_type, str) @@ -189,7 +189,7 @@ def filename(self) -> str | None: return self._filename @property - def headers(self) -> _CIMultiDict: + def headers(self) -> CIMultiDict[str]: """Custom item headers""" return self._headers @@ -939,26 +939,14 @@ def __init__( ) -if TYPE_CHECKING: - from collections.abc import AsyncIterable, AsyncIterator - - _AsyncIterator = AsyncIterator[bytes] - _AsyncIterable = AsyncIterable[bytes] -else: - from collections.abc import AsyncIterable, AsyncIterator - - _AsyncIterator = AsyncIterator - _AsyncIterable = AsyncIterable - - class AsyncIterablePayload(Payload): - _iter: _AsyncIterator | None = None - _value: _AsyncIterable + _iter: AsyncIterator[bytes] | None = None + _value: AsyncIterable[bytes] _cached_chunks: list[bytes] | None = None # _consumed stays False to allow reuse with cached content _autoclose = True # Iterator doesn't need explicit closing - def __init__(self, value: _AsyncIterable, *args: Any, **kwargs: Any) -> None: + def __init__(self, value: AsyncIterable[bytes], *args: Any, **kwargs: Any) -> None: if not isinstance(value, AsyncIterable): raise TypeError( "value argument must support " diff --git a/aiohttp/typedefs.py b/aiohttp/typedefs.py index dd7ad257460..cd016a4e3c4 100644 --- a/aiohttp/typedefs.py +++ b/aiohttp/typedefs.py @@ -1,52 +1,34 @@ import json import os from collections.abc import Awaitable, Callable, Iterable, Mapping -from typing import TYPE_CHECKING, Any, Protocol, Union +from http.cookies import BaseCookie, Morsel +from typing import TYPE_CHECKING, Any, Protocol -from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy, istr -from yarl import URL, Query as _Query - -Query = _Query +from multidict import CIMultiDict, CIMultiDictProxy, istr +from yarl import URL DEFAULT_JSON_ENCODER = json.dumps DEFAULT_JSON_DECODER = json.loads if TYPE_CHECKING: - _CIMultiDict = CIMultiDict[str] - _CIMultiDictProxy = CIMultiDictProxy[str] - _MultiDict = MultiDict[str] - _MultiDictProxy = MultiDictProxy[str] - from http.cookies import BaseCookie, Morsel - from .web import Request, StreamResponse -else: - _CIMultiDict = CIMultiDict - _CIMultiDictProxy = CIMultiDictProxy - _MultiDict = MultiDict - _MultiDictProxy = MultiDictProxy -Byteish = Union[bytes, bytearray, memoryview] +Byteish = bytes | bytearray | memoryview JSONEncoder = Callable[[Any], str] JSONDecoder = Callable[[str], Any] -LooseHeaders = Union[ - Mapping[str, str], - Mapping[istr, str], - _CIMultiDict, - _CIMultiDictProxy, - Iterable[tuple[str | istr, str]], -] +LooseHeaders = ( + Mapping[str, str] + | Mapping[istr, str] + | CIMultiDict[str] + | CIMultiDictProxy[str] + | Iterable[tuple[str | istr, str]] +) RawHeaders = tuple[tuple[bytes, bytes], ...] -StrOrURL = Union[str, URL] - -LooseCookiesMappings = Mapping[str, Union[str, "BaseCookie[str]", "Morsel[Any]"]] -LooseCookiesIterables = Iterable[ - tuple[str, Union[str, "BaseCookie[str]", "Morsel[Any]"]] -] -LooseCookies = Union[ - LooseCookiesMappings, - LooseCookiesIterables, - "BaseCookie[str]", -] +StrOrURL = str | URL + +LooseCookiesMappings = Mapping[str, str | BaseCookie[str] | Morsel[Any]] +LooseCookiesIterables = Iterable[tuple[str, str | BaseCookie[str] | Morsel[Any]]] +LooseCookies = LooseCookiesMappings | LooseCookiesIterables | BaseCookie[str] Handler = Callable[["Request"], Awaitable["StreamResponse"]] @@ -57,4 +39,4 @@ def __call__( ) -> Awaitable["StreamResponse"]: ... -PathLike = Union[str, "os.PathLike[str]"] +PathLike = str | os.PathLike[str] diff --git a/aiohttp/web.py b/aiohttp/web.py index be0797031a1..1322360cbed 100644 --- a/aiohttp/web.py +++ b/aiohttp/web.py @@ -8,7 +8,7 @@ from collections.abc import Awaitable, Callable, Iterable, Iterable as TypingIterable from contextlib import suppress from importlib import import_module -from typing import TYPE_CHECKING, Any, cast +from typing import Any, cast from .abc import AbstractAccessLogger from .helpers import AppKey @@ -256,13 +256,10 @@ ) -if TYPE_CHECKING: +try: from ssl import SSLContext -else: - try: - from ssl import SSLContext - except ImportError: # pragma: no cover - SSLContext = object # type: ignore[misc,assignment] +except ImportError: # pragma: no cover + SSLContext = object # type: ignore[misc,assignment] # Only display warning when using -Wdefault, -We, -X dev or similar. warnings.filterwarnings("ignore", category=NotAppKeyWarning, append=True) diff --git a/aiohttp/web_app.py b/aiohttp/web_app.py index bef158219e4..ddd30efb72f 100644 --- a/aiohttp/web_app.py +++ b/aiohttp/web_app.py @@ -12,7 +12,7 @@ Sequence, ) from functools import lru_cache, partial, update_wrapper -from typing import TYPE_CHECKING, Any, TypeVar, cast, final, overload +from typing import Any, TypeVar, cast, final, overload from aiosignal import Signal from frozenlist import FrozenList @@ -39,21 +39,11 @@ __all__ = ("Application", "CleanupError") - -if TYPE_CHECKING: - _AppSignal = Signal["Application"] - _RespPrepareSignal = Signal[Request, StreamResponse] - _Middlewares = FrozenList[Middleware] - _MiddlewaresHandlers = Sequence[Middleware] - _Subapps = list["Application"] -else: - # No type checker mode, skip types - _AppSignal = Signal - _RespPrepareSignal = Signal - _Handler = Callable - _Middlewares = FrozenList - _MiddlewaresHandlers = Sequence - _Subapps = list +_AppSignal = Signal["Application"] +_RespPrepareSignal = Signal[Request, StreamResponse] +_Middlewares = FrozenList[Middleware] +_MiddlewaresHandlers = Sequence[Middleware] +_Subapps = list["Application"] _T = TypeVar("_T") _U = TypeVar("_U") @@ -415,10 +405,7 @@ def exceptions(self) -> list[BaseException]: return cast(list[BaseException], self.args[1]) -if TYPE_CHECKING: - _CleanupContextBase = FrozenList[Callable[[Application], AsyncIterator[None]]] -else: - _CleanupContextBase = FrozenList +_CleanupContextBase = FrozenList[Callable[[Application], AsyncIterator[None]]] class CleanupContext(_CleanupContextBase): diff --git a/aiohttp/web_response.py b/aiohttp/web_response.py index 2f921d4f559..2d09f82c225 100644 --- a/aiohttp/web_response.py +++ b/aiohttp/web_response.py @@ -1,5 +1,4 @@ import asyncio -import collections.abc import datetime import enum import json @@ -43,10 +42,6 @@ if TYPE_CHECKING: from .web_request import BaseRequest - BaseClass = MutableMapping[str, Any] -else: - BaseClass = collections.abc.MutableMapping - # TODO(py311): Convert to StrEnum for wider use class ContentCoding(enum.Enum): @@ -66,7 +61,7 @@ class ContentCoding(enum.Enum): ############################################################ -class StreamResponse(BaseClass, HeadersMixin, CookieMixin): +class StreamResponse(MutableMapping[str, Any], HeadersMixin, CookieMixin): _body: None | bytes | bytearray | Payload _length_check = True diff --git a/aiohttp/web_runner.py b/aiohttp/web_runner.py index b06c9ebce94..0b04c317f93 100644 --- a/aiohttp/web_runner.py +++ b/aiohttp/web_runner.py @@ -2,7 +2,7 @@ import signal import socket from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Any, Generic, TypeVar +from typing import Any, Generic, TypeVar from yarl import URL @@ -16,13 +16,10 @@ from .web_request import BaseRequest, Request from .web_server import Server -if TYPE_CHECKING: +try: from ssl import SSLContext -else: - try: - from ssl import SSLContext - except ImportError: # pragma: no cover - SSLContext = object # type: ignore[misc,assignment] +except ImportError: # pragma: no cover + SSLContext = object # type: ignore[misc,assignment] __all__ = ( "BaseSite", diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py index 2642ed6542e..e4b3f2f34fe 100644 --- a/aiohttp/web_urldispatcher.py +++ b/aiohttp/web_urldispatcher.py @@ -60,10 +60,6 @@ if TYPE_CHECKING: from .web_app import Application - BaseDict = dict[str, str] -else: - BaseDict = dict - CIRCULAR_SYMLINK_ERROR = (RuntimeError,) if sys.version_info < (3, 13) else () HTTP_METHOD_RE: Final[Pattern[str]] = re.compile( @@ -212,7 +208,7 @@ async def handle_expect_header(self, request: Request) -> StreamResponse | None: return await self._expect_handler(request) -class UrlMappingMatchInfo(BaseDict, AbstractMatchInfo): +class UrlMappingMatchInfo(dict[str, str], AbstractMatchInfo): __slots__ = ("_route", "_apps", "_current_app", "_frozen") diff --git a/aiohttp/worker.py b/aiohttp/worker.py index da44d7253fc..375ac32e77f 100644 --- a/aiohttp/worker.py +++ b/aiohttp/worker.py @@ -7,7 +7,7 @@ import signal import sys from types import FrameType -from typing import TYPE_CHECKING, Any, Optional +from typing import Any, Optional from gunicorn.config import AccessLogFormat as GunicornAccessLogFormat from gunicorn.workers import base @@ -18,18 +18,13 @@ from .web_app import Application from .web_log import AccessLogger -if TYPE_CHECKING: +try: import ssl SSLContext = ssl.SSLContext -else: - try: - import ssl - - SSLContext = ssl.SSLContext - except ImportError: # pragma: no cover - ssl = None # type: ignore[assignment] - SSLContext = object # type: ignore[misc,assignment] +except ImportError: # pragma: no cover + ssl = None # type: ignore[assignment] + SSLContext = object # type: ignore[misc,assignment] __all__ = ("GunicornWebWorker", "GunicornUVLoopWebWorker") diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index e4242c6d117..473427278f8 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -22,7 +22,7 @@ import trustme from multidict import MultiDict from pytest_mock import MockerFixture -from yarl import URL +from yarl import URL, Query import aiohttp from aiohttp import Fingerprint, ServerFingerprintMismatch, hdrs, payload, web @@ -48,7 +48,7 @@ ) from aiohttp.pytest_plugin import AiohttpClient, AiohttpServer from aiohttp.test_utils import TestClient, TestServer, unused_port -from aiohttp.typedefs import Handler, Query +from aiohttp.typedefs import Handler @pytest.fixture(autouse=True)