mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-06 20:24:31 +08:00
make first() an Optional, allow to specify QuerySet with one parameter (#136)
This commit is contained in:
@@ -5,7 +5,7 @@ from django.db.models.query import QuerySet
|
||||
|
||||
_T = TypeVar("_T", bound=Model, covariant=True)
|
||||
|
||||
class BaseManager(QuerySet[_T, _T]):
|
||||
class BaseManager(QuerySet[_T]):
|
||||
creation_counter: int = ...
|
||||
auto_created: bool = ...
|
||||
use_in_migrations: bool = ...
|
||||
@@ -21,7 +21,7 @@ class BaseManager(QuerySet[_T, _T]):
|
||||
def _get_queryset_methods(cls, queryset_class: type) -> Dict[str, Any]: ...
|
||||
def contribute_to_class(self, model: Type[Model], name: str) -> None: ...
|
||||
def db_manager(self, using: Optional[str] = ..., hints: Optional[Dict[str, Model]] = ...) -> Manager: ...
|
||||
def get_queryset(self) -> QuerySet[_T, _T]: ...
|
||||
def get_queryset(self) -> QuerySet[_T]: ...
|
||||
|
||||
class Manager(BaseManager[_T]): ...
|
||||
|
||||
|
||||
@@ -27,6 +27,111 @@ from django.db import models
|
||||
from django.db.models import Manager
|
||||
from django.db.models.query_utils import Q as Q
|
||||
|
||||
_T = TypeVar("_T", bound=models.Model, covariant=True)
|
||||
_QS = TypeVar("_QS", bound="QuerySet")
|
||||
|
||||
class QuerySet(Generic[_T], Collection[_T], Sized):
|
||||
query: Query
|
||||
def __init__(
|
||||
self,
|
||||
model: Optional[Type[models.Model]] = ...,
|
||||
query: Optional[Query] = ...,
|
||||
using: Optional[str] = ...,
|
||||
hints: Optional[Dict[str, models.Model]] = ...,
|
||||
) -> None: ...
|
||||
@classmethod
|
||||
def as_manager(cls) -> Manager[Any]: ...
|
||||
def __len__(self) -> int: ...
|
||||
def __iter__(self) -> Iterator[_T]: ...
|
||||
def __contains__(self, x: object) -> bool: ...
|
||||
@overload
|
||||
def __getitem__(self, i: int) -> _T: ...
|
||||
@overload
|
||||
def __getitem__(self, s: slice) -> QuerySet[_T]: ...
|
||||
def __bool__(self) -> bool: ...
|
||||
def __class_getitem__(cls, item: Type[_T]):
|
||||
pass
|
||||
def __getstate__(self) -> Dict[str, Any]: ...
|
||||
# __and__ and __or__ ignore the other QuerySet's _Row type parameter
|
||||
# because they use the same row type as the self QuerySet.
|
||||
# Technically, the other QuerySet must be of the same type _T, but _T is covariant
|
||||
def __and__(self, other: QuerySet[_T]) -> QuerySet[_T]: ...
|
||||
def __or__(self, other: QuerySet[_T]) -> QuerySet[_T]: ...
|
||||
def iterator(self, chunk_size: int = ...) -> Iterator[_T]: ...
|
||||
def aggregate(self, *args: Any, **kwargs: Any) -> Dict[str, Any]: ...
|
||||
def get(self, *args: Any, **kwargs: Any) -> _T: ...
|
||||
def create(self, *args: Any, **kwargs: Any) -> _T: ...
|
||||
def bulk_create(
|
||||
self, objs: Iterable[Model], batch_size: Optional[int] = ..., ignore_conflicts: bool = ...
|
||||
) -> List[_T]: ...
|
||||
def get_or_create(self, defaults: Optional[MutableMapping[str, Any]] = ..., **kwargs: Any) -> Tuple[_T, bool]: ...
|
||||
def update_or_create(
|
||||
self, defaults: Optional[MutableMapping[str, Any]] = ..., **kwargs: Any
|
||||
) -> Tuple[_T, bool]: ...
|
||||
def earliest(self, *fields: Any, field_name: Optional[Any] = ...) -> _T: ...
|
||||
def latest(self, *fields: Any, field_name: Optional[Any] = ...) -> _T: ...
|
||||
def first(self) -> Optional[_T]: ...
|
||||
def last(self) -> Optional[_T]: ...
|
||||
def in_bulk(self, id_list: Iterable[Any] = ..., *, field_name: str = ...) -> Dict[Any, _T]: ...
|
||||
def delete(self) -> Tuple[int, Dict[str, int]]: ...
|
||||
def update(self, **kwargs: Any) -> int: ...
|
||||
def exists(self) -> bool: ...
|
||||
def explain(self, *, format: Optional[Any] = ..., **options: Any) -> str: ...
|
||||
def raw(
|
||||
self,
|
||||
raw_query: str,
|
||||
params: Any = ...,
|
||||
translations: Optional[Dict[str, str]] = ...,
|
||||
using: Optional[str] = ...,
|
||||
) -> RawQuerySet: ...
|
||||
# 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]]: ...
|
||||
# The type of values_list may be overridden to be more specific in the mypy plugin, depending on the fields param
|
||||
def values_list(
|
||||
self, *fields: Union[str, Combinable], flat: bool = ..., named: bool = ...
|
||||
) -> ValuesQuerySet[_T, Any]: ...
|
||||
def dates(self, field_name: str, kind: str, order: str = ...) -> ValuesQuerySet[_T, datetime.date]: ...
|
||||
def datetimes(
|
||||
self, field_name: str, kind: str, order: str = ..., tzinfo: None = ...
|
||||
) -> ValuesQuerySet[_T, datetime.datetime]: ...
|
||||
def none(self) -> QuerySet[_T]: ...
|
||||
def all(self) -> QuerySet[_T]: ...
|
||||
def filter(self, *args: Any, **kwargs: Any) -> QuerySet[_T]: ...
|
||||
def exclude(self, *args: Any, **kwargs: Any) -> QuerySet[_T]: ...
|
||||
def complex_filter(self, filter_obj: Any) -> QuerySet[_T]: ...
|
||||
def count(self) -> int: ...
|
||||
def union(self, *other_qs: Any, all: bool = ...) -> QuerySet[_T]: ...
|
||||
def intersection(self, *other_qs: Any) -> QuerySet[_T]: ...
|
||||
def difference(self, *other_qs: Any) -> QuerySet[_T]: ...
|
||||
def select_for_update(self, nowait: bool = ..., skip_locked: bool = ..., of: Tuple = ...) -> QuerySet[_T]: ...
|
||||
def select_related(self, *fields: Any) -> QuerySet[_T]: ...
|
||||
def prefetch_related(self, *lookups: Any) -> QuerySet[_T]: ...
|
||||
# TODO: return type
|
||||
def annotate(self, *args: Any, **kwargs: Any) -> QuerySet[Any]: ...
|
||||
def order_by(self, *field_names: Any) -> QuerySet[_T]: ...
|
||||
def distinct(self, *field_names: Any) -> QuerySet[_T]: ...
|
||||
# extra() return type won't be supported any time soon
|
||||
def extra(
|
||||
self,
|
||||
select: Optional[Dict[str, Any]] = ...,
|
||||
where: Optional[List[str]] = ...,
|
||||
params: Optional[List[Any]] = ...,
|
||||
tables: Optional[List[str]] = ...,
|
||||
order_by: Optional[Sequence[str]] = ...,
|
||||
select_params: Optional[Sequence[Any]] = ...,
|
||||
) -> QuerySet[Any]: ...
|
||||
def reverse(self) -> QuerySet[_T]: ...
|
||||
def defer(self, *fields: Any) -> QuerySet[_T]: ...
|
||||
def only(self, *fields: Any) -> QuerySet[_T]: ...
|
||||
def using(self, alias: Optional[str]) -> QuerySet[_T]: ...
|
||||
@property
|
||||
def ordered(self) -> bool: ...
|
||||
@property
|
||||
def db(self) -> str: ...
|
||||
def resolve_expression(self, *args: Any, **kwargs: Any) -> Any: ...
|
||||
# TODO: remove when django adds __class_getitem__ methods
|
||||
def __getattr__(self, item: str) -> Any: ...
|
||||
|
||||
_Row = TypeVar("_Row", covariant=True)
|
||||
|
||||
class BaseIterable(Sequence[_Row]):
|
||||
@@ -47,88 +152,39 @@ class NamedValuesListIterable(ValuesListIterable): ...
|
||||
class FlatValuesListIterable(BaseIterable):
|
||||
def __iter__(self) -> Iterator[Any]: ...
|
||||
|
||||
_T = TypeVar("_T", bound=models.Model, covariant=True)
|
||||
|
||||
class QuerySet(Generic[_T, _Row], Collection[_Row], Sized):
|
||||
query: Query
|
||||
def __init__(
|
||||
self,
|
||||
model: Optional[Type[models.Model]] = ...,
|
||||
query: Optional[Query] = ...,
|
||||
using: Optional[str] = ...,
|
||||
hints: Optional[Dict[str, models.Model]] = ...,
|
||||
) -> None: ...
|
||||
@classmethod
|
||||
def as_manager(cls) -> Manager[Any]: ...
|
||||
def __len__(self) -> int: ...
|
||||
def __iter__(self) -> Iterator[_Row]: ...
|
||||
def __contains__(self, x: object) -> bool: ...
|
||||
@overload
|
||||
class ValuesQuerySet(Generic[_T, _Row], QuerySet[_T], Collection[_Row], Sized):
|
||||
def __iter__(self) -> Iterator[_Row]: ... # type: ignore
|
||||
@overload # type: ignore
|
||||
def __getitem__(self, i: int) -> _Row: ...
|
||||
@overload
|
||||
def __getitem__(self, s: slice) -> QuerySet[_T, _Row]: ...
|
||||
def __bool__(self) -> bool: ...
|
||||
def __class_getitem__(cls, item: Type[_T]):
|
||||
pass
|
||||
def __getstate__(self) -> Dict[str, Any]: ...
|
||||
# __and__ and __or__ ignore the other QuerySet's _Row type parameter because they use the same row type as the self QuerySet.
|
||||
def __getitem__(self, s: slice) -> ValuesQuerySet[_T, _Row]: ...
|
||||
# Technically, the other QuerySet must be of the same type _T, but _T is covariant
|
||||
def __and__(self, other: QuerySet[_T, Any]) -> QuerySet[_T, _Row]: ...
|
||||
def __or__(self, other: QuerySet[_T, Any]) -> QuerySet[_T, _Row]: ...
|
||||
def iterator(self, chunk_size: int = ...) -> Iterator[_Row]: ...
|
||||
def aggregate(self, *args: Any, **kwargs: Any) -> Dict[str, Any]: ...
|
||||
def get(self, *args: Any, **kwargs: Any) -> _Row: ...
|
||||
def create(self, *args: Any, **kwargs: Any) -> _T: ...
|
||||
def bulk_create(
|
||||
self, objs: Iterable[Model], batch_size: Optional[int] = ..., ignore_conflicts: bool = ...
|
||||
) -> List[_T]: ...
|
||||
def get_or_create(self, defaults: Optional[MutableMapping[str, Any]] = ..., **kwargs: Any) -> Tuple[_T, bool]: ...
|
||||
def update_or_create(
|
||||
self, defaults: Optional[MutableMapping[str, Any]] = ..., **kwargs: Any
|
||||
) -> Tuple[_T, bool]: ...
|
||||
def earliest(self, *fields: Any, field_name: Optional[Any] = ...) -> _Row: ...
|
||||
def latest(self, *fields: Any, field_name: Optional[Any] = ...) -> _Row: ...
|
||||
# technically it's Optional[_Row], but it creates a lot of false-positives (same for last())
|
||||
def first(self) -> _Row: ...
|
||||
def last(self) -> _Row: ...
|
||||
def in_bulk(self, id_list: Iterable[Any] = ..., *, field_name: str = ...) -> Dict[Any, _T]: ...
|
||||
def delete(self) -> Tuple[int, Dict[str, int]]: ...
|
||||
def update(self, **kwargs: Any) -> int: ...
|
||||
def exists(self) -> bool: ...
|
||||
def explain(self, *, format: Optional[Any] = ..., **options: Any) -> str: ...
|
||||
def raw(
|
||||
self,
|
||||
raw_query: str,
|
||||
params: Any = ...,
|
||||
translations: Optional[Dict[str, str]] = ...,
|
||||
using: Optional[str] = ...,
|
||||
) -> RawQuerySet: ...
|
||||
# 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) -> QuerySet[_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
|
||||
def values_list(
|
||||
self, *fields: Union[str, Combinable], flat: bool = ..., named: bool = ...
|
||||
) -> QuerySet[_T, Any]: ...
|
||||
def dates(self, field_name: str, kind: str, order: str = ...) -> QuerySet[_T, datetime.date]: ...
|
||||
def datetimes(
|
||||
self, field_name: str, kind: str, order: str = ..., tzinfo: None = ...
|
||||
) -> QuerySet[_T, datetime.datetime]: ...
|
||||
def none(self) -> QuerySet[_T, _Row]: ...
|
||||
def all(self) -> QuerySet[_T, _Row]: ...
|
||||
def filter(self, *args: Any, **kwargs: Any) -> QuerySet[_T, _Row]: ...
|
||||
def exclude(self, *args: Any, **kwargs: Any) -> QuerySet[_T, _Row]: ...
|
||||
def complex_filter(self, filter_obj: Any) -> QuerySet[_T, _Row]: ...
|
||||
def __and__(self, other: ValuesQuerySet[_T, _Row]) -> ValuesQuerySet[_T, _Row]: ... # type: ignore
|
||||
def __or__(self, other: ValuesQuerySet[_T, _Row]) -> ValuesQuerySet[_T, _Row]: ... # type: ignore
|
||||
def iterator(self, chunk_size: int = ...) -> Iterator[_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 latest(self, *fields: Any, field_name: Optional[Any] = ...) -> _Row: ... # type: ignore
|
||||
def first(self) -> Optional[_Row]: ... # type: ignore
|
||||
def last(self) -> Optional[_Row]: ... # type: ignore
|
||||
def none(self) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def all(self) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def filter(self, *args: Any, **kwargs: Any) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def exclude(self, *args: Any, **kwargs: Any) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def complex_filter(self, filter_obj: Any) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def count(self) -> int: ...
|
||||
def union(self, *other_qs: Any, all: bool = ...) -> QuerySet[_T, _Row]: ...
|
||||
def intersection(self, *other_qs: Any) -> QuerySet[_T, _Row]: ...
|
||||
def difference(self, *other_qs: Any) -> QuerySet[_T, _Row]: ...
|
||||
def select_for_update(self, nowait: bool = ..., skip_locked: bool = ..., of: Tuple = ...) -> QuerySet[_T, _Row]: ...
|
||||
def select_related(self, *fields: Any) -> QuerySet[_T, _Row]: ...
|
||||
def prefetch_related(self, *lookups: Any) -> QuerySet[_T, _Row]: ...
|
||||
def union(self, *other_qs: Any, all: bool = ...) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def intersection(self, *other_qs: Any) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def difference(self, *other_qs: Any) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def select_for_update(
|
||||
self, nowait: bool = ..., skip_locked: bool = ..., of: Tuple = ...
|
||||
) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def select_related(self, *fields: Any) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def prefetch_related(self, *lookups: Any) -> ValuesQuerySet[_T, _Row]: ...
|
||||
# TODO: return type
|
||||
def annotate(self, *args: Any, **kwargs: Any) -> QuerySet[Any, Any]: ...
|
||||
def order_by(self, *field_names: Any) -> QuerySet[_T, _Row]: ...
|
||||
def distinct(self, *field_names: Any) -> QuerySet[_T, _Row]: ...
|
||||
def annotate(self, *args: Any, **kwargs: Any) -> QuerySet[Any]: ...
|
||||
def order_by(self, *field_names: Any) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def distinct(self, *field_names: Any) -> ValuesQuerySet[_T, _Row]: ...
|
||||
# extra() return type won't be supported any time soon
|
||||
def extra(
|
||||
self,
|
||||
@@ -138,18 +194,11 @@ class QuerySet(Generic[_T, _Row], Collection[_Row], Sized):
|
||||
tables: Optional[List[str]] = ...,
|
||||
order_by: Optional[Sequence[str]] = ...,
|
||||
select_params: Optional[Sequence[Any]] = ...,
|
||||
) -> QuerySet[Any, Any]: ...
|
||||
def reverse(self) -> QuerySet[_T, _Row]: ...
|
||||
def defer(self, *fields: Any) -> QuerySet[_T, _Row]: ...
|
||||
def only(self, *fields: Any) -> QuerySet[_T, _Row]: ...
|
||||
def using(self, alias: Optional[str]) -> QuerySet[_T, _Row]: ...
|
||||
@property
|
||||
def ordered(self) -> bool: ...
|
||||
@property
|
||||
def db(self) -> str: ...
|
||||
def resolve_expression(self, *args: Any, **kwargs: Any) -> Any: ...
|
||||
# TODO: remove when django adds __class_getitem__ methods
|
||||
def __getattr__(self, item: str) -> Any: ...
|
||||
) -> QuerySet[Any]: ...
|
||||
def reverse(self) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def defer(self, *fields: Any) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def only(self, *fields: Any) -> ValuesQuerySet[_T, _Row]: ...
|
||||
def using(self, alias: Optional[str]) -> ValuesQuerySet[_T, _Row]: ...
|
||||
|
||||
class RawQuerySet(Iterable[_T], Sized):
|
||||
query: RawQuery
|
||||
|
||||
@@ -31,6 +31,6 @@ def redirect(
|
||||
|
||||
_T = TypeVar("_T", bound=Model)
|
||||
|
||||
def get_object_or_404(klass: Union[Type[_T], Manager[_T], QuerySet[_T, _T]], *args: Any, **kwargs: Any) -> _T: ...
|
||||
def get_list_or_404(klass: Union[Type[_T], Manager[_T], QuerySet[_T, _T]], *args: Any, **kwargs: Any) -> List[_T]: ...
|
||||
def get_object_or_404(klass: Union[Type[_T], Manager[_T], QuerySet[_T]], *args: Any, **kwargs: Any) -> _T: ...
|
||||
def get_list_or_404(klass: Union[Type[_T], Manager[_T], QuerySet[_T]], *args: Any, **kwargs: Any) -> List[_T]: ...
|
||||
def resolve_url(to: Union[Callable, Model, str], *args: Any, **kwargs: Any) -> str: ...
|
||||
|
||||
@@ -7,7 +7,7 @@ from mypy.errors import Errors
|
||||
from mypy.nodes import MypyFile, TypeInfo
|
||||
from mypy.options import Options
|
||||
from mypy.plugin import (
|
||||
AnalyzeTypeContext, AttributeContext, ClassDefContext, FunctionContext, MethodContext, Plugin,
|
||||
AttributeContext, ClassDefContext, FunctionContext, MethodContext, Plugin,
|
||||
)
|
||||
from mypy.types import Type as MypyType
|
||||
|
||||
@@ -233,15 +233,6 @@ class NewSemanalDjangoPlugin(Plugin):
|
||||
return partial(request.set_auth_user_model_as_type_for_request_user, django_context=self.django_context)
|
||||
return None
|
||||
|
||||
def get_type_analyze_hook(self, fullname: str
|
||||
) -> Optional[Callable[[AnalyzeTypeContext], MypyType]]:
|
||||
info = self._get_typeinfo_or_none(fullname)
|
||||
if (info
|
||||
and info.has_base(fullnames.QUERYSET_CLASS_FULLNAME)
|
||||
and not info.has_base(fullnames.BASE_MANAGER_CLASS_FULLNAME)):
|
||||
return partial(querysets.set_first_generic_param_as_default_for_second, fullname=fullname)
|
||||
return None
|
||||
|
||||
|
||||
def plugin(version):
|
||||
return NewSemanalDjangoPlugin
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
from collections import OrderedDict
|
||||
from typing import List, Optional, Sequence, Type, Union, cast
|
||||
from typing import List, Optional, Sequence, Type, Union
|
||||
|
||||
from django.core.exceptions import FieldError
|
||||
from django.db.models.base import Model
|
||||
from django.db.models.fields.related import RelatedField
|
||||
from mypy.newsemanal.typeanal import TypeAnalyser
|
||||
from mypy.nodes import Expression, NameExpr, TypeInfo
|
||||
from mypy.plugin import AnalyzeTypeContext, FunctionContext, MethodContext
|
||||
from mypy.types import AnyType, Instance
|
||||
from mypy.types import Type as MypyType
|
||||
from mypy.types import TypeOfAny
|
||||
from mypy.nodes import Expression, NameExpr
|
||||
from mypy.plugin import FunctionContext, MethodContext
|
||||
from mypy.types import AnyType, Instance, Type as MypyType, TypeOfAny
|
||||
|
||||
from mypy_django_plugin.django.context import DjangoContext
|
||||
from mypy_django_plugin.lib import fullnames, helpers
|
||||
@@ -183,20 +180,3 @@ def extract_proper_type_queryset_values(ctx: MethodContext, django_context: Djan
|
||||
|
||||
row_type = helpers.make_typeddict(ctx.api, column_types, set(column_types.keys()))
|
||||
return helpers.reparametrize_instance(ctx.default_return_type, [model_type, row_type])
|
||||
|
||||
|
||||
def set_first_generic_param_as_default_for_second(ctx: AnalyzeTypeContext, fullname: str) -> MypyType:
|
||||
type_analyser_api = cast(TypeAnalyser, ctx.api)
|
||||
|
||||
info = helpers.lookup_fully_qualified_typeinfo(type_analyser_api.api, fullname) # type: ignore
|
||||
assert isinstance(info, TypeInfo)
|
||||
|
||||
if not ctx.type.args:
|
||||
return Instance(info, [AnyType(TypeOfAny.explicit), AnyType(TypeOfAny.explicit)])
|
||||
|
||||
args = ctx.type.args
|
||||
if len(args) == 1:
|
||||
args = [args[0], args[0]]
|
||||
|
||||
analyzed_args = [type_analyser_api.analyze_type(arg) for arg in args]
|
||||
return Instance(info, analyzed_args)
|
||||
|
||||
@@ -28,7 +28,6 @@ IGNORED_ERRORS = {
|
||||
'Cannot assign to a type',
|
||||
'"HttpResponse" has no attribute',
|
||||
'"HttpResponseBase" has no attribute',
|
||||
# '"HttpRequest" has no attribute',
|
||||
'"object" has no attribute',
|
||||
'defined in the current module',
|
||||
re.compile(r'"Callable\[(\[(Any(, )?)*((, )?VarArg\(Any\))?((, )?KwArg\(Any\))?\]|\.\.\.), Any\]" '
|
||||
@@ -73,6 +72,12 @@ IGNORED_ERRORS = {
|
||||
'Incompatible types in assignment (expression has type "Callable[',
|
||||
'SimpleLazyObject'
|
||||
],
|
||||
'aggregation': [
|
||||
re.compile(r'got "Optional\[(Author|Publisher)\]", expected "Union\[(Author|Publisher), Combinable\]"')
|
||||
],
|
||||
'annotations': [
|
||||
'Incompatible type for "store" of "Employee" (got "Optional[Store]", expected "Union[Store, Combinable]")'
|
||||
],
|
||||
'apps': [
|
||||
'Incompatible types in assignment (expression has type "str", target has type "type")',
|
||||
],
|
||||
@@ -114,7 +119,8 @@ IGNORED_ERRORS = {
|
||||
'custom_managers': [
|
||||
'Unsupported dynamic base class',
|
||||
'"Book" has no attribute "favorite_avg"',
|
||||
'Incompatible types in assignment (expression has type "CharField'
|
||||
'Incompatible types in assignment (expression has type "CharField',
|
||||
'Item "Book" of "Optional[Book]" has no attribute "favorite_avg"'
|
||||
],
|
||||
'csrf_tests': [
|
||||
'Incompatible types in assignment (expression has type "property", ' +
|
||||
@@ -135,6 +141,7 @@ IGNORED_ERRORS = {
|
||||
],
|
||||
'db_functions': [
|
||||
'"FloatModel" has no attribute',
|
||||
'Incompatible types in assignment (expression has type "Optional[Any]", variable has type "FloatModel")'
|
||||
],
|
||||
'decorators': [
|
||||
'"Type[object]" has no attribute "method"'
|
||||
@@ -164,9 +171,9 @@ IGNORED_ERRORS = {
|
||||
],
|
||||
'get_object_or_404': [
|
||||
'Argument 1 to "get_object_or_404" has incompatible type "str"; '
|
||||
+ 'expected "Union[Type[<nothing>], QuerySet[<nothing>, <nothing>]]"',
|
||||
+ 'expected "Union[Type[<nothing>], QuerySet[<nothing>]]"',
|
||||
'Argument 1 to "get_list_or_404" has incompatible type "List[Type[Article]]"; '
|
||||
+ 'expected "Union[Type[<nothing>], QuerySet[<nothing>, <nothing>]]"',
|
||||
+ 'expected "Union[Type[<nothing>], QuerySet[<nothing>]]"',
|
||||
'CustomClass'
|
||||
],
|
||||
'generic_relations_regress': [
|
||||
@@ -234,7 +241,9 @@ IGNORED_ERRORS = {
|
||||
'"Dimension" has no attribute "set_component_order"',
|
||||
],
|
||||
'one_to_one': [
|
||||
'expression has type "None", variable has type "UndergroundBar"'
|
||||
'expression has type "None", variable has type "UndergroundBar"',
|
||||
'Item "OneToOneField[Union[Place, Combinable], Place]" '
|
||||
+ 'of "Union[OneToOneField[Union[Place, Combinable], Place], Any]"',
|
||||
],
|
||||
'postgres_tests': [
|
||||
'DummyArrayField',
|
||||
@@ -255,9 +264,9 @@ IGNORED_ERRORS = {
|
||||
'"Person" has no attribute "houses_lst"',
|
||||
'"Book" has no attribute "first_authors"',
|
||||
'"Book" has no attribute "the_authors"',
|
||||
'Incompatible types in assignment (expression has type "List[Room]", variable has type "QuerySet[Room, Room]")',
|
||||
'"Room" has no attribute "main_room_of_attr"',
|
||||
'"Room" has no attribute "house_attr"'
|
||||
'Incompatible types in assignment (expression has type "List[Room]", variable has type "QuerySet[Room]")',
|
||||
'Item "Room" of "Optional[Room]" has no attribute "house_attr"',
|
||||
'Item "Room" of "Optional[Room]" has no attribute "main_room_of_attr"'
|
||||
],
|
||||
'proxy_models': [
|
||||
'Incompatible types in assignment',
|
||||
@@ -266,8 +275,8 @@ IGNORED_ERRORS = {
|
||||
'queries': [
|
||||
'Incompatible types in assignment (expression has type "None", variable has type "str")',
|
||||
'Invalid index type "Optional[str]" for "Dict[str, int]"; expected type "str"',
|
||||
'Unsupported operand types for & ("QuerySet[Author, Author]" and "QuerySet[Tag, Tag]")',
|
||||
'Unsupported operand types for | ("QuerySet[Author, Author]" and "QuerySet[Tag, Tag]")',
|
||||
'Unsupported operand types for & ("QuerySet[Author]" and "QuerySet[Tag]")',
|
||||
'Unsupported operand types for | ("QuerySet[Author]" and "QuerySet[Tag]")',
|
||||
'ObjectA',
|
||||
'ObjectB',
|
||||
'ObjectC',
|
||||
@@ -293,6 +302,10 @@ IGNORED_ERRORS = {
|
||||
'Incompatible types in assignment (expression has type "None", variable has type "int")',
|
||||
'"AbstractBaseSession" has no attribute'
|
||||
],
|
||||
'select_related': [
|
||||
'Item "ForeignKey[Union[Genus, Combinable], Genus]" '
|
||||
+ 'of "Union[ForeignKey[Union[Genus, Combinable], Genus], Any]"'
|
||||
],
|
||||
'select_related_onetoone': [
|
||||
'Incompatible types in assignment (expression has type "Parent2", variable has type "Parent1")',
|
||||
'"Parent1" has no attribute'
|
||||
|
||||
@@ -3,22 +3,22 @@
|
||||
from myapp.models import Blog
|
||||
|
||||
qs = Blog.objects.all()
|
||||
reveal_type(qs) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*, myapp.models.Blog*]'
|
||||
reveal_type(qs) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*]'
|
||||
reveal_type(qs.get(id=1)) # N: Revealed type is 'myapp.models.Blog*'
|
||||
reveal_type(iter(qs)) # N: Revealed type is 'typing.Iterator[myapp.models.Blog*]'
|
||||
reveal_type(qs.iterator()) # N: Revealed type is 'typing.Iterator[myapp.models.Blog*]'
|
||||
reveal_type(qs.first()) # N: Revealed type is 'myapp.models.Blog*'
|
||||
reveal_type(qs.first()) # N: Revealed type is 'Union[myapp.models.Blog*, None]'
|
||||
reveal_type(qs.earliest()) # N: Revealed type is 'myapp.models.Blog*'
|
||||
reveal_type(qs[0]) # N: Revealed type is 'myapp.models.Blog*'
|
||||
reveal_type(qs[:9]) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*, myapp.models.Blog*]'
|
||||
reveal_type(qs[:9]) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*]'
|
||||
reveal_type(qs.in_bulk()) # N: Revealed type is 'builtins.dict[Any, myapp.models.Blog*]'
|
||||
|
||||
# .dates / .datetimes
|
||||
reveal_type(Blog.objects.dates("created_at", "day")) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*, datetime.date]'
|
||||
reveal_type(Blog.objects.datetimes("created_at", "day")) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*, datetime.datetime]'
|
||||
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]'
|
||||
|
||||
# AND-ing QuerySets
|
||||
reveal_type(Blog.objects.all() & Blog.objects.all()) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*, myapp.models.Blog*]'
|
||||
reveal_type(Blog.objects.all() & Blog.objects.all()) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog*]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
@@ -28,11 +28,4 @@
|
||||
from django.db import models
|
||||
|
||||
class Blog(models.Model):
|
||||
created_at = models.DateTimeField()
|
||||
|
||||
- case: queryset_could_be_specified_with_one_type
|
||||
main: |
|
||||
from typing import Optional
|
||||
from django.db import models
|
||||
queryset: models.QuerySet[models.Model] = models.QuerySet()
|
||||
reveal_type(queryset) # N: Revealed type is 'django.db.models.query.QuerySet[django.db.models.base.Model, django.db.models.base.Model]'
|
||||
created_at = models.DateTimeField()
|
||||
@@ -192,8 +192,8 @@
|
||||
- case: values_list_flat_true_with_ids
|
||||
main: |
|
||||
from myapp.models import Blog, Publisher
|
||||
reveal_type(Blog.objects.values_list('id', flat=True)) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Blog, builtins.int]'
|
||||
reveal_type(Blog.objects.values_list('publisher_id', flat=True)) # N: Revealed type is 'django.db.models.query.QuerySet[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]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
@@ -210,8 +210,8 @@
|
||||
main: |
|
||||
from myapp.models import TransactionQuerySet
|
||||
reveal_type(TransactionQuerySet()) # N: Revealed type is 'myapp.models.TransactionQuerySet'
|
||||
reveal_type(TransactionQuerySet().values()) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Transaction, TypedDict({'id': builtins.int, 'total': builtins.int})]'
|
||||
reveal_type(TransactionQuerySet().values_list()) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.Transaction, Tuple[builtins.int, 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]]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
|
||||
@@ -197,10 +197,10 @@
|
||||
main: |
|
||||
from myapp.models import UnrelatedModel, MyModel
|
||||
reveal_type(UnrelatedModel.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.UnrelatedModel]'
|
||||
reveal_type(UnrelatedModel.objects.first()) # N: Revealed type is 'myapp.models.UnrelatedModel*'
|
||||
reveal_type(UnrelatedModel.objects.first()) # N: Revealed type is 'Union[myapp.models.UnrelatedModel*, None]'
|
||||
|
||||
reveal_type(MyModel.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel]'
|
||||
reveal_type(MyModel.objects.first()) # N: Revealed type is 'myapp.models.MyModel*'
|
||||
reveal_type(MyModel.objects.first()) # N: Revealed type is 'Union[myapp.models.MyModel*, None]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
@@ -218,10 +218,10 @@
|
||||
main: |
|
||||
from myapp.models import UnrelatedModel2, MyModel2
|
||||
reveal_type(UnrelatedModel2.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.UnrelatedModel2]'
|
||||
reveal_type(UnrelatedModel2.objects.first()) # N: Revealed type is 'myapp.models.UnrelatedModel2*'
|
||||
reveal_type(UnrelatedModel2.objects.first()) # N: Revealed type is 'Union[myapp.models.UnrelatedModel2*, None]'
|
||||
|
||||
reveal_type(MyModel2.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel2]'
|
||||
reveal_type(MyModel2.objects.first()) # N: Revealed type is 'myapp.models.MyModel2*'
|
||||
reveal_type(MyModel2.objects.first()) # N: Revealed type is 'Union[myapp.models.MyModel2*, None]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
@@ -239,10 +239,10 @@
|
||||
main: |
|
||||
from myapp.models import ParentOfMyModel3, MyModel3
|
||||
reveal_type(ParentOfMyModel3.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.ParentOfMyModel3]'
|
||||
reveal_type(ParentOfMyModel3.objects.first()) # N: Revealed type is 'myapp.models.ParentOfMyModel3*'
|
||||
reveal_type(ParentOfMyModel3.objects.first()) # N: Revealed type is 'Union[myapp.models.ParentOfMyModel3*, None]'
|
||||
|
||||
reveal_type(MyModel3.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel3]'
|
||||
reveal_type(MyModel3.objects.first()) # N: Revealed type is 'myapp.models.MyModel3*'
|
||||
reveal_type(MyModel3.objects.first()) # N: Revealed type is 'Union[myapp.models.MyModel3*, None]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
@@ -260,10 +260,10 @@
|
||||
main: |
|
||||
from myapp.models import ParentOfMyModel4, MyModel4
|
||||
reveal_type(ParentOfMyModel4.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.ParentOfMyModel4]'
|
||||
reveal_type(ParentOfMyModel4.objects.first()) # N: Revealed type is 'myapp.models.ParentOfMyModel4*'
|
||||
reveal_type(ParentOfMyModel4.objects.first()) # N: Revealed type is 'Union[myapp.models.ParentOfMyModel4*, None]'
|
||||
|
||||
reveal_type(MyModel4.objects) # N: Revealed type is 'django.db.models.manager.Manager[myapp.models.MyModel4]'
|
||||
reveal_type(MyModel4.objects.first()) # N: Revealed type is 'myapp.models.MyModel4*'
|
||||
reveal_type(MyModel4.objects.first()) # N: Revealed type is 'Union[myapp.models.MyModel4*, None]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
@@ -308,7 +308,7 @@
|
||||
main: |
|
||||
from myapp.models import User
|
||||
reveal_type(User.objects.get()) # N: Revealed type is 'myapp.models.User*'
|
||||
reveal_type(User.objects.select_related()) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.User*, myapp.models.User*]'
|
||||
reveal_type(User.objects.select_related()) # N: Revealed type is 'django.db.models.query.QuerySet[myapp.models.User*]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
|
||||
Reference in New Issue
Block a user