diff --git a/httpcore/_api.py b/httpcore/_api.py index 859a189c1..cdffd727b 100644 --- a/httpcore/_api.py +++ b/httpcore/_api.py @@ -1,17 +1,18 @@ from contextlib import contextmanager -from typing import Iterator, Optional, Union +from typing import Any, Dict, Iterator, Optional, Union from ._models import URL, Response from ._sync.connection_pool import ConnectionPool +from ._types import HeadersAsMapping, HeadersAsSequence def request( method: Union[bytes, str], url: Union[URL, bytes, str], *, - headers: Union[dict, list, None] = None, + headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, content: Union[bytes, Iterator[bytes], None] = None, - extensions: Optional[dict] = None, + extensions: Optional[Dict[str, Any]] = None, ) -> Response: """ Sends an HTTP request, returning the response. @@ -50,9 +51,9 @@ def stream( method: Union[bytes, str], url: Union[URL, bytes, str], *, - headers: Union[dict, list, None] = None, + headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, content: Union[bytes, Iterator[bytes], None] = None, - extensions: Optional[dict] = None, + extensions: Optional[Dict[str, Any]] = None, ) -> Iterator[Response]: """ Sends an HTTP request, returning the response within a content manager. diff --git a/httpcore/_async/__init__.py b/httpcore/_async/__init__.py index 88dc7f01e..c74d9d172 100644 --- a/httpcore/_async/__init__.py +++ b/httpcore/_async/__init__.py @@ -8,8 +8,8 @@ from .http2 import AsyncHTTP2Connection except ImportError: # pragma: nocover - class AsyncHTTP2Connection: # type: ignore - def __init__(self, *args, **kwargs) -> None: # type: ignore + class AsyncHTTP2Connection: # type: ignore[no-redef] + def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def] raise RuntimeError( "Attempted to use http2 support, but the `h2` package is not " "installed. Use 'pip install httpcore[http2]'." @@ -20,8 +20,8 @@ def __init__(self, *args, **kwargs) -> None: # type: ignore from .socks_proxy import AsyncSOCKSProxy except ImportError: # pragma: nocover - class AsyncSOCKSProxy: # type: ignore - def __init__(self, *args, **kwargs) -> None: # type: ignore + class AsyncSOCKSProxy: # type: ignore[no-redef] + def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def] raise RuntimeError( "Attempted to use SOCKS support, but the `socksio` package is not " "installed. Use 'pip install httpcore[socks]'." diff --git a/httpcore/_async/connection_pool.py b/httpcore/_async/connection_pool.py index 06ead3ee0..874a908dc 100644 --- a/httpcore/_async/connection_pool.py +++ b/httpcore/_async/connection_pool.py @@ -349,6 +349,6 @@ async def __aiter__(self) -> AsyncIterator[bytes]: async def aclose(self) -> None: try: if hasattr(self._stream, "aclose"): - await self._stream.aclose() # type: ignore + await self._stream.aclose() # type: ignore[attr-defined] finally: await self._pool.response_closed(self._status) diff --git a/httpcore/_async/http2.py b/httpcore/_async/http2.py index 4be4789f4..b380a8501 100644 --- a/httpcore/_async/http2.py +++ b/httpcore/_async/http2.py @@ -342,8 +342,9 @@ async def _read_incoming_data( self._connection_error = True raise exc - events = self._h2_state.receive_data(data) - + events = typing.cast( + typing.List[h2.events.Event], self._h2_state.receive_data(data) + ) return events async def _write_outgoing_data(self, request: Request) -> None: @@ -381,13 +382,17 @@ async def _wait_for_outgoing_flow(self, request: Request, stream_id: int) -> int WindowUpdated frames have increased the flow rate. https://tools.ietf.org/html/rfc7540#section-6.9 """ - local_flow = self._h2_state.local_flow_control_window(stream_id) - max_frame_size = self._h2_state.max_outbound_frame_size + local_flow = typing.cast( + int, self._h2_state.local_flow_control_window(stream_id) + ) + max_frame_size = typing.cast(int, self._h2_state.max_outbound_frame_size) flow = min(local_flow, max_frame_size) while flow == 0: await self._receive_events(request) - local_flow = self._h2_state.local_flow_control_window(stream_id) - max_frame_size = self._h2_state.max_outbound_frame_size + local_flow = typing.cast( + int, self._h2_state.local_flow_control_window(stream_id) + ) + max_frame_size = typing.cast(int, self._h2_state.max_outbound_frame_size) flow = min(local_flow, max_frame_size) return flow diff --git a/httpcore/_async/http_proxy.py b/httpcore/_async/http_proxy.py index 48d37cd36..bf0fcc7a5 100644 --- a/httpcore/_async/http_proxy.py +++ b/httpcore/_async/http_proxy.py @@ -1,6 +1,6 @@ import ssl from base64 import b64encode -from typing import List, Mapping, Optional, Sequence, Tuple, Union +from typing import List, Optional, Sequence, Tuple, Union from .._exceptions import ProxyError from .._models import ( @@ -15,15 +15,13 @@ from .._ssl import default_ssl_context from .._synchronization import AsyncLock from .._trace import Trace +from .._types import HeadersAsMapping, HeadersAsSequence from ..backends.base import AsyncNetworkBackend from .connection import AsyncHTTPConnection from .connection_pool import AsyncConnectionPool from .http11 import AsyncHTTP11Connection from .interfaces import AsyncConnectionInterface -HeadersAsSequence = Sequence[Tuple[Union[bytes, str], Union[bytes, str]]] -HeadersAsMapping = Mapping[Union[bytes, str], Union[bytes, str]] - def merge_headers( default_headers: Optional[Sequence[Tuple[bytes, bytes]]] = None, diff --git a/httpcore/_async/interfaces.py b/httpcore/_async/interfaces.py index 95165724e..9694d63f2 100644 --- a/httpcore/_async/interfaces.py +++ b/httpcore/_async/interfaces.py @@ -1,4 +1,4 @@ -from typing import AsyncIterator, Optional, Union +from typing import Any, AsyncIterator, Dict, Optional, Union from .._compat import asynccontextmanager from .._models import ( @@ -11,6 +11,7 @@ enforce_url, include_request_headers, ) +from .._types import HeadersAsMapping, HeadersAsSequence class AsyncRequestInterface: @@ -19,9 +20,9 @@ async def request( method: Union[bytes, str], url: Union[URL, bytes, str], *, - headers: Union[dict, list, None] = None, + headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, content: Union[bytes, AsyncIterator[bytes], None] = None, - extensions: Optional[dict] = None, + extensions: Optional[Dict[str, Any]] = None, ) -> Response: # Strict type checking on our parameters. method = enforce_bytes(method, name="method") @@ -45,15 +46,15 @@ async def request( await response.aclose() return response - @asynccontextmanager + @asynccontextmanager # type: ignore[misc] async def stream( self, method: Union[bytes, str], url: Union[URL, bytes, str], *, - headers: Union[dict, list, None] = None, + headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, content: Union[bytes, AsyncIterator[bytes], None] = None, - extensions: Optional[dict] = None, + extensions: Optional[Dict[str, Any]] = None, ) -> AsyncIterator[Response]: # Strict type checking on our parameters. method = enforce_bytes(method, name="method") diff --git a/httpcore/_compat.py b/httpcore/_compat.py index aa4f5bd3f..a3c0f81d9 100644 --- a/httpcore/_compat.py +++ b/httpcore/_compat.py @@ -1,6 +1,8 @@ # `contextlib.asynccontextmanager` exists from Python 3.7 onwards. # For 3.6 we require the `async_generator` package for a backported version. -try: - from contextlib import asynccontextmanager # type: ignore -except ImportError: - from async_generator import asynccontextmanager # type: ignore # noqa +import sys + +if sys.version_info >= (3, 7): + from contextlib import asynccontextmanager as asynccontextmanager +else: + from async_generator import asynccontextmanager as asynccontextmanager # noqa: F401 diff --git a/httpcore/_exceptions.py b/httpcore/_exceptions.py index f28dcc256..efae0d1ca 100644 --- a/httpcore/_exceptions.py +++ b/httpcore/_exceptions.py @@ -1,9 +1,11 @@ import contextlib -from typing import Dict, Iterator, Type +from typing import Iterator, Mapping, Type + +ExceptionMappingType = Mapping[Type[Exception], Type[Exception]] @contextlib.contextmanager -def map_exceptions(map: Dict[Type, Type]) -> Iterator[None]: +def map_exceptions(map: ExceptionMappingType) -> Iterator[None]: try: yield except Exception as exc: # noqa: PIE786 diff --git a/httpcore/_models.py b/httpcore/_models.py index 170011c68..381205577 100644 --- a/httpcore/_models.py +++ b/httpcore/_models.py @@ -2,6 +2,7 @@ Any, AsyncIterable, AsyncIterator, + Dict, Iterable, Iterator, List, @@ -13,11 +14,9 @@ ) from urllib.parse import urlparse -# Functions for typechecking... - +from ._types import HeadersAsMapping, HeadersAsSequence -HeadersAsSequence = Sequence[Tuple[Union[bytes, str], Union[bytes, str]]] -HeadersAsMapping = Mapping[Union[bytes, str], Union[bytes, str]] +# Functions for typechecking... def enforce_bytes(value: Union[bytes, str], *, name: str) -> bytes: @@ -318,9 +317,9 @@ def __init__( method: Union[bytes, str], url: Union[URL, bytes, str], *, - headers: Union[dict, list, None] = None, + headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, content: Union[bytes, Iterable[bytes], AsyncIterable[bytes], None] = None, - extensions: Optional[dict] = None, + extensions: Optional[Dict[str, Any]] = None, ) -> None: """ Parameters: @@ -356,9 +355,9 @@ def __init__( self, status: int, *, - headers: Union[dict, list, None] = None, + headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, content: Union[bytes, Iterable[bytes], AsyncIterable[bytes], None] = None, - extensions: Optional[dict] = None, + extensions: Optional[Dict[str, Any]] = None, ) -> None: """ Parameters: @@ -376,7 +375,7 @@ def __init__( self.stream: Union[Iterable[bytes], AsyncIterable[bytes]] = enforce_stream( content, name="content" ) - self.extensions: dict = {} if extensions is None else extensions + self.extensions: Dict[str, Any] = {} if extensions is None else extensions self._stream_consumed = False @@ -432,7 +431,7 @@ def close(self) -> None: "You should use 'await response.aclose()' instead." ) if hasattr(self.stream, "close"): - self.stream.close() # type: ignore + self.stream.close() # type: ignore[attr-defined] # Async interface... @@ -471,4 +470,4 @@ async def aclose(self) -> None: "You should use 'response.close()' instead." ) if hasattr(self.stream, "aclose"): - await self.stream.aclose() # type: ignore + await self.stream.aclose() # type: ignore[attr-defined] diff --git a/httpcore/_ssl.py b/httpcore/_ssl.py index 629f002f0..c99c5a679 100644 --- a/httpcore/_ssl.py +++ b/httpcore/_ssl.py @@ -1,6 +1,6 @@ import ssl -import certifi # type: ignore +import certifi def default_ssl_context() -> ssl.SSLContext: diff --git a/httpcore/_sync/__init__.py b/httpcore/_sync/__init__.py index b476d76d9..15611a178 100644 --- a/httpcore/_sync/__init__.py +++ b/httpcore/_sync/__init__.py @@ -8,8 +8,8 @@ from .http2 import HTTP2Connection except ImportError: # pragma: nocover - class HTTP2Connection: # type: ignore - def __init__(self, *args, **kwargs) -> None: # type: ignore + class HTTP2Connection: # type: ignore[no-redef] + def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def] raise RuntimeError( "Attempted to use http2 support, but the `h2` package is not " "installed. Use 'pip install httpcore[http2]'." @@ -20,8 +20,8 @@ def __init__(self, *args, **kwargs) -> None: # type: ignore from .socks_proxy import SOCKSProxy except ImportError: # pragma: nocover - class SOCKSProxy: # type: ignore - def __init__(self, *args, **kwargs) -> None: # type: ignore + class SOCKSProxy: # type: ignore[no-redef] + def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def] raise RuntimeError( "Attempted to use SOCKS support, but the `socksio` package is not " "installed. Use 'pip install httpcore[socks]'." diff --git a/httpcore/_sync/connection_pool.py b/httpcore/_sync/connection_pool.py index 88b291878..14b9425a7 100644 --- a/httpcore/_sync/connection_pool.py +++ b/httpcore/_sync/connection_pool.py @@ -349,6 +349,6 @@ def __iter__(self) -> Iterator[bytes]: def close(self) -> None: try: if hasattr(self._stream, "close"): - self._stream.close() # type: ignore + self._stream.close() # type: ignore[attr-defined] finally: self._pool.response_closed(self._status) diff --git a/httpcore/_sync/http2.py b/httpcore/_sync/http2.py index 5bd2de02a..0e57c89de 100644 --- a/httpcore/_sync/http2.py +++ b/httpcore/_sync/http2.py @@ -342,8 +342,9 @@ def _read_incoming_data( self._connection_error = True raise exc - events = self._h2_state.receive_data(data) - + events = typing.cast( + typing.List[h2.events.Event], self._h2_state.receive_data(data) + ) return events def _write_outgoing_data(self, request: Request) -> None: @@ -381,13 +382,17 @@ def _wait_for_outgoing_flow(self, request: Request, stream_id: int) -> int: WindowUpdated frames have increased the flow rate. https://tools.ietf.org/html/rfc7540#section-6.9 """ - local_flow = self._h2_state.local_flow_control_window(stream_id) - max_frame_size = self._h2_state.max_outbound_frame_size + local_flow = typing.cast( + int, self._h2_state.local_flow_control_window(stream_id) + ) + max_frame_size = typing.cast(int, self._h2_state.max_outbound_frame_size) flow = min(local_flow, max_frame_size) while flow == 0: self._receive_events(request) - local_flow = self._h2_state.local_flow_control_window(stream_id) - max_frame_size = self._h2_state.max_outbound_frame_size + local_flow = typing.cast( + int, self._h2_state.local_flow_control_window(stream_id) + ) + max_frame_size = typing.cast(int, self._h2_state.max_outbound_frame_size) flow = min(local_flow, max_frame_size) return flow diff --git a/httpcore/_sync/http_proxy.py b/httpcore/_sync/http_proxy.py index 3dadf9af7..af9ccc1ff 100644 --- a/httpcore/_sync/http_proxy.py +++ b/httpcore/_sync/http_proxy.py @@ -1,6 +1,6 @@ import ssl from base64 import b64encode -from typing import List, Mapping, Optional, Sequence, Tuple, Union +from typing import List, Optional, Sequence, Tuple, Union from .._exceptions import ProxyError from .._models import ( @@ -15,15 +15,13 @@ from .._ssl import default_ssl_context from .._synchronization import Lock from .._trace import Trace +from .._types import HeadersAsMapping, HeadersAsSequence from ..backends.base import NetworkBackend from .connection import HTTPConnection from .connection_pool import ConnectionPool from .http11 import HTTP11Connection from .interfaces import ConnectionInterface -HeadersAsSequence = Sequence[Tuple[Union[bytes, str], Union[bytes, str]]] -HeadersAsMapping = Mapping[Union[bytes, str], Union[bytes, str]] - def merge_headers( default_headers: Optional[Sequence[Tuple[bytes, bytes]]] = None, diff --git a/httpcore/_sync/interfaces.py b/httpcore/_sync/interfaces.py index df2f2c198..8b0210de4 100644 --- a/httpcore/_sync/interfaces.py +++ b/httpcore/_sync/interfaces.py @@ -1,4 +1,4 @@ -from typing import Iterator, Optional, Union +from typing import Any, Iterator, Dict, Optional, Union from contextlib import contextmanager from .._models import ( @@ -11,6 +11,7 @@ enforce_url, include_request_headers, ) +from .._types import HeadersAsMapping, HeadersAsSequence class RequestInterface: @@ -19,9 +20,9 @@ def request( method: Union[bytes, str], url: Union[URL, bytes, str], *, - headers: Union[dict, list, None] = None, + headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, content: Union[bytes, Iterator[bytes], None] = None, - extensions: Optional[dict] = None, + extensions: Optional[Dict[str, Any]] = None, ) -> Response: # Strict type checking on our parameters. method = enforce_bytes(method, name="method") @@ -45,15 +46,15 @@ def request( response.close() return response - @contextmanager + @contextmanager # type: ignore[misc] def stream( self, method: Union[bytes, str], url: Union[URL, bytes, str], *, - headers: Union[dict, list, None] = None, + headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, content: Union[bytes, Iterator[bytes], None] = None, - extensions: Optional[dict] = None, + extensions: Optional[Dict[str, Any]] = None, ) -> Iterator[Response]: # Strict type checking on our parameters. method = enforce_bytes(method, name="method") diff --git a/httpcore/_synchronization.py b/httpcore/_synchronization.py index 3885ca7fb..87c8687de 100644 --- a/httpcore/_synchronization.py +++ b/httpcore/_synchronization.py @@ -4,7 +4,7 @@ import anyio -from ._exceptions import PoolTimeout, map_exceptions +from ._exceptions import ExceptionMappingType, PoolTimeout, map_exceptions class AsyncLock: @@ -32,7 +32,7 @@ def set(self) -> None: self._event.set() async def wait(self, timeout: Optional[float] = None) -> None: - exc_map: dict = {TimeoutError: PoolTimeout} + exc_map: ExceptionMappingType = {TimeoutError: PoolTimeout} with map_exceptions(exc_map): with anyio.fail_after(timeout): await self._event.wait() diff --git a/httpcore/_trace.py b/httpcore/_trace.py index c957c2cfe..63cb18fd1 100644 --- a/httpcore/_trace.py +++ b/httpcore/_trace.py @@ -1,12 +1,12 @@ from types import TracebackType -from typing import Any, Optional, Type +from typing import Any, Dict, Optional, Type from ._models import Request class Trace: def __init__( - self, name: str, request: Request, kwargs: Optional[dict] = None + self, name: str, request: Request, kwargs: Optional[Dict[str, Any]] = None ) -> None: self.name = name self.trace = request.extensions.get("trace") @@ -27,7 +27,7 @@ def __exit__( ) -> None: if self.trace is not None: if exc_value is None: - info: dict = {"return_value": self.return_value} + info: Dict[str, Any] = {"return_value": self.return_value} self.trace(f"{self.name}.complete", info) else: info = {"exception": exc_value} @@ -47,7 +47,7 @@ async def __aexit__( ) -> None: if self.trace is not None: if exc_value is None: - info: dict = {"return_value": self.return_value} + info: Dict[str, Any] = {"return_value": self.return_value} await self.trace(f"{self.name}.complete", info) else: info = {"exception": exc_value} diff --git a/httpcore/_types.py b/httpcore/_types.py new file mode 100644 index 000000000..1a3834f48 --- /dev/null +++ b/httpcore/_types.py @@ -0,0 +1,4 @@ +from typing import Mapping, Sequence, Tuple, Union + +HeadersAsSequence = Sequence[Tuple[Union[bytes, str], Union[bytes, str]]] +HeadersAsMapping = Mapping[Union[bytes, str], Union[bytes, str]] diff --git a/httpcore/backends/sync.py b/httpcore/backends/sync.py index 18e1dd348..e4a0c9b0d 100644 --- a/httpcore/backends/sync.py +++ b/httpcore/backends/sync.py @@ -5,6 +5,7 @@ from .._exceptions import ( ConnectError, ConnectTimeout, + ExceptionMappingType, ReadError, ReadTimeout, WriteError, @@ -20,7 +21,10 @@ def __init__(self, sock: socket.socket) -> None: self._sock = sock def read(self, max_bytes: int, timeout: typing.Optional[float] = None) -> bytes: - exc_map = {socket.timeout: ReadTimeout, socket.error: ReadError} + exc_map: ExceptionMappingType = { + socket.timeout: ReadTimeout, + socket.error: ReadError, + } with map_exceptions(exc_map): self._sock.settimeout(timeout) return self._sock.recv(max_bytes) @@ -29,7 +33,10 @@ def write(self, buffer: bytes, timeout: typing.Optional[float] = None) -> None: if not buffer: return - exc_map = {socket.timeout: WriteTimeout, socket.error: WriteError} + exc_map: ExceptionMappingType = { + socket.timeout: WriteTimeout, + socket.error: WriteError, + } with map_exceptions(exc_map): while buffer: self._sock.settimeout(timeout) @@ -45,7 +52,10 @@ def start_tls( server_hostname: typing.Optional[str] = None, timeout: typing.Optional[float] = None, ) -> NetworkStream: - exc_map = {socket.timeout: ConnectTimeout, socket.error: ConnectError} + exc_map: ExceptionMappingType = { + socket.timeout: ConnectTimeout, + socket.error: ConnectError, + } with map_exceptions(exc_map): try: self._sock.settimeout(timeout) @@ -59,7 +69,7 @@ def start_tls( def get_extra_info(self, info: str) -> typing.Any: if info == "ssl_object" and isinstance(self._sock, ssl.SSLSocket): - return self._sock._sslobj # type: ignore + return self._sock._sslobj # type: ignore[attr-defined] if info == "client_addr": return self._sock.getsockname() if info == "server_addr": @@ -81,7 +91,10 @@ def connect_tcp( ) -> NetworkStream: address = (host, port) source_address = None if local_address is None else (local_address, 0) - exc_map = {socket.timeout: ConnectTimeout, socket.error: ConnectError} + exc_map: ExceptionMappingType = { + socket.timeout: ConnectTimeout, + socket.error: ConnectError, + } with map_exceptions(exc_map): sock = socket.create_connection( address, timeout, source_address=source_address @@ -91,7 +104,10 @@ def connect_tcp( def connect_unix_socket( self, path: str, timeout: typing.Optional[float] = None ) -> NetworkStream: # pragma: nocover - exc_map = {socket.timeout: ConnectTimeout, socket.error: ConnectError} + exc_map: ExceptionMappingType = { + socket.timeout: ConnectTimeout, + socket.error: ConnectError, + } with map_exceptions(exc_map): sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.settimeout(timeout) diff --git a/httpcore/backends/trio.py b/httpcore/backends/trio.py index 1e1f47da6..05db0908a 100644 --- a/httpcore/backends/trio.py +++ b/httpcore/backends/trio.py @@ -26,7 +26,9 @@ async def read( exc_map = {trio.TooSlowError: ReadTimeout, trio.BrokenResourceError: ReadError} with map_exceptions(exc_map): with trio.fail_after(timeout_or_inf): - return await self._stream.receive_some(max_bytes=max_bytes) + return typing.cast( + bytes, await self._stream.receive_some(max_bytes=max_bytes) + ) async def write( self, buffer: bytes, timeout: typing.Optional[float] = None @@ -75,7 +77,7 @@ async def start_tls( def get_extra_info(self, info: str) -> typing.Any: if info == "ssl_object" and isinstance(self._stream, trio.SSLStream): - return self._stream._ssl_object # type: ignore + return self._stream._ssl_object if info == "client_addr": return self._get_socket_stream().socket.getsockname() if info == "server_addr": @@ -115,7 +117,9 @@ async def connect_tcp( # Trio supports 'local_address' from 0.16.1 onwards. # We only include the keyword argument if a local_address # argument has been passed. - kwargs: dict = {} if local_address is None else {"local_address": local_address} + kwargs: typing.Dict[str, str] = ( + {} if local_address is None else {"local_address": local_address} + ) with map_exceptions(exc_map): with trio.fail_after(timeout_or_inf): stream: trio.abc.Stream = await trio.open_tcp_stream( diff --git a/setup.cfg b/setup.cfg index a3d719d5c..74f6bdcdb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,11 +4,31 @@ max-line-length = 120 exclude = httpcore/_sync,tests/_sync [mypy] -disallow_untyped_defs = True -ignore_missing_imports = True -no_implicit_optional = True +python_version = 3.6 +strict = True show_error_codes = True +[mypy-httpcore._sync.interfaces] +warn_unused_ignores = False + +[mypy-certifi.*] +ignore_missing_imports = True + +[mypy-async_generator.*] +ignore_missing_imports = True + +[mypy-h2.*] +ignore_missing_imports = True + +[mypy-h11.*] +ignore_missing_imports = True + +[mypy-hpack.*] +ignore_missing_imports = True + +[mypy-trio.*] +ignore_missing_imports = True + [mypy-tests.*] disallow_untyped_defs = False check_untyped_defs = True diff --git a/tests/_async/test_connection.py b/tests/_async/test_connection.py index 7405c430e..16cacbab7 100644 --- a/tests/_async/test_connection.py +++ b/tests/_async/test_connection.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Any, Optional import hpack import hyperframe.frame @@ -124,7 +124,7 @@ async def test_request_to_incorrect_origin(): class NeedsRetryBackend(AsyncMockBackend): - def __init__(self, *args, **kwargs) -> None: + def __init__(self, *args: Any, **kwargs: Any) -> None: self._retry = 2 super().__init__(*args, **kwargs) diff --git a/tests/_async/test_connection_pool.py b/tests/_async/test_connection_pool.py index 191912f44..581c3b857 100644 --- a/tests/_async/test_connection_pool.py +++ b/tests/_async/test_connection_pool.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List, NoReturn, Optional import pytest import trio as concurrency @@ -206,7 +206,7 @@ async def connect_tcp( port: int, timeout: Optional[float] = None, local_address: Optional[str] = None, - ): + ) -> NoReturn: raise ConnectError("Could not connect") network_backend = FailedConnectBackend([]) diff --git a/tests/_async/test_http_proxy.py b/tests/_async/test_http_proxy.py index f4ade94cc..6a846262f 100644 --- a/tests/_async/test_http_proxy.py +++ b/tests/_async/test_http_proxy.py @@ -259,6 +259,6 @@ async def test_proxy_tunneling_with_auth(): # Dig into this private property as a cheap lazy way of # checking that the proxy header is set correctly. - assert proxy._proxy_headers == [ # type: ignore + assert proxy._proxy_headers == [ # type: ignore[attr-defined] (b"Proxy-Authorization", b"Basic dXNlcm5hbWU6cGFzc3dvcmQ=") ] diff --git a/tests/_sync/test_connection.py b/tests/_sync/test_connection.py index 7c5a0c164..63b8732c4 100644 --- a/tests/_sync/test_connection.py +++ b/tests/_sync/test_connection.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Any, Optional import hpack import hyperframe.frame @@ -124,7 +124,7 @@ def test_request_to_incorrect_origin(): class NeedsRetryBackend(MockBackend): - def __init__(self, *args, **kwargs) -> None: + def __init__(self, *args: Any, **kwargs: Any) -> None: self._retry = 2 super().__init__(*args, **kwargs) diff --git a/tests/_sync/test_connection_pool.py b/tests/_sync/test_connection_pool.py index 4ba3f6a37..1e2a6f477 100644 --- a/tests/_sync/test_connection_pool.py +++ b/tests/_sync/test_connection_pool.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List, NoReturn, Optional import pytest from tests import concurrency @@ -206,7 +206,7 @@ def connect_tcp( port: int, timeout: Optional[float] = None, local_address: Optional[str] = None, - ): + ) -> NoReturn: raise ConnectError("Could not connect") network_backend = FailedConnectBackend([]) diff --git a/tests/_sync/test_http_proxy.py b/tests/_sync/test_http_proxy.py index ebdbbb8fe..cdfdc4d2d 100644 --- a/tests/_sync/test_http_proxy.py +++ b/tests/_sync/test_http_proxy.py @@ -259,6 +259,6 @@ def test_proxy_tunneling_with_auth(): # Dig into this private property as a cheap lazy way of # checking that the proxy header is set correctly. - assert proxy._proxy_headers == [ # type: ignore + assert proxy._proxy_headers == [ # type: ignore[attr-defined] (b"Proxy-Authorization", b"Basic dXNlcm5hbWU6cGFzc3dvcmQ=") ] diff --git a/tests/concurrency.py b/tests/concurrency.py index b49dec6dd..e8431124a 100644 --- a/tests/concurrency.py +++ b/tests/concurrency.py @@ -10,7 +10,7 @@ """ import threading from types import TracebackType -from typing import List, Optional, Type +from typing import Any, Callable, List, Optional, Type class Nursery: @@ -31,7 +31,7 @@ def __exit__( for thread in self._threads: thread.join() - def start_soon(self, func, *args): + def start_soon(self, func: Callable[..., Any], *args: Any) -> None: thread = threading.Thread(target=func, args=args) self._threads.append(thread) diff --git a/tests/test_models.py b/tests/test_models.py index 056197547..e54704c14 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -25,7 +25,7 @@ def test_url_with_port(): def test_url_with_invalid_argument(): with pytest.raises(TypeError) as exc_info: - httpcore.URL(123) # type: ignore + httpcore.URL(123) # type: ignore[arg-type] assert str(exc_info.value) == "url must be bytes or str, but got int." @@ -60,19 +60,19 @@ def test_request(): def test_request_with_invalid_method(): with pytest.raises(TypeError) as exc_info: - httpcore.Request(123, "https://www.example.com/") # type: ignore + httpcore.Request(123, "https://www.example.com/") # type: ignore[arg-type] assert str(exc_info.value) == "method must be bytes or str, but got int." def test_request_with_invalid_url(): with pytest.raises(TypeError) as exc_info: - httpcore.Request("GET", 123) # type: ignore + httpcore.Request("GET", 123) # type: ignore[arg-type] assert str(exc_info.value) == "url must be a URL, bytes, or str, but got int." def test_request_with_invalid_headers(): with pytest.raises(TypeError) as exc_info: - httpcore.Request("GET", "https://www.example.com/", headers=123) # type: ignore + httpcore.Request("GET", "https://www.example.com/", headers=123) # type: ignore[arg-type] assert ( str(exc_info.value) == "headers must be a mapping or sequence of two-tuples, but got int."