diff --git a/django-stubs/test/client.pyi b/django-stubs/test/client.pyi index 320c26baf..07d52e72c 100644 --- a/django-stubs/test/client.pyi +++ b/django-stubs/test/client.pyi @@ -1,9 +1,10 @@ -from collections.abc import Mapping -from io import BytesIO +from collections.abc import AsyncGenerator, Callable, Generator, Iterable, Mapping +from http import HTTPStatus +from io import BytesIO, IOBase from json import JSONEncoder from re import Pattern from types import TracebackType -from typing import Any, TypeAlias +from typing import Any, TypeAlias, TypeVar from django.contrib.auth.base_user import AbstractBaseUser from django.contrib.sessions.backends.base import SessionBase @@ -14,22 +15,33 @@ from django.http.request import HttpRequest from django.http.response import HttpResponse, HttpResponseBase from django.utils.functional import _StrOrPromise -BOUNDARY: str = ... -MULTIPART_CONTENT: str = ... -CONTENT_TYPE_RE: Pattern[str] = ... -JSON_CONTENT_TYPE_RE: Pattern[str] = ... +_T = TypeVar("_T") + +BOUNDARY: str +MULTIPART_CONTENT: str +CONTENT_TYPE_RE: Pattern[str] +JSON_CONTENT_TYPE_RE: Pattern[str] +REDIRECT_STATUS_CODES: frozenset[HTTPStatus] class RedirectCycleError(Exception): - last_response: HttpResponseBase = ... - redirect_chain: list[tuple[str, int]] = ... + last_response: HttpResponseBase + redirect_chain: list[tuple[str, int]] def __init__(self, message: str, last_response: HttpResponseBase) -> None: ... -class FakePayload: - read_started: bool = ... +class FakePayload(IOBase): + read_started: bool def __init__(self, content: bytes | str | None = ...) -> None: ... def __len__(self) -> int: ... - def read(self, num_bytes: int = ...) -> bytes: ... - def write(self, content: bytes | str) -> None: ... + def read(self, size: int = ..., /) -> bytes: ... + def readline(self, size: int | None = ..., /) -> bytes: ... + def write(self, b: bytes | str, /) -> None: ... + +def closing_iterator_wrapper(iterable: Iterable[_T], close: Callable) -> Generator[_T]: ... +async def aclosing_iterator_wrapper(iterable: Iterable[_T], close: Callable) -> AsyncGenerator[_T]: ... + +_Response = TypeVar("_Response", bound=HttpResponse) + +def conditional_content_removal(request: HttpRequest, response: _Response) -> _Response: ... class ClientHandler(BaseHandler): enforce_csrf_checks: bool = ... @@ -65,8 +77,8 @@ class RequestFactory: data: _RequestData = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: object, ) -> WSGIRequest: ... def post( @@ -76,8 +88,8 @@ class RequestFactory: content_type: str = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: object, ) -> WSGIRequest: ... def head( @@ -86,8 +98,8 @@ class RequestFactory: data: _RequestData = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: object, ) -> WSGIRequest: ... def trace( @@ -95,8 +107,8 @@ class RequestFactory: path: _StrOrPromise, secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: object, ) -> WSGIRequest: ... def options( @@ -106,8 +118,8 @@ class RequestFactory: content_type: str = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: object, ) -> WSGIRequest: ... def put( @@ -117,8 +129,8 @@ class RequestFactory: content_type: str = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: object, ) -> WSGIRequest: ... def patch( @@ -128,8 +140,8 @@ class RequestFactory: content_type: str = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: object, ) -> WSGIRequest: ... def delete( @@ -139,8 +151,8 @@ class RequestFactory: content_type: str = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: object, ) -> WSGIRequest: ... def generic( @@ -151,23 +163,38 @@ class RequestFactory: content_type: str | None = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: object, ) -> WSGIRequest: ... -class Client(RequestFactory): +class AsyncRequestFactory(RequestFactory): ... + +class ClientMixin: + def store_exc_info(self, **kwargs: Any) -> None: ... + def check_exception(self, response: HttpResponse) -> None: ... + @property + def session(self) -> SessionBase: ... + async def asession(self) -> SessionBase: ... + def login(self, **credentials: Any) -> bool: ... + async def alogin(self, **credentials: Any) -> bool: ... + def force_login(self, user: AbstractBaseUser, backend: str | None = ...) -> None: ... + async def aforce_login(self, user: AbstractBaseUser, backend: str | None = ...) -> None: ... + def logout(self) -> None: ... + async def alogout(self) -> None: ... + +class Client(ClientMixin, RequestFactory): handler: ClientHandler raise_request_exception: bool exc_info: tuple[type[BaseException], BaseException, TracebackType] | None - headers: dict[str, Any] + headers: dict[str, Any] | None def __init__( self, enforce_csrf_checks: bool = ..., raise_request_exception: bool = ..., *, - json_encoder: type[JSONEncoder] = ..., headers: Mapping[str, Any] | None = ..., + query_params: Mapping[str, Any] | None = ..., **defaults: Any, ) -> None: ... # Silence type warnings, since this class overrides arguments and return types in an unsafe manner. @@ -179,8 +206,8 @@ class Client(RequestFactory): follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... def post( # type: ignore [override] @@ -191,8 +218,8 @@ class Client(RequestFactory): follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... def head( # type: ignore [override] @@ -202,22 +229,23 @@ class Client(RequestFactory): follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... - def trace( # type: ignore [override] + def options( # type: ignore [override] self, path: _StrOrPromise, data: _RequestData = ..., + content_type: str = ..., follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... - def options( # type: ignore [override] + def put( # type: ignore [override] self, path: _StrOrPromise, data: _RequestData = ..., @@ -225,11 +253,11 @@ class Client(RequestFactory): follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... - def put( # type: ignore [override] + def patch( # type: ignore [override] self, path: _StrOrPromise, data: _RequestData = ..., @@ -237,11 +265,11 @@ class Client(RequestFactory): follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... - def patch( # type: ignore [override] + def delete( # type: ignore [override] self, path: _StrOrPromise, data: _RequestData = ..., @@ -249,43 +277,35 @@ class Client(RequestFactory): follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... - def delete( # type: ignore [override] + def trace( # type: ignore [override] self, path: _StrOrPromise, data: _RequestData = ..., - content_type: str = ..., follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... - def store_exc_info(self, **kwargs: Any) -> None: ... - @property - def session(self) -> SessionBase: ... - def login(self, **credentials: Any) -> bool: ... - def force_login(self, user: AbstractBaseUser, backend: str | None = ...) -> None: ... - def logout(self) -> None: ... - -class AsyncRequestFactory(RequestFactory): ... -class AsyncClient(AsyncRequestFactory): +class AsyncClient(ClientMixin, AsyncRequestFactory): handler: AsyncClientHandler raise_request_exception: bool exc_info: tuple[type[BaseException], BaseException, TracebackType] | None - headers: dict[str, Any] + extra: dict[str, Any] | None = ... + headers: dict[str, Any] | None = ... def __init__( self, enforce_csrf_checks: bool = ..., raise_request_exception: bool = ..., *, - json_encoder: type[JSONEncoder] = ..., headers: Mapping[str, Any] | None = ..., + query_params: Mapping[str, Any] | None = ..., **defaults: Any, ) -> None: ... # Silence type warnings, since this class overrides arguments and return types in an unsafe manner. @@ -297,8 +317,8 @@ class AsyncClient(AsyncRequestFactory): follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... async def post( # type: ignore [override] @@ -309,8 +329,8 @@ class AsyncClient(AsyncRequestFactory): follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... async def head( # type: ignore [override] @@ -320,22 +340,23 @@ class AsyncClient(AsyncRequestFactory): follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... - async def trace( # type: ignore [override] + async def options( # type: ignore [override] self, path: _StrOrPromise, data: _RequestData = ..., + content_type: str = ..., follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... - async def options( # type: ignore [override] + async def put( # type: ignore [override] self, path: _StrOrPromise, data: _RequestData = ..., @@ -343,11 +364,11 @@ class AsyncClient(AsyncRequestFactory): follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... - async def put( # type: ignore [override] + async def patch( # type: ignore [override] self, path: _StrOrPromise, data: _RequestData = ..., @@ -355,11 +376,11 @@ class AsyncClient(AsyncRequestFactory): follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... - async def patch( # type: ignore [override] + async def delete( # type: ignore [override] self, path: _StrOrPromise, data: _RequestData = ..., @@ -367,27 +388,18 @@ class AsyncClient(AsyncRequestFactory): follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... - async def delete( # type: ignore [override] + async def trace( # type: ignore [override] self, path: _StrOrPromise, data: _RequestData = ..., - content_type: str = ..., follow: bool = ..., secure: bool = ..., *, - QUERY_STRING: str = ..., headers: Mapping[str, Any] | None = ..., + query_params: str | None = ..., **extra: str, ) -> HttpResponse: ... - def store_exc_info(self, **kwargs: Any) -> None: ... - @property - def session(self) -> SessionBase: ... - def login(self, **credentials: Any) -> bool: ... - def force_login(self, user: AbstractBaseUser, backend: str | None = ...) -> None: ... - def logout(self) -> None: ... - -def conditional_content_removal(request: HttpRequest, response: HttpResponseBase) -> HttpResponse: ...