Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
84e0290
Test typing round 2
Dreamsorcerer Aug 6, 2024
0bd5e60
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 6, 2024
f8e6b82
Update lint.in
Dreamsorcerer Aug 6, 2024
e19fabf
Update lint.txt
Dreamsorcerer Aug 6, 2024
4aa630f
Update ci-cd.yml
Dreamsorcerer Aug 6, 2024
f4c97a7
Update test_cookiejar.py
Dreamsorcerer Aug 6, 2024
a523d50
Update test_client_session.py
Dreamsorcerer Aug 6, 2024
4c10987
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 6, 2024
963a233
Update test_cookiejar.py
Dreamsorcerer Aug 6, 2024
3e283b4
Update test_client_response.py
Dreamsorcerer Aug 6, 2024
537aea9
Update test_client_functional.py
Dreamsorcerer Aug 6, 2024
5d894c3
Update test_client_request.py
Dreamsorcerer Aug 6, 2024
b1a94f4
Fix
Dreamsorcerer Aug 7, 2024
3fd242a
Update client.py
Dreamsorcerer Aug 7, 2024
3ea994d
Update cookiejar.py
Dreamsorcerer Aug 7, 2024
e5dd252
Update test_client_request.py
Dreamsorcerer Aug 7, 2024
53f0ad1
Update test_client_session.py
Dreamsorcerer Aug 7, 2024
866ad69
Update test_client_ws.py
Dreamsorcerer Aug 7, 2024
26b1e60
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 7, 2024
f0099f0
Update test_connector.py
Dreamsorcerer Aug 7, 2024
735e25f
Update test_cookiejar.py
Dreamsorcerer Aug 7, 2024
5cb084e
Replace sentinel with empty str
Dreamsorcerer Aug 7, 2024
19347af
Merge branch 'test-typing2' of github.com:aio-libs/aiohttp into test-…
Dreamsorcerer Aug 7, 2024
5801545
Update .coveragerc
Dreamsorcerer Aug 7, 2024
94c6a71
Coverage improvements
Dreamsorcerer Aug 7, 2024
ca6e838
Update .coveragerc
Dreamsorcerer Aug 7, 2024
bb1d5b8
Coverage
Dreamsorcerer Aug 7, 2024
3e4a2ca
Coverage
Dreamsorcerer Aug 7, 2024
cb476ec
Update test_client_session.py
Dreamsorcerer Aug 7, 2024
7d95da1
Update test_client_ws_functional.py
Dreamsorcerer Aug 7, 2024
4e30fbc
Coverage
Dreamsorcerer Aug 7, 2024
0ed2b77
Update test_client_functional.py
Dreamsorcerer Aug 7, 2024
26a6318
Update test_client_response.py
Dreamsorcerer Aug 7, 2024
668dd75
Update test_client_functional.py
Dreamsorcerer Aug 7, 2024
5082ceb
Update test_client_request.py
Dreamsorcerer Aug 7, 2024
fd9ba47
Merge branch 'master' into test-typing2
Dreamsorcerer Aug 7, 2024
cdf3161
Merge branch 'master' into test-typing2
Dreamsorcerer Aug 7, 2024
86d68fb
Update test_client_request.py
Dreamsorcerer Aug 7, 2024
4ce72fa
Update test_connector.py
Dreamsorcerer Aug 7, 2024
612be40
Update test_connector.py
Dreamsorcerer Aug 7, 2024
b5bda48
Update test_connector.py
Dreamsorcerer Aug 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ omit = site-packages
[report]
exclude_also =
if TYPE_CHECKING
assert False
: \.\.\.(\s*#.*)?$
^ +\.\.\.$
2 changes: 1 addition & 1 deletion .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.9
python-version: 3.11
- name: Cache PyPI
uses: actions/[email protected]
with:
Expand Down
29 changes: 20 additions & 9 deletions aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import traceback
import warnings
from contextlib import suppress
from types import SimpleNamespace, TracebackType
from types import TracebackType
from typing import (
TYPE_CHECKING,
Any,
Expand Down Expand Up @@ -156,7 +156,7 @@


class _RequestOptions(TypedDict, total=False):
params: Union[Mapping[str, str], None]
params: Union[Mapping[str, Union[str, int]], str, None]
data: Any
json: Any
cookies: Union[LooseCookies, None]
Expand All @@ -176,7 +176,7 @@ class _RequestOptions(TypedDict, total=False):
ssl: Union[SSLContext, bool, Fingerprint]
server_hostname: Union[str, None]
proxy_headers: Union[LooseHeaders, None]
trace_request_ctx: Union[SimpleNamespace, None]
trace_request_ctx: Union[Mapping[str, str], None]
read_bufsize: Union[int, None]
auto_decompress: Union[bool, None]
max_line_size: Union[int, None]
Expand Down Expand Up @@ -374,11 +374,22 @@ def __del__(self, _warnings: Any = warnings) -> None:
context["source_traceback"] = self._source_traceback
self._loop.call_exception_handler(context)

def request(
self, method: str, url: StrOrURL, **kwargs: Any
) -> "_RequestContextManager":
"""Perform HTTP request."""
return _RequestContextManager(self._request(method, url, **kwargs))
if sys.version_info >= (3, 11) and TYPE_CHECKING:

def request(
self,
method: str,
url: StrOrURL,
**kwargs: Unpack[_RequestOptions],
) -> "_RequestContextManager": ...

Check notice

Code scanning / CodeQL

Statement has no effect

This statement has no effect.

else:

def request(
self, method: str, url: StrOrURL, **kwargs: Any
) -> "_RequestContextManager":
"""Perform HTTP request."""
return _RequestContextManager(self._request(method, url, **kwargs))

def _build_url(self, str_or_url: StrOrURL) -> URL:
url = URL(str_or_url)
Expand Down Expand Up @@ -415,7 +426,7 @@ async def _request(
ssl: Union[SSLContext, bool, Fingerprint] = True,
server_hostname: Optional[str] = None,
proxy_headers: Optional[LooseHeaders] = None,
trace_request_ctx: Optional[SimpleNamespace] = None,
trace_request_ctx: Optional[Mapping[str, str]] = None,
read_bufsize: Optional[int] = None,
auto_decompress: Optional[bool] = None,
max_line_size: Optional[int] = None,
Expand Down
2 changes: 1 addition & 1 deletion aiohttp/client_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def __str__(self) -> str:
return "{}, message={!r}, url={!r}".format(
self.status,
self.message,
self.request_info.real_url,
str(self.request_info.real_url),
)

def __repr__(self) -> str:
Expand Down
13 changes: 9 additions & 4 deletions aiohttp/client_reqrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ class ClientRequest:
hdrs.ACCEPT_ENCODING: _gen_default_accept_encoding(),
}

body = b""
# Type of body depends on PAYLOAD_REGISTRY, which is dynamic.
body: Any = b""
auth = None
response = None

Expand Down Expand Up @@ -371,7 +372,7 @@ def update_headers(self, headers: Optional[LooseHeaders]) -> None:

if headers:
if isinstance(headers, (dict, MultiDictProxy, MultiDict)):
headers = headers.items() # type: ignore[assignment]
headers = headers.items()

for key, value in headers: # type: ignore[misc]
# A special case for Host header
Expand Down Expand Up @@ -532,6 +533,10 @@ def update_proxy(
raise ValueError("proxy_auth must be None or BasicAuth() tuple")
self.proxy = proxy
self.proxy_auth = proxy_auth
if proxy_headers is not None and not isinstance(
proxy_headers, (MultiDict, MultiDictProxy)
):
proxy_headers = CIMultiDict(proxy_headers)
self.proxy_headers = proxy_headers

def keep_alive(self) -> bool:
Expand Down Expand Up @@ -567,10 +572,10 @@ async def write_bytes(
await self.body.write(writer)
else:
if isinstance(self.body, (bytes, bytearray)):
self.body = (self.body,) # type: ignore[assignment]
self.body = (self.body,)

for chunk in self.body:
await writer.write(chunk) # type: ignore[arg-type]
await writer.write(chunk)
except OSError as underlying_exc:
reraised_exc = underlying_exc

Expand Down
5 changes: 3 additions & 2 deletions aiohttp/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
List,
Literal,
Optional,
Sequence,
Set,
Tuple,
Type,
Expand Down Expand Up @@ -812,7 +813,7 @@ def clear_dns_cache(
self._cached_hosts.clear()

async def _resolve_host(
self, host: str, port: int, traces: Optional[List["Trace"]] = None
self, host: str, port: int, traces: Optional[Sequence["Trace"]] = None
) -> List[ResolveResult]:
"""Resolve host and return list of addresses."""
if is_ip_address(host):
Expand Down Expand Up @@ -880,7 +881,7 @@ async def _resolve_host_with_throttle(
key: Tuple[str, int],
host: str,
port: int,
traces: Optional[List["Trace"]],
traces: Optional[Sequence["Trace"]],
) -> List[ResolveResult]:
"""Resolve host with a dns events throttle."""
if key in self._throttle_dns_events:
Expand Down
25 changes: 14 additions & 11 deletions aiohttp/cookiejar.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
from typing import (
DefaultDict,
Dict,
FrozenSet,
Iterable,
Iterator,
List,
Mapping,
Optional,
Set,
Expand Down Expand Up @@ -83,7 +83,7 @@ def __init__(
*,
unsafe: bool = False,
quote_cookie: bool = True,
treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None,
treat_as_secure_origin: Union[StrOrURL, Iterable[StrOrURL], None] = None,
) -> None:
self._cookies: DefaultDict[Tuple[str, str], SimpleCookie] = defaultdict(
SimpleCookie
Expand All @@ -92,17 +92,20 @@ def __init__(
self._unsafe = unsafe
self._quote_cookie = quote_cookie
if treat_as_secure_origin is None:
treat_as_secure_origin = []
self._treat_as_secure_origin: FrozenSet[URL] = frozenset()
elif isinstance(treat_as_secure_origin, URL):
treat_as_secure_origin = [treat_as_secure_origin.origin()]
self._treat_as_secure_origin = frozenset({treat_as_secure_origin.origin()})
elif isinstance(treat_as_secure_origin, str):
treat_as_secure_origin = [URL(treat_as_secure_origin).origin()]
self._treat_as_secure_origin = frozenset(
{URL(treat_as_secure_origin).origin()}
)
else:
treat_as_secure_origin = [
URL(url).origin() if isinstance(url, str) else url.origin()
for url in treat_as_secure_origin
]
self._treat_as_secure_origin = treat_as_secure_origin
self._treat_as_secure_origin = frozenset(
{
URL(url).origin() if isinstance(url, str) else url.origin()
for url in treat_as_secure_origin
}
)
self._next_expiration: float = ceil(time.time())
self._expirations: Dict[Tuple[str, str, str], float] = {}

Expand Down Expand Up @@ -243,7 +246,7 @@ def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> No

self._do_expiration()

def filter_cookies(self, request_url: URL = URL()) -> "BaseCookie[str]":
def filter_cookies(self, request_url: URL) -> "BaseCookie[str]":
"""Returns this jar's cookies filtered by their attributes."""
if not isinstance(request_url, URL):
warnings.warn(
Expand Down
34 changes: 30 additions & 4 deletions aiohttp/pytest_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@
import contextlib
import inspect
import warnings
from typing import Any, Awaitable, Callable, Dict, Iterator, Optional, Type, Union
from typing import (
Any,
Awaitable,
Callable,
Dict,
Iterator,
Optional,
Protocol,
Type,
Union,
)

import pytest

Expand All @@ -24,9 +34,23 @@
except ImportError: # pragma: no cover
uvloop = None # type: ignore[assignment]

AiohttpClient = Callable[[Union[Application, BaseTestServer]], Awaitable[TestClient]]
AiohttpRawServer = Callable[[Application], Awaitable[RawTestServer]]
AiohttpServer = Callable[[Application], Awaitable[TestServer]]


class AiohttpClient(Protocol):
def __call__(
self,
__param: Union[Application, BaseTestServer],
*,
server_kwargs: Optional[Dict[str, Any]] = None,
**kwargs: Any
) -> Awaitable[TestClient]: ...

Check notice

Code scanning / CodeQL

Statement has no effect

This statement has no effect.


class AiohttpServer(Protocol):
def __call__(
self, app: Application, *, port: Optional[int] = None, **kwargs: Any
) -> Awaitable[TestServer]: ...

Check notice

Code scanning / CodeQL

Statement has no effect

This statement has no effect.


def pytest_addoption(parser): # type: ignore[no-untyped-def]
Expand Down Expand Up @@ -258,7 +282,9 @@ def aiohttp_server(loop: asyncio.AbstractEventLoop) -> Iterator[AiohttpServer]:
"""
servers = []

async def go(app, *, port=None, **kwargs): # type: ignore[no-untyped-def]
async def go(
app: Application, *, port: Optional[int] = None, **kwargs: Any
) -> TestServer:
server = TestServer(app, port=port)
await server.start_server(**kwargs)
servers.append(server)
Expand Down
Loading