From ac739e5cdc74b459915ba175dd0c1fb49eade314 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Tue, 9 Feb 2021 20:55:46 +0000 Subject: [PATCH] Mypy coverage --- .mypy.ini | 37 ++++++++++++++++++++++++++++++------ CHANGES/5457.misc | 1 + Makefile | 2 +- aiohttp/connector.py | 2 +- aiohttp/resolver.py | 5 +++-- aiohttp/worker.py | 2 +- examples/__init__.py | 0 examples/background_tasks.py | 4 ++-- examples/client_json.py | 2 +- examples/client_ws.py | 5 +++-- examples/fake_server.py | 8 ++++++-- examples/web_classview.py | 4 ++-- examples/web_cookies.py | 21 ++++++++++---------- 13 files changed, 63 insertions(+), 30 deletions(-) create mode 100644 CHANGES/5457.misc create mode 100644 examples/__init__.py diff --git a/.mypy.ini b/.mypy.ini index 5cf92fa6297..6fb5bf18431 100644 --- a/.mypy.ini +++ b/.mypy.ini @@ -1,24 +1,49 @@ [mypy] -warn_unused_configs = True -strict = True +files = aiohttp, examples +check_untyped_defs = True +follow_imports_for_stubs = True +#disallow_any_decorated = True +disallow_any_generics = True +disallow_incomplete_defs = True +disallow_subclassing_any = True +disallow_untyped_calls = True +disallow_untyped_decorators = True +disallow_untyped_defs = True +implicit_reexport = False +no_implicit_optional = True +show_error_codes = True +strict_equality = True +warn_incomplete_stub = True +warn_redundant_casts = True +#warn_unreachable = True +warn_unused_ignores = True +disallow_any_unimported = True +warn_return_any = True + +[mypy-examples.*] +disallow_untyped_calls = False +disallow_untyped_defs = False [mypy-aiodns] ignore_missing_imports = True -[mypy-brotli] +[mypy-aioredis] ignore_missing_imports = True -[mypy-gunicorn.*] +[mypy-asynctest] ignore_missing_imports = True -[mypy-uvloop] +[mypy-brotli] ignore_missing_imports = True [mypy-cchardet] ignore_missing_imports = True +[mypy-gunicorn.*] +ignore_missing_imports = True + [mypy-tokio] ignore_missing_imports = True -[mypy-asynctest] +[mypy-uvloop] ignore_missing_imports = True diff --git a/CHANGES/5457.misc b/CHANGES/5457.misc new file mode 100644 index 00000000000..5f0fad6bce6 --- /dev/null +++ b/CHANGES/5457.misc @@ -0,0 +1 @@ +Improve Mypy coverage. diff --git a/Makefile b/Makefile index 6a617042960..12572c65042 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,7 @@ fmt format: .PHONY: mypy mypy: - mypy --show-error-codes aiohttp + mypy .develop: .install-deps $(call to-hash,$(PYS) $(CYS) $(CS)) pip install -e . diff --git a/aiohttp/connector.py b/aiohttp/connector.py index aeabcb0308e..4de0cf42d78 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -844,7 +844,7 @@ async def _resolve_host( for trace in traces: await trace.send_dns_resolvehost_end(host) - return res # type: ignore[no-any-return] + return res key = (host, port) diff --git a/aiohttp/resolver.py b/aiohttp/resolver.py index 660c209ca9e..2161c8fa84d 100644 --- a/aiohttp/resolver.py +++ b/aiohttp/resolver.py @@ -1,6 +1,6 @@ import asyncio import socket -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List, Optional, Type, Union from .abc import AbstractResolver from .helpers import get_running_loop @@ -146,4 +146,5 @@ async def close(self) -> None: self._resolver.cancel() -DefaultResolver = AsyncResolver if aiodns_default else ThreadedResolver +_DefaultType = Type[Union[AsyncResolver, ThreadedResolver]] +DefaultResolver: _DefaultType = AsyncResolver if aiodns_default else ThreadedResolver diff --git a/aiohttp/worker.py b/aiohttp/worker.py index b945f8b3b40..2b460cc7103 100644 --- a/aiohttp/worker.py +++ b/aiohttp/worker.py @@ -29,7 +29,7 @@ __all__ = ("GunicornWebWorker", "GunicornUVLoopWebWorker", "GunicornTokioWebWorker") -class GunicornWebWorker(base.Worker): # type: ignore[misc] +class GunicornWebWorker(base.Worker): # type: ignore[misc,no-any-unimported] DEFAULT_AIOHTTP_LOG_FORMAT = AccessLogger.LOG_FORMAT DEFAULT_GUNICORN_LOG_FORMAT = GunicornAccessLogFormat.default diff --git a/examples/__init__.py b/examples/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/background_tasks.py b/examples/background_tasks.py index 2a1ec12afae..8c2bb9ee692 100755 --- a/examples/background_tasks.py +++ b/examples/background_tasks.py @@ -43,8 +43,8 @@ async def listen_to_redis(app): print("Redis connection closed.") -async def start_background_tasks(app): - app["redis_listener"] = app.loop.create_task(listen_to_redis(app)) +async def start_background_tasks(app: web.Application) -> None: + app["redis_listener"] = asyncio.create_task(listen_to_redis(app)) async def cleanup_background_tasks(app): diff --git a/examples/client_json.py b/examples/client_json.py index e54edeaddb6..f57115640c4 100755 --- a/examples/client_json.py +++ b/examples/client_json.py @@ -4,7 +4,7 @@ import aiohttp -async def fetch(session): +async def fetch(session: aiohttp.ClientSession) -> None: print("Query http://httpbin.org/get") async with session.get("http://httpbin.org/get") as resp: print(resp.status) diff --git a/examples/client_ws.py b/examples/client_ws.py index ec48eccc9ad..38d83003624 100755 --- a/examples/client_ws.py +++ b/examples/client_ws.py @@ -44,8 +44,9 @@ async def dispatch(): break # send request - async with aiohttp.ws_connect(url, autoclose=False, autoping=False) as ws: - await dispatch() + async with aiohttp.ClientSession() as session: + async with session.ws_connect(url, autoclose=False, autoping=False) as ws: + await dispatch() ARGS = argparse.ArgumentParser( diff --git a/examples/fake_server.py b/examples/fake_server.py index 007d96ba027..0006f5f0028 100755 --- a/examples/fake_server.py +++ b/examples/fake_server.py @@ -6,11 +6,12 @@ import aiohttp from aiohttp import web +from aiohttp.abc import AbstractResolver from aiohttp.resolver import DefaultResolver from aiohttp.test_utils import unused_port -class FakeResolver: +class FakeResolver(AbstractResolver): _LOCAL_HOST = {0: "127.0.0.1", socket.AF_INET: "127.0.0.1", socket.AF_INET6: "::1"} def __init__(self, fakes, *, loop): @@ -34,6 +35,9 @@ async def resolve(self, host, port=0, family=socket.AF_INET): else: return await self._resolver.resolve(host, port, family) + async def close(self) -> None: + self._resolver.close() + class FakeFacebook: def __init__(self, *, loop): @@ -45,7 +49,7 @@ def __init__(self, *, loop): web.get("/v2.7/me/friends", self.on_my_friends), ] ) - self.runner = None + self.runner = web.AppRunner(self.app) here = pathlib.Path(__file__) ssl_cert = here.parent / "server.crt" ssl_key = here.parent / "server.key" diff --git a/examples/web_classview.py b/examples/web_classview.py index 0f65f7d7f43..a6d3e435aca 100755 --- a/examples/web_classview.py +++ b/examples/web_classview.py @@ -14,7 +14,7 @@ async def get(self): return web.json_response( { "method": "get", - "args": dict(self.request.GET), + "args": dict(self.request.query), "headers": dict(self.request.headers), }, dumps=functools.partial(json.dumps, indent=4), @@ -25,7 +25,7 @@ async def post(self): return web.json_response( { "method": "post", - "args": dict(self.request.GET), + "args": dict(self.request.query), "data": dict(data), "headers": dict(self.request.headers), }, diff --git a/examples/web_cookies.py b/examples/web_cookies.py index e7a4a595d77..7b4743699ff 100755 --- a/examples/web_cookies.py +++ b/examples/web_cookies.py @@ -3,6 +3,7 @@ """ from pprint import pformat +from typing import NoReturn from aiohttp import web @@ -22,20 +23,20 @@ async def root(request): return resp -async def login(request): - resp = web.HTTPFound(location="/") - resp.set_cookie("AUTH", "secret") - return resp +async def login(request: web.Request) -> NoReturn: + exc = web.HTTPFound(location="/") + exc.set_cookie("AUTH", "secret") + raise exc -async def logout(request): - resp = web.HTTPFound(location="/") - resp.del_cookie("AUTH") - return resp +async def logout(request: web.Request) -> NoReturn: + exc = web.HTTPFound(location="/") + exc.del_cookie("AUTH") + raise exc -def init(loop): - app = web.Application(loop=loop) +def init(): + app = web.Application() app.router.add_get("/", root) app.router.add_get("/login", login) app.router.add_get("/logout", logout)