diff --git a/docs/testing/mypy.md b/docs/testing/mypy.md index db0230c330..4b9b8932db 100644 --- a/docs/testing/mypy.md +++ b/docs/testing/mypy.md @@ -128,24 +128,18 @@ needing to do an explicit annotation. When declaring the types for functions that accept a `QuerySet` object, you should always supply the model type that it accepts as the -type parameter. +first type parameter. ```python def foo(user: QuerySet[UserProfile]) -> None: ... ``` -In cases where you need to type the return value from `.values_list` -or `.values` on a `QuerySet`, you can use the special -`django_stubs_ext.ValuesQuerySet` type. - -For `.values_list`, the second type parameter will be the type of the -column. +For `.values_list`, supply the type of the column as the second type +parameter. ```python -from django_stubs_ext import ValuesQuerySet - -def get_book_page_counts() -> ValuesQuerySet[Book, int]: +def get_book_page_counts() -> QuerySet[Book, int]: return Book.objects.filter().values_list("page_count", flat=True) ``` @@ -153,15 +147,13 @@ For `.values`, we prefer to define a `TypedDict` containing the key-value pairs for the columns. ```python -from django_stubs_ext import ValuesQuerySet - class BookMetadata(TypedDict): id: int name: str def get_book_meta_data( book_ids: List[int], -) -> ValuesQuerySet[Book, BookMetadata]: +) -> QuerySet[Book, BookMetadata]: return Book.objects.filter(id__in=book_ids).values("name", "id") ``` diff --git a/zerver/actions/message_send.py b/zerver/actions/message_send.py index 2e324e4bf0..81fd36c781 100644 --- a/zerver/actions/message_send.py +++ b/zerver/actions/message_send.py @@ -11,12 +11,11 @@ import orjson from django.conf import settings from django.core.exceptions import ValidationError from django.db import IntegrityError, transaction -from django.db.models import F, Q +from django.db.models import F, Q, QuerySet from django.utils.html import escape from django.utils.timezone import now as timezone_now from django.utils.translation import gettext as _ from django.utils.translation import override as override_language -from django_stubs_ext import ValuesQuerySet from zerver.actions.uploads import do_claim_attachments from zerver.actions.user_topics import ( @@ -380,7 +379,7 @@ def get_recipient_info( user_ids = message_to_user_id_set | possibly_mentioned_user_ids if user_ids: - query: ValuesQuerySet[UserProfile, ActiveUserDict] = UserProfile.objects.filter( + query: QuerySet[UserProfile, ActiveUserDict] = UserProfile.objects.filter( is_active=True ).values( "id", diff --git a/zerver/actions/streams.py b/zerver/actions/streams.py index acaf19b145..b29c767838 100644 --- a/zerver/actions/streams.py +++ b/zerver/actions/streams.py @@ -9,7 +9,6 @@ from django.db.models import Q, QuerySet from django.utils.timezone import now as timezone_now from django.utils.translation import gettext as _ from django.utils.translation import override as override_language -from django_stubs_ext import ValuesQuerySet from zerver.actions.default_streams import ( do_remove_default_stream, @@ -393,7 +392,7 @@ def merge_streams( def get_subscriber_ids( stream: Stream, requesting_user: UserProfile | None = None -) -> ValuesQuerySet[Subscription, int]: +) -> QuerySet[Subscription, int]: subscriptions_query = get_subscribers_query(stream, requesting_user) return subscriptions_query.values_list("user_profile_id", flat=True) diff --git a/zerver/lib/cache.py b/zerver/lib/cache.py index 7d915f2c94..85aeb8c088 100644 --- a/zerver/lib/cache.py +++ b/zerver/lib/cache.py @@ -14,8 +14,7 @@ from typing import TYPE_CHECKING, Any, Generic, TypeVar from django.conf import settings from django.core.cache import caches from django.core.cache.backends.base import BaseCache -from django.db.models import Q -from django_stubs_ext import QuerySetAny +from django.db.models import Q, QuerySet from typing_extensions import ParamSpec if TYPE_CHECKING: @@ -140,7 +139,7 @@ def cache_with_key( return val[0] val = func(*args, **kwargs) - if isinstance(val, QuerySetAny): + if isinstance(val, QuerySet): logging.error( "cache_with_key attempted to store a full QuerySet object -- declining to cache", stack_info=True, diff --git a/zerver/lib/cache_helpers.py b/zerver/lib/cache_helpers.py index 2f729d250e..9d940bd0d3 100644 --- a/zerver/lib/cache_helpers.py +++ b/zerver/lib/cache_helpers.py @@ -9,7 +9,6 @@ from django.contrib.sessions.models import Session from django.db import connection from django.db.models import QuerySet from django.utils.timezone import now as timezone_now -from django_stubs_ext import ValuesQuerySet # This file needs to be different from cache.py because cache.py # cannot import anything from zerver.models or we'd have an import @@ -58,7 +57,7 @@ def session_cache_items( items_for_remote_cache[store.cache_key] = store.decode(session.session_data) -def get_active_realm_ids() -> ValuesQuerySet[RealmCount, int]: +def get_active_realm_ids() -> QuerySet[RealmCount, int]: """For installations like Zulip Cloud hosting a lot of realms, it only makes sense to do cache-filling work for realms that have any currently active users/clients. Otherwise, we end up with every single-user diff --git a/zerver/lib/display_recipient.py b/zerver/lib/display_recipient.py index 8e99477b84..99009d6b35 100644 --- a/zerver/lib/display_recipient.py +++ b/zerver/lib/display_recipient.py @@ -1,6 +1,6 @@ from typing import TYPE_CHECKING, Optional, TypedDict -from django_stubs_ext import ValuesQuerySet +from django.db.models import QuerySet from zerver.lib.cache import ( bulk_cached_fetch, @@ -102,7 +102,7 @@ def bulk_fetch_stream_names( def get_tiny_stream_rows( recipient_ids: list[int], - ) -> ValuesQuerySet[Stream, TinyStreamResult]: + ) -> QuerySet[Stream, TinyStreamResult]: stream_ids = [recipient_id_to_stream_id[recipient_id] for recipient_id in recipient_ids] return Stream.objects.filter(id__in=stream_ids).values("recipient_id", "name") diff --git a/zerver/lib/message.py b/zerver/lib/message.py index 39f85045ae..4393028a02 100644 --- a/zerver/lib/message.py +++ b/zerver/lib/message.py @@ -9,7 +9,6 @@ from django.db import connection from django.db.models import Exists, Max, OuterRef, QuerySet, Sum from django.utils.timezone import now as timezone_now from django.utils.translation import gettext as _ -from django_stubs_ext import ValuesQuerySet from psycopg2.sql import SQL from analytics.lib.counts import COUNT_STATS @@ -491,7 +490,7 @@ def bulk_access_stream_messages_query( def get_messages_with_usermessage_rows_for_user( user_profile_id: int, message_ids: Sequence[int] -) -> ValuesQuerySet[UserMessage, int]: +) -> QuerySet[UserMessage, int]: """ Returns a subset of `message_ids` containing only messages the user has a UserMessage for. Makes O(1) database queries. diff --git a/zerver/lib/query_helpers.py b/zerver/lib/query_helpers.py index a1568147e7..23fa756873 100644 --- a/zerver/lib/query_helpers.py +++ b/zerver/lib/query_helpers.py @@ -1,17 +1,17 @@ from typing import TypeVar from django.db import models -from django_stubs_ext import ValuesQuerySet +from django.db.models import QuerySet ModelT = TypeVar("ModelT", bound=models.Model) RowT = TypeVar("RowT") def query_for_ids( - query: ValuesQuerySet[ModelT, RowT], + query: QuerySet[ModelT, RowT], user_ids: list[int], field: str, -) -> ValuesQuerySet[ModelT, RowT]: +) -> QuerySet[ModelT, RowT]: """ This function optimizes searches of the form `user_profile_id in (1, 2, 3, 4)` by quickly diff --git a/zerver/lib/stream_subscription.py b/zerver/lib/stream_subscription.py index 719114c9b4..f04539b931 100644 --- a/zerver/lib/stream_subscription.py +++ b/zerver/lib/stream_subscription.py @@ -7,7 +7,6 @@ from operator import itemgetter from typing import Any from django.db.models import Q, QuerySet -from django_stubs_ext import ValuesQuerySet from zerver.models import AlertWord, Realm, Recipient, Stream, Subscription, UserProfile, UserTopic @@ -53,7 +52,7 @@ def get_active_subscriptions_for_stream_ids(stream_ids: set[int]) -> QuerySet[Su def get_subscribed_stream_ids_for_user( user_profile: UserProfile, -) -> ValuesQuerySet[Subscription, int]: +) -> QuerySet[Subscription, int]: return Subscription.objects.filter( user_profile_id=user_profile, recipient__type=Recipient.STREAM, @@ -63,7 +62,7 @@ def get_subscribed_stream_ids_for_user( def get_subscribed_stream_recipient_ids_for_user( user_profile: UserProfile, -) -> ValuesQuerySet[Subscription, int]: +) -> QuerySet[Subscription, int]: return Subscription.objects.filter( user_profile_id=user_profile, recipient__type=Recipient.STREAM, diff --git a/zerver/lib/test_classes.py b/zerver/lib/test_classes.py index df3df6ff6c..3566aae659 100644 --- a/zerver/lib/test_classes.py +++ b/zerver/lib/test_classes.py @@ -21,6 +21,7 @@ from django.core.signals import got_request_exception from django.db import connection, transaction from django.db.migrations.executor import MigrationExecutor from django.db.migrations.state import StateApps +from django.db.models import QuerySet from django.db.utils import IntegrityError from django.http import HttpRequest, HttpResponse, HttpResponseBase from django.http.response import ResponseHeaders @@ -32,7 +33,6 @@ from django.urls import resolve from django.utils import translation from django.utils.module_loading import import_string from django.utils.timezone import now as timezone_now -from django_stubs_ext import ValuesQuerySet from fakeldap import MockLDAP from openapi_core.contrib.django import DjangoOpenAPIRequest, DjangoOpenAPIResponse from requests import PreparedRequest @@ -1258,7 +1258,7 @@ Output: """ self.assertEqual(self.get_json_error(result, status_code=status_code), msg) - def assert_length(self, items: Collection[Any] | ValuesQuerySet[Any, Any], count: int) -> None: + def assert_length(self, items: Collection[Any] | QuerySet[Any, Any], count: int) -> None: actual_count = len(items) if actual_count != count: # nocoverage print("\nITEMS:\n") diff --git a/zerver/lib/user_groups.py b/zerver/lib/user_groups.py index dc9f9eac3a..541e1b58b6 100644 --- a/zerver/lib/user_groups.py +++ b/zerver/lib/user_groups.py @@ -10,7 +10,6 @@ from django.db.models import F, QuerySet from django.utils.timezone import now as timezone_now from django.utils.translation import gettext as _ from django_cte import With -from django_stubs_ext import ValuesQuerySet from psycopg2.sql import SQL, Literal from zerver.lib.exceptions import ( @@ -441,7 +440,7 @@ def get_direct_user_groups(user_profile: UserProfile) -> list[UserGroup]: def get_user_group_direct_member_ids( user_group: UserGroup, -) -> ValuesQuerySet[UserGroupMembership, int]: +) -> QuerySet[UserGroupMembership, int]: return UserGroupMembership.objects.filter(user_group=user_group).values_list( "user_profile_id", flat=True ) diff --git a/zerver/models/recipients.py b/zerver/models/recipients.py index dc06d00dcd..38a4bc5c8f 100644 --- a/zerver/models/recipients.py +++ b/zerver/models/recipients.py @@ -3,7 +3,7 @@ from collections import defaultdict from typing import TYPE_CHECKING from django.db import models, transaction -from django_stubs_ext import ValuesQuerySet +from django.db.models import QuerySet from typing_extensions import override from zerver.lib.display_recipient import get_display_recipient @@ -79,7 +79,7 @@ class Recipient(models.Model): return self._type_names[self.type] -def get_direct_message_group_user_ids(recipient: Recipient) -> ValuesQuerySet["Subscription", int]: +def get_direct_message_group_user_ids(recipient: Recipient) -> QuerySet["Subscription", int]: from zerver.models import Subscription assert recipient.type == Recipient.DIRECT_MESSAGE_GROUP