Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 1 addition & 15 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,8 @@ ignore = W503, E203, B305, PIE801
max-line-length = 120

[mypy]
disallow_untyped_defs = True
disallow_any_generics = True
ignore_missing_imports = True
no_implicit_optional = True
show_error_codes = True
warn_unused_ignores = True
warn_unused_configs = True
disallow_subclassing_any = True
check_untyped_defs = True
disallow_untyped_decorators = True
warn_redundant_casts = True
strict_concatenate = True
disallow_incomplete_defs = True
no_implicit_reexport = True
warn_return_any = True
strict_equality = True
strict = True

[mypy-tests.*]
disallow_untyped_defs = False
Expand Down
8 changes: 4 additions & 4 deletions tests/client/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ async def test_access_content_stream_response(server):

@pytest.mark.usefixtures("async_environment")
async def test_stream_request(server):
async def hello_world():
async def hello_world() -> typing.AsyncIterator[bytes]:
yield b"Hello, "
yield b"world!"

Expand All @@ -100,7 +100,7 @@ async def hello_world():

@pytest.mark.usefixtures("async_environment")
async def test_cannot_stream_sync_request(server):
def hello_world(): # pragma: no cover
def hello_world() -> typing.Iterator[bytes]: # pragma: no cover
yield b"Hello, "
yield b"world!"

Expand Down Expand Up @@ -180,8 +180,8 @@ async def test_100_continue(server):
@pytest.mark.usefixtures("async_environment")
async def test_context_managed_transport():
class Transport(httpx.AsyncBaseTransport):
def __init__(self):
self.events = []
def __init__(self) -> None:
self.events: typing.List[str] = []

async def aclose(self):
# The base implementation of httpx.AsyncBaseTransport just
Expand Down
4 changes: 2 additions & 2 deletions tests/client/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class ResponseBodyAuth(Auth):

requires_response_body = True

def __init__(self, token):
def __init__(self, token: str) -> None:
self.token = token

def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]:
Expand Down Expand Up @@ -689,7 +689,7 @@ async def test_digest_auth_unavailable_streaming_body():
auth = DigestAuth(username="user", password="password123")
app = DigestApp()

async def streaming_body():
async def streaming_body() -> typing.AsyncIterator[bytes]:
yield b"Example request body" # pragma: no cover

async with httpx.AsyncClient(transport=ConsumeBodyTransport(app)) as client:
Expand Down
6 changes: 3 additions & 3 deletions tests/client/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def test_raw_iterator(server):


def test_cannot_stream_async_request(server):
async def hello_world(): # pragma: no cover
async def hello_world() -> typing.AsyncIterator[bytes]: # pragma: no cover
yield b"Hello, "
yield b"world!"

Expand Down Expand Up @@ -229,8 +229,8 @@ def test_merge_relative_url_with_encoded_slashes():

def test_context_managed_transport():
class Transport(httpx.BaseTransport):
def __init__(self):
self.events = []
def __init__(self) -> None:
self.events: typing.List[str] = []

def close(self):
# The base implementation of httpx.BaseTransport just
Expand Down
4 changes: 3 additions & 1 deletion tests/client/test_redirects.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import typing

import pytest

import httpx
Expand Down Expand Up @@ -351,7 +353,7 @@ def test_cannot_redirect_streaming_body():
client = httpx.Client(transport=ConsumeBodyTransport(redirects))
url = "https://example.org/redirect_body"

def streaming_body():
def streaming_body() -> typing.Iterator[bytes]:
yield b"Example request body" # pragma: no cover

with pytest.raises(httpx.StreamConsumed):
Expand Down
26 changes: 16 additions & 10 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
from httpx import URL
from tests.concurrency import sleep

if typing.TYPE_CHECKING: # pragma: no cover
from httpx._transports.asgi import _Receive, _Send

ENVIRONMENT_VARIABLES = {
"SSL_CERT_FILE",
"SSL_CERT_DIR",
Expand Down Expand Up @@ -72,7 +75,10 @@ def clean_environ():
os.environ.update(original_environ)


async def app(scope, receive, send):
_Scope = typing.Dict[str, typing.Any]


async def app(scope: _Scope, receive: "_Receive", send: "_Send") -> None:
assert scope["type"] == "http"
if scope["path"].startswith("/slow_response"):
await slow_response(scope, receive, send)
Expand All @@ -92,7 +98,7 @@ async def app(scope, receive, send):
await hello_world(scope, receive, send)


async def hello_world(scope, receive, send):
async def hello_world(scope: _Scope, receive: "_Receive", send: "_Send") -> None:
await send(
{
"type": "http.response.start",
Expand All @@ -103,7 +109,7 @@ async def hello_world(scope, receive, send):
await send({"type": "http.response.body", "body": b"Hello, world!"})


async def hello_world_json(scope, receive, send):
async def hello_world_json(scope: _Scope, receive: "_Receive", send: "_Send") -> None:
await send(
{
"type": "http.response.start",
Expand All @@ -114,7 +120,7 @@ async def hello_world_json(scope, receive, send):
await send({"type": "http.response.body", "body": b'{"Hello": "world!"}'})


async def slow_response(scope, receive, send):
async def slow_response(scope: _Scope, receive: "_Receive", send: "_Send") -> None:
await sleep(1.0)
await send(
{
Expand All @@ -126,7 +132,7 @@ async def slow_response(scope, receive, send):
await send({"type": "http.response.body", "body": b"Hello, world!"})


async def status_code(scope, receive, send):
async def status_code(scope: _Scope, receive: "_Receive", send: "_Send") -> None:
status_code = int(scope["path"].replace("/status/", ""))
await send(
{
Expand All @@ -138,7 +144,7 @@ async def status_code(scope, receive, send):
await send({"type": "http.response.body", "body": b"Hello, world!"})


async def echo_body(scope, receive, send):
async def echo_body(scope: _Scope, receive: "_Receive", send: "_Send") -> None:
body = b""
more_body = True

Expand All @@ -157,7 +163,7 @@ async def echo_body(scope, receive, send):
await send({"type": "http.response.body", "body": body})


async def echo_binary(scope, receive, send):
async def echo_binary(scope: _Scope, receive: "_Receive", send: "_Send") -> None:
body = b""
more_body = True

Expand All @@ -176,7 +182,7 @@ async def echo_binary(scope, receive, send):
await send({"type": "http.response.body", "body": body})


async def echo_headers(scope, receive, send):
async def echo_headers(scope: _Scope, receive: "_Receive", send: "_Send") -> None:
body = {
name.capitalize().decode(): value.decode()
for name, value in scope.get("headers", [])
Expand All @@ -191,7 +197,7 @@ async def echo_headers(scope, receive, send):
await send({"type": "http.response.body", "body": json.dumps(body).encode()})


async def redirect_301(scope, receive, send):
async def redirect_301(scope: _Scope, receive: "_Receive", send: "_Send") -> None:
await send(
{"type": "http.response.start", "status": 301, "headers": [[b"location", b"/"]]}
)
Expand Down Expand Up @@ -275,7 +281,7 @@ async def restart(self) -> None: # pragma: no cover
while not self.started:
await sleep(0.2)

async def watch_restarts(self): # pragma: no cover
async def watch_restarts(self) -> None: # pragma: no cover
while True:
if self.should_exit:
return
Expand Down
18 changes: 9 additions & 9 deletions tests/models/test_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ def __iter__(self):


def test_generator_with_transfer_encoding_header():
def content():
def content() -> typing.Iterator[bytes]:
yield b"test 123" # pragma: no cover

request = httpx.Request("POST", "http://example.org", content=content())
assert request.headers == {"Host": "example.org", "Transfer-Encoding": "chunked"}


def test_generator_with_content_length_header():
def content():
def content() -> typing.Iterator[bytes]:
yield b"test 123" # pragma: no cover

headers = {"Content-Length": "8"}
Expand Down Expand Up @@ -100,16 +100,16 @@ async def test_aread_and_stream_data():

def test_cannot_access_streaming_content_without_read():
# Ensure that streaming requests
def streaming_body(): # pragma: no cover
yield ""
def streaming_body() -> typing.Iterator[bytes]: # pragma: no cover
yield b""

request = httpx.Request("POST", "http://example.org", content=streaming_body())
with pytest.raises(httpx.RequestNotRead):
request.content


def test_transfer_encoding_header():
async def streaming_body(data):
async def streaming_body(data: bytes) -> typing.AsyncIterator[bytes]:
yield data # pragma: no cover

data = streaming_body(b"test 123")
Expand All @@ -125,7 +125,7 @@ def test_ignore_transfer_encoding_header_if_content_length_exists():
See https://github.com/encode/httpx/issues/1168
"""

def streaming_body(data):
def streaming_body(data: bytes) -> typing.Iterator[bytes]:
yield data # pragma: no cover

data = streaming_body(b"abcd")
Expand All @@ -151,7 +151,7 @@ def test_override_accept_encoding_header():


def test_override_content_length_header():
async def streaming_body(data):
async def streaming_body(data: bytes) -> typing.AsyncIterator[bytes]:
yield data # pragma: no cover

data = streaming_body(b"test 123")
Expand Down Expand Up @@ -194,7 +194,7 @@ def test_request_picklable():

@pytest.mark.asyncio
async def test_request_async_streaming_content_picklable():
async def streaming_body(data):
async def streaming_body(data: bytes) -> typing.AsyncIterator[bytes]:
yield data

data = streaming_body(b"test 123")
Expand All @@ -212,7 +212,7 @@ async def streaming_body(data):


def test_request_generator_content_picklable():
def content():
def content() -> typing.Iterator[bytes]:
yield b"test 123" # pragma: no cover

request = httpx.Request("POST", "http://example.org", content=content())
Expand Down
13 changes: 7 additions & 6 deletions tests/models/test_responses.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import pickle
import typing

import chardet
import pytest
Expand All @@ -14,12 +15,12 @@ def __iter__(self):
yield b"world!"


def streaming_body():
def streaming_body() -> typing.Iterator[bytes]:
yield b"Hello, "
yield b"world!"


async def async_streaming_body():
async def async_streaming_body() -> typing.AsyncIterator[bytes]:
yield b"Hello, "
yield b"world!"

Expand Down Expand Up @@ -396,7 +397,7 @@ def test_iter_raw_with_chunksize():


def test_iter_raw_doesnt_return_empty_chunks():
def streaming_body_with_empty_chunks():
def streaming_body_with_empty_chunks() -> typing.Iterator[bytes]:
yield b"Hello, "
yield b""
yield b"world!"
Expand Down Expand Up @@ -539,7 +540,7 @@ def test_iter_bytes_with_empty_response():


def test_iter_bytes_doesnt_return_empty_chunks():
def streaming_body_with_empty_chunks():
def streaming_body_with_empty_chunks() -> typing.Iterator[bytes]:
yield b"Hello, "
yield b""
yield b"world!"
Expand Down Expand Up @@ -915,15 +916,15 @@ def test_cannot_access_unset_request():


def test_generator_with_transfer_encoding_header():
def content():
def content() -> typing.Iterator[bytes]:
yield b"test 123" # pragma: no cover

response = httpx.Response(200, content=content())
assert response.headers == {"Transfer-Encoding": "chunked"}


def test_generator_with_content_length_header():
def content():
def content() -> typing.Iterator[bytes]:
yield b"test 123" # pragma: no cover

headers = {"Content-Length": "8"}
Expand Down
4 changes: 3 additions & 1 deletion tests/test_api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import typing

import pytest

import httpx
Expand All @@ -18,7 +20,7 @@ def test_post(server):


def test_post_byte_iterator(server):
def data():
def data() -> typing.Iterator[bytes]:
yield b"Hello"
yield b", "
yield b"world!"
Expand Down
Loading