Skip to content

Commit 8887bfa

Browse files
Sync from aiohttp (#56)
1 parent 98444cb commit 8887bfa

File tree

6 files changed

+122
-124
lines changed

6 files changed

+122
-124
lines changed

.mypy.ini

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[mypy]
2+
files = pytest_aiohttp, tests
3+
check_untyped_defs = True
4+
follow_imports_for_stubs = True
5+
disallow_any_decorated = True
6+
disallow_any_generics = True
7+
disallow_any_unimported = True
8+
disallow_incomplete_defs = True
9+
disallow_subclassing_any = True
10+
disallow_untyped_calls = True
11+
disallow_untyped_decorators = True
12+
disallow_untyped_defs = True
13+
# TODO(PY312): explicit-override
14+
enable_error_code = ignore-without-code, possibly-undefined, redundant-expr, redundant-self, truthy-bool, truthy-iterable, unused-awaitable
15+
extra_checks = True
16+
implicit_reexport = False
17+
no_implicit_optional = True
18+
pretty = True
19+
show_column_numbers = True
20+
show_error_codes = True
21+
show_error_code_links = True
22+
strict_equality = True
23+
warn_incomplete_stub = True
24+
warn_redundant_casts = True
25+
warn_return_any = True
26+
warn_unreachable = True
27+
warn_unused_ignores = True

pytest_aiohttp/plugin.py

Lines changed: 78 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,59 @@
1-
import asyncio
2-
import warnings
3-
from typing import Any, Awaitable, Callable, Dict, Generator, Optional, Type, Union
1+
from typing import (
2+
Any,
3+
Awaitable,
4+
Dict,
5+
Iterator,
6+
Optional,
7+
Protocol,
8+
Type,
9+
TypeVar,
10+
Union,
11+
overload,
12+
)
413

514
import pytest
615
import pytest_asyncio
716
from aiohttp.test_utils import BaseTestServer, RawTestServer, TestClient, TestServer
8-
from aiohttp.web import Application, BaseRequest, StreamResponse
17+
from aiohttp.web import Application, BaseRequest, Request
18+
from aiohttp.web_protocol import _RequestHandler
19+
20+
_Request = TypeVar("_Request", bound=BaseRequest)
21+
922

10-
AiohttpClient = Callable[[Union[Application, BaseTestServer]], Awaitable[TestClient]]
23+
class AiohttpClient(Protocol):
24+
@overload
25+
async def __call__(
26+
self,
27+
__param: Application,
28+
*,
29+
server_kwargs: Optional[Dict[str, Any]] = None,
30+
**kwargs: Any,
31+
) -> TestClient[Request, Application]: ...
32+
33+
@overload
34+
async def __call__(
35+
self,
36+
__param: BaseTestServer, # TODO(aiohttp4): BaseTestServer[_Request]
37+
*,
38+
server_kwargs: Optional[Dict[str, Any]] = None,
39+
**kwargs: Any,
40+
) -> TestClient[_Request, None]: ...
41+
42+
43+
class AiohttpServer(Protocol):
44+
def __call__(
45+
self, app: Application, *, port: Optional[int] = None, **kwargs: Any
46+
) -> Awaitable[TestServer]: ...
47+
48+
49+
class AiohttpRawServer(Protocol):
50+
def __call__(
51+
self,
52+
handler: _RequestHandler, # TODO(aiohttp4): _RequestHandler[BaseRequest]
53+
*,
54+
port: Optional[int] = None,
55+
**kwargs: Any,
56+
) -> Awaitable[RawTestServer]: ...
1157

1258

1359
LEGACY_MODE = DeprecationWarning(
@@ -28,41 +74,8 @@ def pytest_configure(config) -> None:
2874
config.issue_config_time_warning(LEGACY_MODE, stacklevel=2)
2975

3076

31-
@pytest.fixture
32-
def loop(event_loop: asyncio.AbstractEventLoop) -> asyncio.AbstractEventLoop:
33-
warnings.warn(
34-
"'loop' fixture is deprecated and scheduled for removal, "
35-
"please use 'event_loop' instead",
36-
DeprecationWarning,
37-
)
38-
return event_loop
39-
40-
41-
@pytest.fixture
42-
def proactor_loop(event_loop: asyncio.AbstractEventLoop) -> asyncio.AbstractEventLoop:
43-
warnings.warn(
44-
"'proactor_loop' fixture is deprecated and scheduled for removal, "
45-
"please use 'event_loop' instead",
46-
DeprecationWarning,
47-
)
48-
return event_loop
49-
50-
51-
@pytest.fixture
52-
def aiohttp_unused_port(
53-
unused_tcp_port_factory: Callable[[], int]
54-
) -> Callable[[], int]:
55-
warnings.warn(
56-
"'aiohttp_unused_port' fixture is deprecated "
57-
"and scheduled for removal, "
58-
"please use 'unused_tcp_port_factory' instead",
59-
DeprecationWarning,
60-
)
61-
return unused_tcp_port_factory
62-
63-
6477
@pytest_asyncio.fixture
65-
async def aiohttp_server() -> Callable[..., Awaitable[TestServer]]:
78+
async def aiohttp_server() -> Iterator[AiohttpServer]:
6679
"""Factory to create a TestServer instance, given an app.
6780
6881
aiohttp_server(app, **kwargs)
@@ -84,15 +97,15 @@ async def go(
8497

8598

8699
@pytest_asyncio.fixture
87-
async def aiohttp_raw_server() -> Callable[..., Awaitable[RawTestServer]]:
100+
async def aiohttp_raw_server() -> Iterator[AiohttpRawServer]:
88101
"""Factory to create a RawTestServer instance, given a web handler.
89102
90103
aiohttp_raw_server(handler, **kwargs)
91104
"""
92105
servers = []
93106

94107
async def go(
95-
handler: Callable[[BaseRequest], Awaitable[StreamResponse]],
108+
handler: _RequestHandler, # TODO(aiohttp4): _RequestHandler[BaseRequest]
96109
*,
97110
port: Optional[int] = None,
98111
**kwargs: Any,
@@ -108,8 +121,8 @@ async def go(
108121
await servers.pop().close()
109122

110123

111-
@pytest.fixture
112-
def aiohttp_client_cls() -> Type[TestClient]:
124+
@pytest_asyncio.fixture
125+
def aiohttp_client_cls() -> Type[TestClient[Any, Any]]:
113126
"""
114127
Client class to use in ``aiohttp_client`` factory.
115128
@@ -137,8 +150,8 @@ def test_login(aiohttp_client):
137150

138151
@pytest_asyncio.fixture
139152
async def aiohttp_client(
140-
aiohttp_client_cls: Type[TestClient],
141-
) -> Generator[AiohttpClient, None, None]:
153+
aiohttp_client_cls: Type[TestClient[Any, Any]]
154+
) -> Iterator[AiohttpClient]:
142155
"""Factory to create a TestClient instance.
143156
144157
aiohttp_client(app, **kwargs)
@@ -147,12 +160,30 @@ async def aiohttp_client(
147160
"""
148161
clients = []
149162

163+
@overload
164+
async def go(
165+
__param: Application,
166+
*,
167+
server_kwargs: Optional[Dict[str, Any]] = None,
168+
**kwargs: Any,
169+
) -> TestClient[Request, Application]: ...
170+
171+
@overload
172+
async def go(
173+
__param: BaseTestServer, # TODO(aiohttp4): BaseTestServer[_Request]
174+
*,
175+
server_kwargs: Optional[Dict[str, Any]] = None,
176+
**kwargs: Any,
177+
) -> TestClient[_Request, None]: ...
178+
150179
async def go(
151-
__param: Union[Application, BaseTestServer],
180+
__param: Union[
181+
Application, BaseTestServer
182+
], # TODO(aiohttp4): BaseTestServer[Any]
152183
*,
153184
server_kwargs: Optional[Dict[str, Any]] = None,
154185
**kwargs: Any,
155-
) -> TestClient:
186+
) -> TestClient[Any, Any]:
156187
if isinstance(__param, Application):
157188
server_kwargs = server_kwargs or {}
158189
server = TestServer(__param, **server_kwargs)

setup.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ setup_requires =
4242

4343
install_requires =
4444
pytest >= 6.1.0
45-
aiohttp >= 3.8.1
45+
aiohttp >= 3.11.0b0
4646
pytest-asyncio >= 0.17.2
4747

4848
[options.extras_require]
4949
testing =
5050
coverage == 6.2
51-
mypy == 0.931
51+
mypy == 1.12.1
5252

5353
[options.entry_points]
5454
pytest11 =

tests/test_fixtures.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
from typing import Any
1+
import pytest
22

3-
pytest_plugins: str = "pytester"
3+
pytest_plugins = "pytester"
44

55

6-
def test_aiohttp_plugin(testdir: Any) -> None:
6+
def test_aiohttp_plugin(testdir: pytest.Testdir) -> None:
77
testdir.makepyfile(
88
"""\
99
import pytest
1010
from unittest import mock
1111
1212
from aiohttp import web
1313
14+
value = web.AppKey('value', str)
15+
1416
1517
async def hello(request):
1618
return web.Response(body=b'Hello, world')
@@ -54,11 +56,11 @@ async def test_noop() -> None:
5456
5557
async def previous(request):
5658
if request.method == 'POST':
57-
with pytest.warns(DeprecationWarning):
58-
request.app['value'] = (await request.post())['value']
59+
with pytest.deprecated_call(): # FIXME: this isn't actually called
60+
request.app[value] = (await request.post())['value']
5961
return web.Response(body=b'thanks for the data')
6062
else:
61-
v = request.app.get('value', 'unknown')
63+
v = request.app.get(value, 'unknown')
6264
return web.Response(body='value: {}'.format(v).encode())
6365
6466
@@ -100,14 +102,13 @@ async def test_custom_port_test_server(aiohttp_server, unused_tcp_port):
100102
app = await create_app()
101103
server = await aiohttp_server(app, port=unused_tcp_port)
102104
assert server.port == unused_tcp_port
103-
104105
"""
105106
)
106107
result = testdir.runpytest("--asyncio-mode=auto")
107108
result.assert_outcomes(passed=8)
108109

109110

110-
def test_aiohttp_raw_server(testdir: Any) -> None:
111+
def test_aiohttp_raw_server(testdir: pytest.Testdir) -> None:
111112
testdir.makepyfile(
112113
"""\
113114
import pytest
@@ -135,14 +136,13 @@ async def test_hello(cli) -> None:
135136
assert resp.status == 200
136137
text = await resp.text()
137138
assert 'OK' in text
138-
139139
"""
140140
)
141141
result = testdir.runpytest("--asyncio-mode=auto")
142142
result.assert_outcomes(passed=1)
143143

144144

145-
def test_aiohttp_client_cls_fixture_custom_client_used(testdir: Any) -> None:
145+
def test_aiohttp_client_cls_fixture_custom_client_used(testdir: pytest.Testdir) -> None:
146146
testdir.makepyfile(
147147
"""
148148
import pytest
@@ -169,7 +169,7 @@ async def test_hello(aiohttp_client) -> None:
169169
result.assert_outcomes(passed=1)
170170

171171

172-
def test_aiohttp_client_cls_fixture_factory(testdir: Any) -> None:
172+
def test_aiohttp_client_cls_fixture_factory(testdir: pytest.Testdir) -> None:
173173
testdir.makeconftest(
174174
"""\
175175

tests/test_obsolete_fixtures.py

Lines changed: 0 additions & 60 deletions
This file was deleted.

tests/test_switch_mode.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
from typing import Any
1+
import pytest
22

33
from pytest_aiohttp.plugin import LEGACY_MODE
44

55
pytest_plugins: str = "pytester"
66

77

8-
def test_warning_for_legacy_mode(testdir: Any) -> None:
8+
def test_warning_for_legacy_mode(testdir: pytest.Testdir) -> None:
99
testdir.makepyfile(
1010
"""\
1111
async def test_a():
@@ -18,7 +18,7 @@ async def test_a():
1818
result.stdout.fnmatch_lines(["*" + str(LEGACY_MODE) + "*"])
1919

2020

21-
def test_auto_mode(testdir: Any) -> None:
21+
def test_auto_mode(testdir: pytest.Testdir) -> None:
2222
testdir.makepyfile(
2323
"""\
2424
async def test_a():
@@ -31,7 +31,7 @@ async def test_a():
3131
result.stdout.no_fnmatch_line("*" + str(LEGACY_MODE) + "*")
3232

3333

34-
def test_strict_mode(testdir: Any) -> None:
34+
def test_strict_mode(testdir: pytest.Testdir) -> None:
3535
testdir.makepyfile(
3636
"""\
3737
import pytest

0 commit comments

Comments
 (0)