-import asyncio
import typing
from .._models import Request, Response
from .base import AsyncBaseTransport, BaseTransport
+SyncHandler = typing.Callable[[Request], Response]
+AsyncHandler = typing.Callable[[Request], typing.Coroutine[None, None, Response]]
+
class MockTransport(AsyncBaseTransport, BaseTransport):
- def __init__(self, handler: typing.Callable[[Request], Response]) -> None:
+ def __init__(self, handler: typing.Union[SyncHandler, AsyncHandler]) -> None:
self.handler = handler
def handle_request(
request: Request,
) -> Response:
request.read()
- return self.handler(request)
+ response = self.handler(request)
+ if not isinstance(response, Response): # pragma: no cover
+ raise TypeError("Cannot use an async handler in a sync Client")
+ return response
async def handle_async_request(
self,
# If it is, then the `response` variable need to be awaited to actually
# return the result.
- # https://simonwillison.net/2020/Sep/2/await-me-maybe/
- if asyncio.iscoroutine(response):
+ if not isinstance(response, Response):
response = await response
return response
@pytest.mark.anyio
async def test_async_mock_transport():
- async def hello_world(request):
+ async def hello_world(request: httpx.Request) -> httpx.Response:
return httpx.Response(200, text="Hello, world!")
transport = httpx.MockTransport(hello_world)
async def handle_async_request(self, request: httpx.Request) -> httpx.Response:
assert isinstance(request.stream, httpx.AsyncByteStream)
[_ async for _ in request.stream]
- return self.handler(request)
+ return self.handler(request) # type: ignore[return-value]
@pytest.mark.anyio
def handle_request(self, request: httpx.Request) -> httpx.Response:
assert isinstance(request.stream, httpx.SyncByteStream)
[_ for _ in request.stream]
- return self.handler(request)
+ return self.handler(request) # type: ignore[return-value]
def test_cannot_redirect_streaming_body():