diff --git a/django-stubs/contrib/admin/decorators.pyi b/django-stubs/contrib/admin/decorators.pyi index e26b265..3fdfae2 100644 --- a/django-stubs/contrib/admin/decorators.pyi +++ b/django-stubs/contrib/admin/decorators.pyi @@ -1,5 +1,6 @@ from typing import Any, Callable, Optional, Type +from django.contrib.admin.sites import AdminSite from django.db.models.base import Model -def register(*models: Type[Model], site: Optional[Any] = ...) -> Callable: ... +def register(*models: Type[Model], site: Optional[AdminSite] = ...) -> Callable: ... diff --git a/django-stubs/contrib/admin/sites.pyi b/django-stubs/contrib/admin/sites.pyi index 2227f87..607f766 100644 --- a/django-stubs/contrib/admin/sites.pyi +++ b/django-stubs/contrib/admin/sites.pyi @@ -1,36 +1,51 @@ +import sys from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Type, Union +from django.apps.config import AppConfig from django.contrib.admin.options import ModelAdmin +from django.contrib.auth.forms import AuthenticationForm from django.core.handlers.wsgi import WSGIRequest from django.db.models.base import Model +from django.db.models.query import QuerySet from django.http.response import HttpResponse from django.template.response import TemplateResponse from django.urls.resolvers import URLResolver from django.utils.functional import LazyObject +from django.core.checks import CheckMessage -from django.apps.config import AppConfig +if sys.version_info >= (3, 9): + from weakref import WeakSet -all_sites: Any + all_sites: WeakSet[AdminSite] +else: + from typing import MutableSet + + all_sites: MutableSet[AdminSite] + +_ActionCallback = Callable[[ModelAdmin, WSGIRequest, QuerySet], Optional[TemplateResponse]] class AlreadyRegistered(Exception): ... class NotRegistered(Exception): ... class AdminSite: - site_title: Any = ... - site_header: Any = ... - index_title: Any = ... + site_title: str = ... + site_header: str = ... + index_title: str = ... site_url: str = ... - login_form: Any = ... - index_template: Any = ... - app_index_template: Any = ... - login_template: Any = ... - logout_template: Any = ... - password_change_template: Any = ... - password_change_done_template: Any = ... + login_form: Optional[AuthenticationForm] = ... + index_template: Optional[str] = ... + app_index_template: Optional[str] = ... + login_template: Optional[str] = ... + logout_template: Optional[str] = ... + password_change_template: Optional[str] = ... + password_change_done_template: Optional[str] = ... name: str = ... + _empty_value_display: str = ... _registry: Dict[Type[Model], ModelAdmin] + _global_actions: Dict[str, _ActionCallback] + _actions: Dict[str, _ActionCallback] def __init__(self, name: str = ...) -> None: ... - def check(self, app_configs: Optional[Iterable[AppConfig]]) -> List[Any]: ... + def check(self, app_configs: Optional[Iterable[AppConfig]]) -> List[CheckMessage]: ... def register( self, model_or_iterable: Union[Type[Model], Iterable[Type[Model]]], @@ -39,28 +54,28 @@ class AdminSite: ) -> None: ... def unregister(self, model_or_iterable: Union[Type[Model], Iterable[Type[Model]]]) -> None: ... def is_registered(self, model: Type[Model]) -> bool: ... - def add_action(self, action: Callable, name: Optional[str] = ...) -> None: ... + def add_action(self, action: _ActionCallback, name: Optional[str] = ...) -> None: ... def disable_action(self, name: str) -> None: ... def get_action(self, name: str) -> Callable: ... @property - def actions(self): ... + def actions(self) -> Iterable[Tuple[str, _ActionCallback]]: ... @property - def empty_value_display(self): ... + def empty_value_display(self) -> str: ... @empty_value_display.setter - def empty_value_display(self, empty_value_display: Any) -> None: ... + def empty_value_display(self, empty_value_display: str) -> None: ... def has_permission(self, request: WSGIRequest) -> bool: ... def admin_view(self, view: Callable, cacheable: bool = ...) -> Callable: ... def get_urls(self) -> List[URLResolver]: ... @property def urls(self) -> Tuple[List[URLResolver], str, str]: ... - def each_context(self, request: Any): ... + def each_context(self, request: WSGIRequest) -> Dict[str, Any]: ... def password_change( self, request: WSGIRequest, extra_context: Optional[Dict[str, Any]] = ... ) -> TemplateResponse: ... def password_change_done( self, request: WSGIRequest, extra_context: Optional[Dict[str, Any]] = ... ) -> TemplateResponse: ... - def i18n_javascript(self, request: WSGIRequest, extra_context: Optional[Dict[Any, Any]] = ...) -> HttpResponse: ... + def i18n_javascript(self, request: WSGIRequest, extra_context: Optional[Dict[str, Any]] = ...) -> HttpResponse: ... def logout(self, request: WSGIRequest, extra_context: Optional[Dict[str, Any]] = ...) -> TemplateResponse: ... def login(self, request: WSGIRequest, extra_context: Optional[Dict[str, Any]] = ...) -> HttpResponse: ... def _build_app_dict(self, request: WSGIRequest, label: Optional[str] = ...) -> Dict[str, Any]: ... @@ -72,4 +87,4 @@ class AdminSite: class DefaultAdminSite(LazyObject): ... -site: Any +site: AdminSite diff --git a/scripts/enabled_test_modules.py b/scripts/enabled_test_modules.py index c4414f1..7c049b8 100644 --- a/scripts/enabled_test_modules.py +++ b/scripts/enabled_test_modules.py @@ -113,9 +113,15 @@ IGNORED_ERRORS = { 'error: "HttpResponse" has no attribute "context_data"', ], "admin_checks": ['Argument 1 to "append" of "list" has incompatible type "str"; expected "CheckMessage"'], + "admin_default_site": [ + 'Incompatible types in assignment (expression has type "DefaultAdminSite", variable has type "AdminSite")' + ], "admin_inlines": [ 'error: "HttpResponse" has no attribute "rendered_content"', ], + "admin_registration": [ + 'Argument "site" to "register" has incompatible type "Type[Traveler]"; expected "Optional[AdminSite]"', + ], "admin_utils": [ '"Article" has no attribute "non_field"', ],