Skip to content

Commit

Permalink
Enforce strict mypy checks
Browse files Browse the repository at this point in the history
This change covers the entire codebase with strict typings
and makes the ignores granular.

PR #5370 by @derlih
  • Loading branch information
derlih authored Jan 21, 2021
1 parent de950c2 commit 742a8b6
Show file tree
Hide file tree
Showing 36 changed files with 298 additions and 193 deletions.
24 changes: 24 additions & 0 deletions .mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[mypy]
warn_unused_configs = True
strict = True

[mypy-aiodns]
ignore_missing_imports = True

[mypy-brotli]
ignore_missing_imports = True

[mypy-gunicorn.*]
ignore_missing_imports = True

[mypy-uvloop]
ignore_missing_imports = True

[mypy-cchardet]
ignore_missing_imports = True

[mypy-tokio]
ignore_missing_imports = True

[mypy-asynctest]
ignore_missing_imports = True
1 change: 1 addition & 0 deletions CHANGES/3927.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Use ``mypy --strict``
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ fmt format:

.PHONY: mypy
mypy:
mypy aiohttp tests
mypy --show-error-codes aiohttp tests

.develop: .install-deps $(call to-hash,$(PYS) $(CYS) $(CS))
pip install -e .
Expand Down
10 changes: 5 additions & 5 deletions aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
try:
from ssl import SSLContext
except ImportError: # pragma: no cover
SSLContext = object # type: ignore
SSLContext = object # type: ignore[misc,assignment]


@dataclasses.dataclass(frozen=True)
Expand Down Expand Up @@ -248,7 +248,7 @@ def __init__(
if timeout is sentinel:
self._timeout = DEFAULT_TIMEOUT
else:
self._timeout = timeout # type: ignore
self._timeout = timeout # type: ignore[assignment]
self._raise_for_status = raise_for_status
self._auto_decompress = auto_decompress
self._trust_env = trust_env
Expand Down Expand Up @@ -381,7 +381,7 @@ async def _request(
real_timeout = self._timeout # type: ClientTimeout
else:
if not isinstance(timeout, ClientTimeout):
real_timeout = ClientTimeout(total=timeout) # type: ignore
real_timeout = ClientTimeout(total=timeout) # type: ignore[arg-type]
else:
real_timeout = timeout
# timeout is cumulative for all request operations
Expand Down Expand Up @@ -690,7 +690,7 @@ async def _ws_connect(
DeprecationWarning,
stacklevel=2,
)
ws_timeout = ClientWSTimeout(ws_close=timeout) # type: ignore
ws_timeout = ClientWSTimeout(ws_close=timeout) # type: ignore[arg-type]
else:
ws_timeout = DEFAULT_WS_CLIENT_TIMEOUT
if receive_timeout is not None:
Expand Down Expand Up @@ -1053,7 +1053,7 @@ def __init__(self, coro: Coroutine["asyncio.Future[Any]", None, _RetType]) -> No
def send(self, arg: None) -> "asyncio.Future[Any]":
return self._coro.send(arg)

def throw(self, arg: BaseException) -> None: # type: ignore
def throw(self, arg: BaseException) -> None: # type: ignore[arg-type,override]
self._coro.throw(arg)

def close(self) -> None:
Expand Down
6 changes: 3 additions & 3 deletions aiohttp/client_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

SSLContext = ssl.SSLContext
except ImportError: # pragma: no cover
ssl = SSLContext = None # type: ignore
ssl = SSLContext = None # type: ignore[assignment]


if TYPE_CHECKING: # pragma: no cover
Expand Down Expand Up @@ -270,11 +270,11 @@ class ClientSSLError(ClientConnectorError):
ssl_error_bases = (ClientSSLError,)


class ClientConnectorSSLError(*ssl_error_bases): # type: ignore
class ClientConnectorSSLError(*ssl_error_bases): # type: ignore[misc]
"""Response ssl error."""


class ClientConnectorCertificateError(*cert_errors_bases): # type: ignore
class ClientConnectorCertificateError(*cert_errors_bases): # type: ignore[misc]
"""Response certificate error."""

def __init__(
Expand Down
29 changes: 15 additions & 14 deletions aiohttp/client_reqrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@
import ssl
from ssl import SSLContext
except ImportError: # pragma: no cover
ssl = None # type: ignore
SSLContext = object # type: ignore
ssl = None # type: ignore[assignment]
SSLContext = object # type: ignore[misc,assignment]

try:
import cchardet as chardet
except ImportError: # pragma: no cover
import chardet # type: ignore
import chardet # type: ignore[no-redef]


__all__ = ("ClientRequest", "ClientResponse", "RequestInfo", "Fingerprint")
Expand Down Expand Up @@ -333,9 +333,9 @@ def update_headers(self, headers: Optional[LooseHeaders]) -> None:

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

for key, value in headers: # type: ignore
for key, value in headers: # type: ignore[misc]
# A special case for Host header
if key.lower() == "host":
self.headers[key] = value
Expand All @@ -347,7 +347,7 @@ def update_auto_headers(self, skip_auto_headers: Iterable[str]) -> None:
(hdr, None) for hdr in sorted(skip_auto_headers)
)
used_headers = self.headers.copy()
used_headers.extend(self.skip_auto_headers) # type: ignore
used_headers.extend(self.skip_auto_headers) # type: ignore[arg-type]

for hdr, val in self.DEFAULT_HEADERS.items():
if hdr not in used_headers:
Expand All @@ -369,15 +369,15 @@ def update_cookies(self, cookies: Optional[LooseCookies]) -> None:
if isinstance(cookies, Mapping):
iter_cookies = cookies.items()
else:
iter_cookies = cookies # type: ignore
iter_cookies = cookies # type: ignore[assignment]
for name, value in iter_cookies:
if isinstance(value, Morsel):
# Preserve coded_value
mrsl_val = value.get(value.key, Morsel())
mrsl_val.set(value.key, value.value, value.coded_value)
c[name] = mrsl_val
else:
c[name] = value # type: ignore
c[name] = value # type: ignore[assignment]

self.headers[hdrs.COOKIE] = c.output(header="", sep=";").strip()

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

for chunk in self.body:
await writer.write(chunk) # type: ignore
await writer.write(chunk) # type: ignore[arg-type]

await writer.write_eof()
except OSError as exc:
Expand Down Expand Up @@ -806,7 +806,7 @@ def links(self) -> "MultiDictProxy[MultiDictProxy[Union[str, URL]]]":

link.add(key, value)

key = link.get("rel", url) # type: ignore
key = link.get("rel", url) # type: ignore[assignment]

link.add("url", self.url.join(URL(url)))

Expand All @@ -824,7 +824,8 @@ async def start(self, connection: "Connection") -> "ClientResponse":
while True:
# read response
try:
message, payload = await self._protocol.read() # type: ignore
protocol = self._protocol
message, payload = await protocol.read() # type: ignore[union-attr]
except http.HttpProcessingError as exc:
raise ClientResponseError(
self.request_info,
Expand Down Expand Up @@ -1011,7 +1012,7 @@ async def text(self, encoding: Optional[str] = None, errors: str = "strict") ->
if encoding is None:
encoding = self.get_encoding()

return self._body.decode(encoding, errors=errors) # type: ignore
return self._body.decode(encoding, errors=errors) # type: ignore[union-attr]

async def json(
self,
Expand Down Expand Up @@ -1039,7 +1040,7 @@ async def json(
if encoding is None:
encoding = self.get_encoding()

return loads(self._body.decode(encoding)) # type: ignore
return loads(self._body.decode(encoding)) # type: ignore[union-attr]

async def __aenter__(self) -> "ClientResponse":
return self
Expand Down
10 changes: 5 additions & 5 deletions aiohttp/client_ws.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import asyncio
import dataclasses
from typing import Any, Optional
from typing import Any, Optional, cast

import async_timeout
from typing_extensions import Final
Expand Down Expand Up @@ -68,10 +68,10 @@ def __init__(
self._autoclose = autoclose
self._autoping = autoping
self._heartbeat = heartbeat
self._heartbeat_cb = None
self._heartbeat_cb: Optional[asyncio.TimerHandle] = None
if heartbeat is not None:
self._pong_heartbeat = heartbeat / 2.0
self._pong_response_cb = None
self._pong_response_cb: Optional[asyncio.TimerHandle] = None
self._loop = loop
self._waiting = None # type: Optional[asyncio.Future[bool]]
self._exception = None # type: Optional[BaseException]
Expand Down Expand Up @@ -286,13 +286,13 @@ async def receive_str(self, *, timeout: Optional[float] = None) -> str:
msg = await self.receive(timeout)
if msg.type != WSMsgType.TEXT:
raise TypeError(f"Received message {msg.type}:{msg.data!r} is not str")
return msg.data
return cast(str, msg.data)

async def receive_bytes(self, *, timeout: Optional[float] = None) -> bytes:
msg = await self.receive(timeout)
if msg.type != WSMsgType.BINARY:
raise TypeError(f"Received message {msg.type}:{msg.data!r} is not bytes")
return msg.data
return cast(bytes, msg.data)

async def receive_json(
self,
Expand Down
22 changes: 12 additions & 10 deletions aiohttp/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@

SSLContext = ssl.SSLContext
except ImportError: # pragma: no cover
ssl = None # type: ignore
SSLContext = object # type: ignore
ssl = None # type: ignore[assignment]
SSLContext = object # type: ignore[misc,assignment]


__all__ = ("BaseConnector", "TCPConnector", "UnixConnector", "NamedPipeConnector")
Expand Down Expand Up @@ -218,18 +218,18 @@ def __init__(
self._force_close = force_close

# {host_key: FIFO list of waiters}
self._waiters = defaultdict(deque) # type: ignore
self._waiters = defaultdict(deque) # type: ignore[var-annotated]

self._loop = loop
self._factory = functools.partial(ResponseHandler, loop=loop)

self.cookies = SimpleCookie() # type: SimpleCookie[str]

# start keep-alive connection cleanup task
self._cleanup_handle = None
self._cleanup_handle: Optional[asyncio.TimerHandle] = None

# start cleanup closed transports task
self._cleanup_closed_handle = None
self._cleanup_closed_handle: Optional[asyncio.TimerHandle] = None
self._cleanup_closed_disabled = not enable_cleanup_closed
self._cleanup_closed_transports = [] # type: List[Optional[asyncio.Transport]]
self._cleanup_closed()
Expand Down Expand Up @@ -744,7 +744,7 @@ def __init__(
self._ssl = ssl
if resolver is None:
resolver = DefaultResolver()
self._resolver = resolver
self._resolver: AbstractResolver = resolver

self._use_dns_cache = use_dns_cache
self._cached_hosts = _DNSCacheTable(ttl=ttl_dns_cache)
Expand Down Expand Up @@ -943,7 +943,7 @@ async def _wrap_create_connection(
) -> Tuple[asyncio.Transport, ResponseHandler]:
try:
async with ceil_timeout(timeout.sock_connect):
return await self._loop.create_connection(*args, **kwargs) # type: ignore # noqa
return await self._loop.create_connection(*args, **kwargs) # type: ignore[return-value] # noqa
except cert_errors as exc:
raise ClientConnectorCertificateError(req.connection_key, exc) from exc
except ssl_errors as exc:
Expand Down Expand Up @@ -1031,7 +1031,7 @@ async def _create_proxy_connection(
) -> Tuple[asyncio.Transport, ResponseHandler]:
headers = {} # type: Dict[str, str]
if req.proxy_headers is not None:
headers = req.proxy_headers # type: ignore
headers = req.proxy_headers # type: ignore[assignment]
headers[hdrs.HOST] = req.headers[hdrs.HOST]

url = req.proxy
Expand Down Expand Up @@ -1202,7 +1202,9 @@ def __init__(
limit=limit,
limit_per_host=limit_per_host,
)
if not isinstance(self._loop, asyncio.ProactorEventLoop): # type: ignore
if not isinstance(
self._loop, asyncio.ProactorEventLoop # type: ignore[attr-defined]
):
raise RuntimeError(
"Named Pipes only available in proactor " "loop under windows"
)
Expand All @@ -1218,7 +1220,7 @@ async def _create_connection(
) -> ResponseHandler:
try:
async with ceil_timeout(timeout.sock_connect):
_, proto = await self._loop.create_pipe_connection( # type: ignore
_, proto = await self._loop.create_pipe_connection( # type: ignore[attr-defined] # noqa: E501
self._factory, self._path
)
# the drain is required so that the connection_made is called
Expand Down
2 changes: 1 addition & 1 deletion aiohttp/cookiejar.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> No
for name, cookie in cookies:
if not isinstance(cookie, Morsel):
tmp = SimpleCookie() # type: SimpleCookie[str]
tmp[name] = cookie # type: ignore
tmp[name] = cookie # type: ignore[assignment]
cookie = tmp[name]

domain = cookie["domain"]
Expand Down
4 changes: 2 additions & 2 deletions aiohttp/formdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,14 @@ def add_fields(self, *fields: Any) -> None:

if isinstance(rec, io.IOBase):
k = guess_filename(rec, "unknown")
self.add_field(k, rec) # type: ignore
self.add_field(k, rec) # type: ignore[arg-type]

elif isinstance(rec, (MultiDictProxy, MultiDict)):
to_add.extend(rec.items())

elif isinstance(rec, (list, tuple)) and len(rec) == 2:
k, fp = rec
self.add_field(k, fp) # type: ignore
self.add_field(k, fp) # type: ignore[arg-type]

else:
raise TypeError(
Expand Down
Loading

0 comments on commit 742a8b6

Please sign in to comment.