From d72b80757d0701d9d503f08605b96a5367704353 Mon Sep 17 00:00:00 2001 From: Jon Janzen Date: Wed, 27 Sep 2023 21:52:02 -0700 Subject: [PATCH 1/6] Asyncify auth funcs + methods in test Client https://github.com/django/django/commit/5e98959d9242c57a55c65847758781f82d386fa4 --- django-stubs/contrib/auth/__init__.pyi | 7 +++++++ django-stubs/test/client.pyi | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/django-stubs/contrib/auth/__init__.pyi b/django-stubs/contrib/auth/__init__.pyi index 0d24bb9b0..cd37c03ad 100644 --- a/django-stubs/contrib/auth/__init__.pyi +++ b/django-stubs/contrib/auth/__init__.pyi @@ -19,13 +19,20 @@ REDIRECT_FIELD_NAME: str def load_backend(path: str) -> ModelBackend: ... def get_backends() -> list[ModelBackend]: ... def authenticate(request: HttpRequest | None = ..., **credentials: Any) -> AbstractBaseUser | None: ... +async def aauthenticate(request: HttpRequest | None = ..., **credentials: Any) -> AbstractBaseUser | None: ... def login( request: HttpRequest, user: AbstractBaseUser | None, backend: type[ModelBackend] | str | None = ... ) -> None: ... +async def alogin( + request: HttpRequest, user: AbstractBaseUser | None, backend: type[ModelBackend] | str | None = ... +) -> None: ... def logout(request: HttpRequest) -> None: ... +async def alogout(request: HttpRequest) -> None: ... def get_user_model() -> type[AbstractBaseUser]: ... def get_user(request: HttpRequest | Client) -> AbstractBaseUser | AnonymousUser: ... +async def aget_user(request: HttpRequest | Client) -> AbstractBaseUser | AnonymousUser: ... def get_permission_codename(action: str, opts: Options) -> str: ... def update_session_auth_hash(request: HttpRequest, user: AbstractBaseUser) -> None: ... +async def aupdate_session_auth_hash(request: HttpRequest, user: AbstractBaseUser) -> None: ... default_app_config: str diff --git a/django-stubs/test/client.pyi b/django-stubs/test/client.pyi index 43a4a1e97..4ec49b6ae 100644 --- a/django-stubs/test/client.pyi +++ b/django-stubs/test/client.pyi @@ -179,9 +179,13 @@ class ClientMixin: def check_exception(self, response: HttpResponseBase) -> NoReturn: ... @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[_MonkeyPatchedWSGIResponse]): handler: ClientHandler From 33e6a35af88b0690b1d5652a4a536b0912438b4e Mon Sep 17 00:00:00 2001 From: Jon Janzen Date: Wed, 27 Sep 2023 21:55:24 -0700 Subject: [PATCH 2/6] Fixed #34565 -- Added support for async checking of user passwords. https://github.com/django/django/commit/674c23999cb6982a9d447fedec4d72e135201fee --- django-stubs/contrib/auth/base_user.pyi | 1 + django-stubs/contrib/auth/hashers.pyi | 3 +++ 2 files changed, 4 insertions(+) diff --git a/django-stubs/contrib/auth/base_user.pyi b/django-stubs/contrib/auth/base_user.pyi index 22aa17e81..f5af40aba 100644 --- a/django-stubs/contrib/auth/base_user.pyi +++ b/django-stubs/contrib/auth/base_user.pyi @@ -30,6 +30,7 @@ class AbstractBaseUser(models.Model): def is_authenticated(self) -> Literal[True]: ... def set_password(self, raw_password: str | None) -> None: ... def check_password(self, raw_password: str) -> bool: ... + async def acheck_password(self, raw_password: str) -> bool: ... def set_unusable_password(self) -> None: ... def has_usable_password(self) -> bool: ... def get_session_auth_hash(self) -> str: ... diff --git a/django-stubs/contrib/auth/hashers.pyi b/django-stubs/contrib/auth/hashers.pyi index 3942d6f5b..7ea9aa9b0 100644 --- a/django-stubs/contrib/auth/hashers.pyi +++ b/django-stubs/contrib/auth/hashers.pyi @@ -6,6 +6,9 @@ UNUSABLE_PASSWORD_SUFFIX_LENGTH: int def is_password_usable(encoded: str | None) -> bool: ... def check_password(password: str | None, encoded: str, setter: Callable | None = ..., preferred: str = ...) -> bool: ... +async def acheck_password( + password: str | None, encoded: str, setter: Callable | None = ..., preferred: str = ... +) -> bool: ... def make_password(password: str | None, salt: str | None = ..., hasher: str | BasePasswordHasher = ...) -> str: ... def get_hashers() -> list[BasePasswordHasher]: ... def get_hashers_by_algorithm() -> dict[str, BasePasswordHasher]: ... From d61bab220c227e0f957e4883be16d629d67f23ba Mon Sep 17 00:00:00 2001 From: Jon Janzen Date: Wed, 27 Sep 2023 21:57:20 -0700 Subject: [PATCH 3/6] Fixed #34714 -- Added aget_object_or_404()/aget_list_or_404() shortcuts. https://github.com/django/django/commit/b9473cac65190822e7c94f695f1f7b4d5b49502a --- django-stubs/shortcuts.pyi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/django-stubs/shortcuts.pyi b/django-stubs/shortcuts.pyi index 376fbac75..1e352e86b 100644 --- a/django-stubs/shortcuts.pyi +++ b/django-stubs/shortcuts.pyi @@ -34,5 +34,7 @@ def redirect( _T = TypeVar("_T", bound=Model) def get_object_or_404(klass: type[_T] | Manager[_T] | QuerySet[_T], *args: Any, **kwargs: Any) -> _T: ... +async def aget_object_or_404(klass: type[_T] | Manager[_T] | QuerySet[_T], *args: Any, **kwargs: Any) -> _T: ... def get_list_or_404(klass: type[_T] | Manager[_T] | QuerySet[_T], *args: Any, **kwargs: Any) -> list[_T]: ... +async def aget_list_or_404(klass: type[_T] | Manager[_T] | QuerySet[_T], *args: Any, **kwargs: Any) -> list[_T]: ... def resolve_url(to: Callable | Model | str, *args: Any, **kwargs: Any) -> str: ... From 43f47f86580d3104f3349e48781dae05c4e08b23 Mon Sep 17 00:00:00 2001 From: Jon Janzen Date: Wed, 27 Sep 2023 21:58:43 -0700 Subject: [PATCH 4/6] Fixed #34331 -- Added QuerySet.aiterator() support for prefetch_related(). https://github.com/django/django/commit/fff14736f1cc594f79ea0e2656b8375d837b7aca --- django-stubs/db/models/query.pyi | 1 + 1 file changed, 1 insertion(+) diff --git a/django-stubs/db/models/query.pyi b/django-stubs/db/models/query.pyi index 152de5bc0..43d237a39 100644 --- a/django-stubs/db/models/query.pyi +++ b/django-stubs/db/models/query.pyi @@ -231,6 +231,7 @@ class Prefetch: def get_current_queryset(self, level: int) -> QuerySet | None: ... def prefetch_related_objects(model_instances: Iterable[_T], *related_lookups: str | Prefetch) -> None: ... +async def aprefetch_related_objects(model_instances: Iterable[_T], *related_lookups: str | Prefetch) -> None: ... def get_prefetcher(instance: Model, through_attr: str, to_attr: str) -> tuple[Any, Any, bool, bool]: ... class InstanceCheckMeta(type): ... From 8a4f399e0655c0bd8c6c1052b83b1f08e2d12235 Mon Sep 17 00:00:00 2001 From: Marti Raudsepp Date: Fri, 8 Dec 2023 13:45:33 +0200 Subject: [PATCH 5/6] Update stubtest ignores --- scripts/stubtest/allowlist.txt | 4 ++++ scripts/stubtest/allowlist_todo_django50.txt | 15 --------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/scripts/stubtest/allowlist.txt b/scripts/stubtest/allowlist.txt index 358e9a653..1daf8b560 100644 --- a/scripts/stubtest/allowlist.txt +++ b/scripts/stubtest/allowlist.txt @@ -395,3 +395,7 @@ django.urls.resolvers.URLPattern.lookup_str django.urls.resolvers.URLResolver.url_patterns django.urls.resolvers.URLResolver.urlconf_module django.utils.connection.BaseConnectionHandler.settings + +# Module-scoped loop variables that shouldn't be exported +django.contrib.admindocs.utils.name +django.contrib.admindocs.utils.urlbase diff --git a/scripts/stubtest/allowlist_todo_django50.txt b/scripts/stubtest/allowlist_todo_django50.txt index 5b9c0b7c5..da17fabd3 100644 --- a/scripts/stubtest/allowlist_todo_django50.txt +++ b/scripts/stubtest/allowlist_todo_django50.txt @@ -40,18 +40,10 @@ django.contrib.admin.sites.AdminSite.get_model_admin django.contrib.admin.utils.build_q_object_from_lookup_parameters django.contrib.admin.utils.get_last_value_from_parameters django.contrib.admin.views.main.ChangeList.get_queryset -django.contrib.auth.aauthenticate django.contrib.auth.admin.UserAdmin.lookup_allowed -django.contrib.auth.aget_user -django.contrib.auth.alogin -django.contrib.auth.alogout -django.contrib.auth.aupdate_session_auth_hash -django.contrib.auth.base_user.AbstractBaseUser.acheck_password django.contrib.auth.hashers.CryptPasswordHasher -django.contrib.auth.hashers.acheck_password django.contrib.auth.hashers.verify_password django.contrib.auth.middleware.auser -django.contrib.auth.models.AbstractBaseUser.acheck_password django.contrib.contenttypes.fields.GenericForeignKey.get_content_type django.contrib.contenttypes.fields.GenericForeignKey.get_prefetch_querysets django.contrib.contenttypes.prefetch @@ -242,7 +234,6 @@ django.db.models.lookups.Lookup.allowed_default django.db.models.query.Prefetch.get_current_querysets django.db.models.query.QuerySet.aupdate_or_create django.db.models.query.QuerySet.update_or_create -django.db.models.query.aprefetch_related_objects django.db.models.query_utils.FilteredRelation.relabeled_clone django.db.models.query_utils.FilteredRelation.resolve_expression django.db.models.query_utils.Q.identity @@ -278,8 +269,6 @@ django.forms.renderers.BaseRenderer.field_template_name django.forms.renderers.Jinja2DivFormRenderer.__init__ django.forms.utils.RenderableFieldMixin django.forms.widgets.ClearableFileInput.checked -django.shortcuts.aget_list_or_404 -django.shortcuts.aget_object_or_404 django.template.Template.__iter__ django.template.autoreload django.template.base.Template.__iter__ @@ -300,10 +289,6 @@ django.test.client.AsyncClient.patch django.test.client.AsyncClient.post django.test.client.AsyncClient.put django.test.client.AsyncClient.trace -django.test.client.ClientMixin.aforce_login -django.test.client.ClientMixin.alogin -django.test.client.ClientMixin.alogout -django.test.client.ClientMixin.asession django.test.runner.DiscoverRunner.__init__ django.test.runner.DiscoverRunner.run_tests django.test.runner.RemoteTestResult.addDuration From 85e094b5378d37b03d19f0367df85997136d600b Mon Sep 17 00:00:00 2001 From: Marti Raudsepp Date: Fri, 8 Dec 2023 13:52:25 +0200 Subject: [PATCH 6/6] Revert this part -- only reported to me locally for some reason --- scripts/stubtest/allowlist.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripts/stubtest/allowlist.txt b/scripts/stubtest/allowlist.txt index 1daf8b560..358e9a653 100644 --- a/scripts/stubtest/allowlist.txt +++ b/scripts/stubtest/allowlist.txt @@ -395,7 +395,3 @@ django.urls.resolvers.URLPattern.lookup_str django.urls.resolvers.URLResolver.url_patterns django.urls.resolvers.URLResolver.urlconf_module django.utils.connection.BaseConnectionHandler.settings - -# Module-scoped loop variables that shouldn't be exported -django.contrib.admindocs.utils.name -django.contrib.admindocs.utils.urlbase