Rename ValuesQuerySet -> _ValuesQuerySet and remove _BaseQuerySet. Ma… (#654)

* Rename ValuesQuerySet -> _ValuesQuerySet and remove _BaseQuerySet. Make a public alias called ValuesQuerySet in django_stubs_ext.

* Update tests
This commit is contained in:
Seth Yastrov
2021-06-28 12:23:00 +02:00
committed by GitHub
parent 29e971ed9d
commit f9317c7679
10 changed files with 58 additions and 32 deletions

View File

@@ -8,7 +8,7 @@ from django.db.models.sql.compiler import SQLCompiler
from django.db.backends.base.base import BaseDatabaseWrapper from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.models import Q, QuerySet from django.db.models import Q, QuerySet
from django.db.models.fields import Field from django.db.models.fields import Field
from django.db.models.query import _BaseQuerySet from django.db.models.query import QuerySet
_OutputField = Union[Field, str] _OutputField = Union[Field, str]
@@ -132,7 +132,7 @@ class Subquery(Expression):
template: str = ... template: str = ...
queryset: QuerySet = ... queryset: QuerySet = ...
extra: Dict[Any, Any] = ... extra: Dict[Any, Any] = ...
def __init__(self, queryset: _BaseQuerySet, output_field: Optional[_OutputField] = ..., **extra: Any) -> None: ... def __init__(self, queryset: QuerySet, output_field: Optional[_OutputField] = ..., **extra: Any) -> None: ...
class Exists(Subquery): class Exists(Subquery):
negated: bool = ... negated: bool = ...

View File

@@ -28,9 +28,9 @@ from django.db.models import Manager
from django.db.models.query_utils import Q as Q # noqa: F401 from django.db.models.query_utils import Q as Q # noqa: F401
_T = TypeVar("_T", bound=models.Model, covariant=True) _T = TypeVar("_T", bound=models.Model, covariant=True)
_QS = TypeVar("_QS", bound="_BaseQuerySet") _QS = TypeVar("_QS", bound="QuerySet")
class _BaseQuerySet(Generic[_T], Sized): class QuerySet(Generic[_T], Collection[_T], Reversible[_T], Sized):
model: Type[_T] model: Type[_T]
query: Query query: Query
def __init__( def __init__(
@@ -47,8 +47,8 @@ class _BaseQuerySet(Generic[_T], Sized):
def __class_getitem__(cls: Type[_QS], item: Type[_T]) -> Type[_QS]: ... def __class_getitem__(cls: Type[_QS], item: Type[_T]) -> Type[_QS]: ...
def __getstate__(self) -> Dict[str, Any]: ... def __getstate__(self) -> Dict[str, Any]: ...
# Technically, the other QuerySet must be of the same type _T, but _T is covariant # Technically, the other QuerySet must be of the same type _T, but _T is covariant
def __and__(self: _QS, other: _BaseQuerySet[_T]) -> _QS: ... def __and__(self: _QS, other: QuerySet[_T]) -> _QS: ...
def __or__(self: _QS, other: _BaseQuerySet[_T]) -> _QS: ... def __or__(self: _QS, other: QuerySet[_T]) -> _QS: ...
def iterator(self, chunk_size: int = ...) -> Iterator[_T]: ... def iterator(self, chunk_size: int = ...) -> Iterator[_T]: ...
def aggregate(self, *args: Any, **kwargs: Any) -> Dict[str, Any]: ... def aggregate(self, *args: Any, **kwargs: Any) -> Dict[str, Any]: ...
def get(self, *args: Any, **kwargs: Any) -> _T: ... def get(self, *args: Any, **kwargs: Any) -> _T: ...
@@ -78,15 +78,15 @@ class _BaseQuerySet(Generic[_T], Sized):
using: Optional[str] = ..., using: Optional[str] = ...,
) -> RawQuerySet: ... ) -> RawQuerySet: ...
# The type of values may be overridden to be more specific in the mypy plugin, depending on the fields param # The type of values may be overridden to be more specific in the mypy plugin, depending on the fields param
def values(self, *fields: Union[str, Combinable], **expressions: Any) -> ValuesQuerySet[_T, Dict[str, Any]]: ... def values(self, *fields: Union[str, Combinable], **expressions: Any) -> _ValuesQuerySet[_T, Dict[str, Any]]: ...
# The type of values_list may be overridden to be more specific in the mypy plugin, depending on the fields param # The type of values_list may be overridden to be more specific in the mypy plugin, depending on the fields param
def values_list( def values_list(
self, *fields: Union[str, Combinable], flat: bool = ..., named: bool = ... self, *fields: Union[str, Combinable], flat: bool = ..., named: bool = ...
) -> ValuesQuerySet[_T, Any]: ... ) -> _ValuesQuerySet[_T, Any]: ...
def dates(self, field_name: str, kind: str, order: str = ...) -> ValuesQuerySet[_T, datetime.date]: ... def dates(self, field_name: str, kind: str, order: str = ...) -> _ValuesQuerySet[_T, datetime.date]: ...
def datetimes( def datetimes(
self, field_name: str, kind: str, order: str = ..., tzinfo: Optional[datetime.tzinfo] = ... self, field_name: str, kind: str, order: str = ..., tzinfo: Optional[datetime.tzinfo] = ...
) -> ValuesQuerySet[_T, datetime.datetime]: ... ) -> _ValuesQuerySet[_T, datetime.datetime]: ...
def none(self: _QS) -> _QS: ... def none(self: _QS) -> _QS: ...
def all(self: _QS) -> _QS: ... def all(self: _QS) -> _QS: ...
def filter(self: _QS, *args: Any, **kwargs: Any) -> _QS: ... def filter(self: _QS, *args: Any, **kwargs: Any) -> _QS: ...
@@ -126,7 +126,7 @@ class _BaseQuerySet(Generic[_T], Sized):
def db(self) -> str: ... def db(self) -> str: ...
def resolve_expression(self, *args: Any, **kwargs: Any) -> Any: ... def resolve_expression(self, *args: Any, **kwargs: Any) -> Any: ...
class QuerySet(_BaseQuerySet[_T], Collection[_T], Reversible[_T], Sized):
def __iter__(self) -> Iterator[_T]: ... def __iter__(self) -> Iterator[_T]: ...
def __contains__(self, x: object) -> bool: ... def __contains__(self, x: object) -> bool: ...
@overload @overload
@@ -138,7 +138,7 @@ class QuerySet(_BaseQuerySet[_T], Collection[_T], Reversible[_T], Sized):
_Row = TypeVar("_Row", covariant=True) _Row = TypeVar("_Row", covariant=True)
class BaseIterable(Sequence[_Row]): class BaseIterable(Sequence[_Row]):
def __init__(self, queryset: _BaseQuerySet, chunked_fetch: bool = ..., chunk_size: int = ...): ... def __init__(self, queryset: QuerySet, chunked_fetch: bool = ..., chunk_size: int = ...): ...
def __iter__(self) -> Iterator[_Row]: ... def __iter__(self) -> Iterator[_Row]: ...
def __contains__(self, x: object) -> bool: ... def __contains__(self, x: object) -> bool: ...
def __len__(self) -> int: ... def __len__(self) -> int: ...
@@ -155,13 +155,14 @@ class NamedValuesListIterable(ValuesListIterable): ...
class FlatValuesListIterable(BaseIterable): class FlatValuesListIterable(BaseIterable):
def __iter__(self) -> Iterator[Any]: ... def __iter__(self) -> Iterator[Any]: ...
class ValuesQuerySet(_BaseQuerySet[_T], Collection[_Row], Sized): class _ValuesQuerySet(Generic[_T, _Row], Collection[_Row], Reversible[_Row], QuerySet[_T], Sized): # type: ignore
def __len__(self) -> int: ...
def __contains__(self, x: object) -> bool: ... def __contains__(self, x: object) -> bool: ...
def __iter__(self) -> Iterator[_Row]: ... # type: ignore def __iter__(self) -> Iterator[_Row]: ... # type: ignore
@overload # type: ignore @overload # type: ignore
def __getitem__(self, i: int) -> _Row: ... def __getitem__(self, i: int) -> _Row: ...
@overload @overload
def __getitem__(self: _QS, s: slice) -> _QS: ... def __getitem__(self: _QS, s: slice) -> _QS: ... # type: ignore
def iterator(self, chunk_size: int = ...) -> Iterator[_Row]: ... # type: ignore def iterator(self, chunk_size: int = ...) -> Iterator[_Row]: ... # type: ignore
def get(self, *args: Any, **kwargs: Any) -> _Row: ... # type: ignore def get(self, *args: Any, **kwargs: Any) -> _Row: ... # type: ignore
def earliest(self, *fields: Any, field_name: Optional[Any] = ...) -> _Row: ... # type: ignore def earliest(self, *fields: Any, field_name: Optional[Any] = ...) -> _Row: ... # type: ignore

View File

@@ -24,7 +24,7 @@ from uuid import UUID
from django.core.files.base import File from django.core.files.base import File
from django.db.models.base import Model from django.db.models.base import Model
from django.db.models.manager import Manager from django.db.models.manager import Manager
from django.db.models.query import QuerySet, _BaseQuerySet from django.db.models.query import QuerySet
from django.db.models.query_utils import Q from django.db.models.query_utils import Q
from django.forms.fields import CharField, ChoiceField, Field from django.forms.fields import CharField, ChoiceField, Field
from django.forms.forms import BaseForm, DeclarativeFieldsMetaclass from django.forms.forms import BaseForm, DeclarativeFieldsMetaclass
@@ -257,7 +257,7 @@ class ModelChoiceField(ChoiceField):
to_field_name: None = ... to_field_name: None = ...
def __init__( def __init__(
self, self,
queryset: Optional[Union[Manager, _BaseQuerySet]], queryset: Optional[Union[Manager, QuerySet]],
*, *,
empty_label: Optional[str] = ..., empty_label: Optional[str] = ...,
required: bool = ..., required: bool = ...,
@@ -284,7 +284,7 @@ class ModelMultipleChoiceField(ModelChoiceField):
widget: Any = ... widget: Any = ...
hidden_widget: Any = ... hidden_widget: Any = ...
default_error_messages: Any = ... default_error_messages: Any = ...
def __init__(self, queryset: Optional[Union[Manager, _BaseQuerySet]], **kwargs: Any) -> None: ... def __init__(self, queryset: Optional[Union[Manager, QuerySet]], **kwargs: Any) -> None: ...
def _get_foreign_key( def _get_foreign_key(
parent_model: Type[Model], model: Type[Model], fk_name: Optional[str] = ..., can_fail: bool = ... parent_model: Type[Model], model: Type[Model], fk_name: Optional[str] = ..., can_fail: bool = ...

View File

@@ -1,7 +1,7 @@
from typing import Any, Generic, Optional, Sequence, Tuple, Type, TypeVar from typing import Any, Generic, Optional, Sequence, Tuple, Type, TypeVar
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.db.models.query import QuerySet, _BaseQuerySet from django.db.models.query import QuerySet
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
from django.db.models import Model from django.db.models import Model
@@ -22,15 +22,15 @@ class MultipleObjectMixin(Generic[T], ContextMixin):
def get_queryset(self) -> QuerySet[T]: ... def get_queryset(self) -> QuerySet[T]: ...
def get_ordering(self) -> Sequence[str]: ... def get_ordering(self) -> Sequence[str]: ...
def paginate_queryset( def paginate_queryset(
self, queryset: _BaseQuerySet, page_size: int self, queryset: QuerySet, page_size: int
) -> Tuple[Paginator, int, QuerySet[T], bool]: ... ) -> Tuple[Paginator, int, QuerySet[T], bool]: ...
def get_paginate_by(self, queryset: _BaseQuerySet) -> Optional[int]: ... def get_paginate_by(self, queryset: QuerySet) -> Optional[int]: ...
def get_paginator( def get_paginator(
self, queryset: QuerySet, per_page: int, orphans: int = ..., allow_empty_first_page: bool = ..., **kwargs: Any self, queryset: QuerySet, per_page: int, orphans: int = ..., allow_empty_first_page: bool = ..., **kwargs: Any
) -> Paginator: ... ) -> Paginator: ...
def get_paginate_orphans(self) -> int: ... def get_paginate_orphans(self) -> int: ...
def get_allow_empty(self) -> bool: ... def get_allow_empty(self) -> bool: ...
def get_context_object_name(self, object_list: _BaseQuerySet) -> Optional[str]: ... def get_context_object_name(self, object_list: QuerySet) -> Optional[str]: ...
class BaseListView(MultipleObjectMixin[T], View): class BaseListView(MultipleObjectMixin[T], View):
def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ... def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...

View File

@@ -1,3 +1,4 @@
from .aliases import ValuesQuerySet as ValuesQuerySet
from .patch import monkeypatch as monkeypatch from .patch import monkeypatch as monkeypatch
__all__ = ["monkeypatch"] __all__ = ["monkeypatch", "ValuesQuerySet"]

View File

@@ -0,0 +1,8 @@
import typing
if typing.TYPE_CHECKING:
from django.db.models.query import _T, _Row, _ValuesQuerySet
ValuesQuerySet = _ValuesQuerySet[_T, _Row]
else:
ValuesQuerySet = typing.Any

View File

@@ -0,0 +1,16 @@
- case: alias_values_query_set
main: |
from django_stubs_ext import ValuesQuerySet
from myapp.models import Blog
a: ValuesQuerySet[Blog, Blog]
installed_apps:
- myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from django.db import models
class Blog(models.Model):
created_at = models.DateTimeField()

View File

@@ -14,8 +14,8 @@
reveal_type(qs.in_bulk()) # N: Revealed type is "builtins.dict[Any, myapp.models.Blog*]" reveal_type(qs.in_bulk()) # N: Revealed type is "builtins.dict[Any, myapp.models.Blog*]"
# .dates / .datetimes # .dates / .datetimes
reveal_type(Blog.objects.dates("created_at", "day")) # N: Revealed type is "django.db.models.query.ValuesQuerySet[myapp.models.Blog*, datetime.date]" reveal_type(Blog.objects.dates("created_at", "day")) # N: Revealed type is "django.db.models.query._ValuesQuerySet[myapp.models.Blog*, datetime.date]"
reveal_type(Blog.objects.datetimes("created_at", "day")) # N: Revealed type is "django.db.models.query.ValuesQuerySet[myapp.models.Blog*, datetime.datetime]" reveal_type(Blog.objects.datetimes("created_at", "day")) # N: Revealed type is "django.db.models.query._ValuesQuerySet[myapp.models.Blog*, datetime.datetime]"
# AND-ing QuerySets # AND-ing QuerySets
reveal_type(Blog.objects.all() & Blog.objects.all()) # N: Revealed type is "django.db.models.manager.Manager[myapp.models.Blog]" reveal_type(Blog.objects.all() & Blog.objects.all()) # N: Revealed type is "django.db.models.manager.Manager[myapp.models.Blog]"

View File

@@ -111,8 +111,8 @@
- case: values_of_many_to_many_field - case: values_of_many_to_many_field
main: | main: |
from myapp.models import Author, Book from myapp.models import Author, Book
reveal_type(Book.objects.values('authors')) # N: Revealed type is "django.db.models.query.ValuesQuerySet[myapp.models.Book, TypedDict({'authors': builtins.int})]" reveal_type(Book.objects.values('authors')) # N: Revealed type is "django.db.models.query._ValuesQuerySet[myapp.models.Book, TypedDict({'authors': builtins.int})]"
reveal_type(Author.objects.values('books')) # N: Revealed type is "django.db.models.query.ValuesQuerySet[myapp.models.Author, TypedDict({'books': builtins.int})]" reveal_type(Author.objects.values('books')) # N: Revealed type is "django.db.models.query._ValuesQuerySet[myapp.models.Author, TypedDict({'books': builtins.int})]"
installed_apps: installed_apps:
- myapp - myapp
files: files:

View File

@@ -191,8 +191,8 @@
- case: values_list_flat_true_with_ids - case: values_list_flat_true_with_ids
main: | main: |
from myapp.models import Blog, Publisher from myapp.models import Blog, Publisher
reveal_type(Blog.objects.values_list('id', flat=True)) # N: Revealed type is "django.db.models.query.ValuesQuerySet[myapp.models.Blog, builtins.int]" reveal_type(Blog.objects.values_list('id', flat=True)) # N: Revealed type is "django.db.models.query._ValuesQuerySet[myapp.models.Blog, builtins.int]"
reveal_type(Blog.objects.values_list('publisher_id', flat=True)) # N: Revealed type is "django.db.models.query.ValuesQuerySet[myapp.models.Blog, builtins.int]" reveal_type(Blog.objects.values_list('publisher_id', flat=True)) # N: Revealed type is "django.db.models.query._ValuesQuerySet[myapp.models.Blog, builtins.int]"
# is Iterable[int] # is Iterable[int]
reveal_type(list(Blog.objects.values_list('id', flat=True))) # N: Revealed type is "builtins.list[builtins.int*]" reveal_type(list(Blog.objects.values_list('id', flat=True))) # N: Revealed type is "builtins.list[builtins.int*]"
installed_apps: installed_apps:
@@ -211,8 +211,8 @@
main: | main: |
from myapp.models import TransactionQuerySet from myapp.models import TransactionQuerySet
reveal_type(TransactionQuerySet()) # N: Revealed type is "myapp.models.TransactionQuerySet" reveal_type(TransactionQuerySet()) # N: Revealed type is "myapp.models.TransactionQuerySet"
reveal_type(TransactionQuerySet().values()) # N: Revealed type is "django.db.models.query.ValuesQuerySet[myapp.models.Transaction, TypedDict({'id': builtins.int, 'total': builtins.int})]" reveal_type(TransactionQuerySet().values()) # N: Revealed type is "django.db.models.query._ValuesQuerySet[myapp.models.Transaction, TypedDict({'id': builtins.int, 'total': builtins.int})]"
reveal_type(TransactionQuerySet().values_list()) # N: Revealed type is "django.db.models.query.ValuesQuerySet[myapp.models.Transaction, Tuple[builtins.int, builtins.int]]" reveal_type(TransactionQuerySet().values_list()) # N: Revealed type is "django.db.models.query._ValuesQuerySet[myapp.models.Transaction, Tuple[builtins.int, builtins.int]]"
installed_apps: installed_apps:
- myapp - myapp
files: files:
@@ -228,8 +228,8 @@
- case: values_list_of_many_to_many_field - case: values_list_of_many_to_many_field
main: | main: |
from myapp.models import Author, Book from myapp.models import Author, Book
reveal_type(Book.objects.values_list('authors')) # N: Revealed type is "django.db.models.query.ValuesQuerySet[myapp.models.Book, Tuple[builtins.int]]" reveal_type(Book.objects.values_list('authors')) # N: Revealed type is "django.db.models.query._ValuesQuerySet[myapp.models.Book, Tuple[builtins.int]]"
reveal_type(Author.objects.values_list('books')) # N: Revealed type is "django.db.models.query.ValuesQuerySet[myapp.models.Author, Tuple[builtins.int]]" reveal_type(Author.objects.values_list('books')) # N: Revealed type is "django.db.models.query._ValuesQuerySet[myapp.models.Author, Tuple[builtins.int]]"
installed_apps: installed_apps:
- myapp - myapp
files: files: