diff --git a/django-stubs/contrib/auth/decorators.pyi b/django-stubs/contrib/auth/decorators.pyi index ce8b161ab..fd5b0320b 100644 --- a/django-stubs/contrib/auth/decorators.pyi +++ b/django-stubs/contrib/auth/decorators.pyi @@ -1,13 +1,15 @@ from typing import Callable, Iterable, Optional, TypeVar, Union, overload from django.contrib.auth import REDIRECT_FIELD_NAME as REDIRECT_FIELD_NAME # noqa: F401 -from django.contrib.auth.models import AbstractUser +from django.contrib.auth.models import AbstractBaseUser, AnonymousUser from django.http.response import HttpResponseBase _VIEW = TypeVar("_VIEW", bound=Callable[..., HttpResponseBase]) def user_passes_test( - test_func: Callable[[AbstractUser], bool], login_url: Optional[str] = ..., redirect_field_name: str = ... + test_func: Callable[[Union[AbstractBaseUser, AnonymousUser]], bool], + login_url: Optional[str] = ..., + redirect_field_name: str = ..., ) -> Callable[[_VIEW], _VIEW]: ... # There are two ways of calling @login_required: @with(arguments) and @bare diff --git a/django-stubs/contrib/staticfiles/handlers.pyi b/django-stubs/contrib/staticfiles/handlers.pyi index b6402c38b..370098132 100644 --- a/django-stubs/contrib/staticfiles/handlers.pyi +++ b/django-stubs/contrib/staticfiles/handlers.pyi @@ -1,11 +1,11 @@ from typing import Any, Awaitable, Callable, Dict, Mapping, Sequence, Tuple from urllib.parse import ParseResult -from django.core.handlers.asgi import ASGIHandler, ASGIRequest +from django.core.handlers.asgi import ASGIHandler from django.core.handlers.base import BaseHandler -from django.core.handlers.wsgi import WSGIHandler, WSGIRequest +from django.core.handlers.wsgi import WSGIHandler from django.http import HttpRequest -from django.http.response import HttpResponseBase +from django.http.response import FileResponse, HttpResponseBase class StaticFilesHandlerMixin: handles_files: bool = ... @@ -15,7 +15,7 @@ class StaticFilesHandlerMixin: def get_base_url(self) -> str: ... def _should_handle(self, path: str) -> bool: ... def file_path(self, url: str) -> str: ... - def serve(self, request: HttpRequest) -> HttpResponseBase: ... + def serve(self, request: HttpRequest) -> FileResponse: ... def get_response(self, request: HttpRequest) -> HttpResponseBase: ... async def get_response_async(self, request: HttpRequest) -> HttpResponseBase: ... diff --git a/django-stubs/contrib/staticfiles/views.pyi b/django-stubs/contrib/staticfiles/views.pyi index 59767a556..0f5fbb02a 100644 --- a/django-stubs/contrib/staticfiles/views.pyi +++ b/django-stubs/contrib/staticfiles/views.pyi @@ -1,6 +1,6 @@ from typing import Any from django.http.request import HttpRequest -from django.http.response import HttpResponseBase +from django.http.response import FileResponse -def serve(request: HttpRequest, path: str, insecure: bool = ..., **kwargs: Any) -> HttpResponseBase: ... +def serve(request: HttpRequest, path: str, insecure: bool = ..., **kwargs: Any) -> FileResponse: ... diff --git a/django-stubs/db/models/query.pyi b/django-stubs/db/models/query.pyi index c596e0680..2ad08b1b5 100644 --- a/django-stubs/db/models/query.pyi +++ b/django-stubs/db/models/query.pyi @@ -115,9 +115,9 @@ class _QuerySet(Generic[_T, _Row], Collection[_Row], Reversible[_Row], Sized): def extra( self, select: Optional[Dict[str, Any]] = ..., - where: Optional[List[str]] = ..., - params: Optional[List[Any]] = ..., - tables: Optional[List[str]] = ..., + where: Optional[Sequence[str]] = ..., + params: Optional[Sequence[Any]] = ..., + tables: Optional[Sequence[str]] = ..., order_by: Optional[Sequence[str]] = ..., select_params: Optional[Sequence[Any]] = ..., ) -> _QuerySet[Any, Any]: ... diff --git a/django-stubs/template/backends/jinja2.pyi b/django-stubs/template/backends/jinja2.pyi index 623bd409a..32b52a27a 100644 --- a/django-stubs/template/backends/jinja2.pyi +++ b/django-stubs/template/backends/jinja2.pyi @@ -5,6 +5,7 @@ from django.template.exceptions import TemplateSyntaxError from .base import BaseEngine class Jinja2(BaseEngine): + env: Any = ... context_processors: List[str] = ... def __init__(self, params: Dict[str, Any]) -> None: ... @property diff --git a/django-stubs/template/loaders/filesystem.pyi b/django-stubs/template/loaders/filesystem.pyi index bed0faac9..8931c630d 100644 --- a/django-stubs/template/loaders/filesystem.pyi +++ b/django-stubs/template/loaders/filesystem.pyi @@ -1,4 +1,5 @@ -from typing import Iterator, List, Optional +from pathlib import Path +from typing import Iterator, List, Optional, Union from django.template.base import Origin from django.template.engine import Engine @@ -6,8 +7,8 @@ from django.template.engine import Engine from .base import Loader as BaseLoader class Loader(BaseLoader): - dirs: Optional[List[str]] = ... - def __init__(self, engine: Engine, dirs: Optional[List[str]] = ...) -> None: ... - def get_dirs(self) -> List[str]: ... + dirs: Optional[List[Union[str, Path]]] = ... + def __init__(self, engine: Engine, dirs: Optional[List[Union[str, Path]]] = ...) -> None: ... + def get_dirs(self) -> List[Union[str, Path]]: ... def get_contents(self, origin: Origin) -> str: ... def get_template_sources(self, template_name: str) -> Iterator[Origin]: ... diff --git a/django-stubs/test/testcases.pyi b/django-stubs/test/testcases.pyi index 5b8c4479b..40b0199eb 100644 --- a/django-stubs/test/testcases.pyi +++ b/django-stubs/test/testcases.pyi @@ -26,7 +26,7 @@ from django.db.backends.base.base import BaseDatabaseWrapper from django.db.models.base import Model from django.db.models.query import QuerySet, RawQuerySet from django.forms.fields import EmailField -from django.http.response import HttpResponse, HttpResponseBase +from django.http.response import FileResponse, HttpResponseBase from django.template.base import Template from django.test.client import AsyncClient, Client from django.test.html import Element @@ -202,7 +202,7 @@ class FSFilesHandler(WSGIHandler): base_url: Any = ... def __init__(self, application: Any) -> None: ... def file_path(self, url: Any): ... - def serve(self, request: Any): ... + def serve(self, request: Any) -> FileResponse: ... class _StaticFilesHandler(FSFilesHandler): def get_base_dir(self): ... diff --git a/django-stubs/views/static.pyi b/django-stubs/views/static.pyi index a1b9c896c..80d194394 100644 --- a/django-stubs/views/static.pyi +++ b/django-stubs/views/static.pyi @@ -1,11 +1,11 @@ from typing import Any, Optional +from django.http import FileResponse from django.http.request import HttpRequest -from django.http.response import HttpResponseBase def serve( request: HttpRequest, path: str, document_root: Optional[str] = ..., show_indexes: bool = ... -) -> HttpResponseBase: ... +) -> FileResponse: ... DEFAULT_DIRECTORY_INDEX_TEMPLATE: str template_translatable: Any diff --git a/tests/typecheck/contrib/auth/test_decorators.yml b/tests/typecheck/contrib/auth/test_decorators.yml index 18ac1d3a1..a43504bbe 100644 --- a/tests/typecheck/contrib/auth/test_decorators.yml +++ b/tests/typecheck/contrib/auth/test_decorators.yml @@ -27,14 +27,14 @@ - case: user_passes_test main: | from django.contrib.auth.decorators import user_passes_test - @user_passes_test(lambda u: u.username.startswith('super')) + @user_passes_test(lambda u: u.get_username().startswith('super')) def view_func(request): ... reveal_type(view_func) # N: Revealed type is "def (request: Any) -> Any" - case: user_passes_test_bare_is_error main: | from django.http.response import HttpResponse from django.contrib.auth.decorators import user_passes_test - @user_passes_test # E: Argument 1 to "user_passes_test" has incompatible type "Callable[[Any], HttpResponse]"; expected "Callable[[AbstractUser], bool]" + @user_passes_test # E: Argument 1 to "user_passes_test" has incompatible type "Callable[[Any], HttpResponse]"; expected "Callable[[Union[AbstractBaseUser, AnonymousUser]], bool]" def view_func(request) -> HttpResponse: ... - case: permission_required main: | diff --git a/tests/typecheck/managers/querysets/test_from_queryset.yml b/tests/typecheck/managers/querysets/test_from_queryset.yml index 2a2ae5db4..aadd114e7 100644 --- a/tests/typecheck/managers/querysets/test_from_queryset.yml +++ b/tests/typecheck/managers/querysets/test_from_queryset.yml @@ -407,7 +407,7 @@ reveal_type(MyModel.objects.difference) # N: Revealed type is "def (*other_qs: Any) -> myapp.models.MyQuerySet[myapp.models.MyModel]" reveal_type(MyModel.objects.distinct) # N: Revealed type is "def (*field_names: Any) -> myapp.models.MyQuerySet[myapp.models.MyModel]" reveal_type(MyModel.objects.exclude) # N: Revealed type is "def (*args: Any, **kwargs: Any) -> myapp.models.MyQuerySet[myapp.models.MyModel]" - reveal_type(MyModel.objects.extra) # N: Revealed type is "def (select: Union[builtins.dict[builtins.str, Any], None] =, where: Union[builtins.list[builtins.str], None] =, params: Union[builtins.list[Any], None] =, tables: Union[builtins.list[builtins.str], None] =, order_by: Union[typing.Sequence[builtins.str], None] =, select_params: Union[typing.Sequence[Any], None] =) -> myapp.models.MyQuerySet[myapp.models.MyModel]" + reveal_type(MyModel.objects.extra) # N: Revealed type is "def (select: Union[builtins.dict[builtins.str, Any], None] =, where: Union[typing.Sequence[builtins.str], None] =, params: Union[typing.Sequence[Any], None] =, tables: Union[typing.Sequence[builtins.str], None] =, order_by: Union[typing.Sequence[builtins.str], None] =, select_params: Union[typing.Sequence[Any], None] =) -> myapp.models.MyQuerySet[myapp.models.MyModel]" reveal_type(MyModel.objects.filter) # N: Revealed type is "def (*args: Any, **kwargs: Any) -> myapp.models.MyQuerySet[myapp.models.MyModel]" reveal_type(MyModel.objects.intersection) # N: Revealed type is "def (*other_qs: Any) -> myapp.models.MyQuerySet[myapp.models.MyModel]" reveal_type(MyModel.objects.none) # N: Revealed type is "def () -> myapp.models.MyQuerySet[myapp.models.MyModel]"