mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-06 12:14:28 +08:00
various fixes
This commit is contained in:
@@ -54,29 +54,16 @@ class GenericForeignKey(FieldCacheMixin):
|
||||
|
||||
class GenericRel(ForeignObjectRel):
|
||||
field: GenericRelation
|
||||
limit_choices_to: Optional[Union[Dict[str, Any], Callable[[], Any]]]
|
||||
model: Type[Model]
|
||||
multiple: bool
|
||||
on_delete: Callable
|
||||
parent_link: bool
|
||||
related_name: str
|
||||
related_query_name: None
|
||||
symmetrical: bool
|
||||
def __init__(
|
||||
self,
|
||||
field: GenericRelation,
|
||||
to: Union[Type[Model], str],
|
||||
related_name: None = ...,
|
||||
related_name: Optional[str] = ...,
|
||||
related_query_name: Optional[str] = ...,
|
||||
limit_choices_to: Optional[Union[Dict[str, Any], Callable[[], Any]]] = ...,
|
||||
) -> None: ...
|
||||
|
||||
class GenericRelation(ForeignObject):
|
||||
auto_created: bool = ...
|
||||
many_to_many: bool = ...
|
||||
many_to_one: bool = ...
|
||||
one_to_many: bool = ...
|
||||
one_to_one: bool = ...
|
||||
rel_class: Any = ...
|
||||
mti_inherited: bool = ...
|
||||
object_id_field_name: Any = ...
|
||||
@@ -93,23 +80,16 @@ class GenericRelation(ForeignObject):
|
||||
limit_choices_to: Optional[Union[Dict[str, Any], Callable[[], Any]]] = ...,
|
||||
**kwargs: Any
|
||||
) -> None: ...
|
||||
def check(self, **kwargs: Any) -> List[Error]: ...
|
||||
def resolve_related_fields(self) -> List[Tuple[PositiveIntegerField, Field]]: ...
|
||||
def get_path_info(self, filtered_relation: Optional[FilteredRelation] = ...) -> List[PathInfo]: ...
|
||||
def get_reverse_path_info(self, filtered_relation: None = ...) -> List[PathInfo]: ...
|
||||
def value_to_string(self, obj: Model) -> str: ...
|
||||
model: Any = ...
|
||||
def set_attributes_from_rel(self) -> None: ...
|
||||
def get_internal_type(self) -> str: ...
|
||||
def get_content_type(self) -> ContentType: ...
|
||||
def get_extra_restriction(
|
||||
self, where_class: Type[WhereNode], alias: Optional[str], remote_alias: str
|
||||
) -> WhereNode: ...
|
||||
def bulk_related_objects(self, objs: List[Model], using: str = ...) -> QuerySet: ...
|
||||
|
||||
class ReverseGenericManyToOneDescriptor(ReverseManyToOneDescriptor):
|
||||
field: GenericRelation
|
||||
rel: GenericRel
|
||||
def related_manager_cls(self): ...
|
||||
class ReverseGenericManyToOneDescriptor(ReverseManyToOneDescriptor): ...
|
||||
|
||||
def create_generic_related_manager(superclass: Any, rel: Any): ...
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from django.core.checks.messages import Error
|
||||
from django.db.models.query import QuerySet
|
||||
from typing import Optional
|
||||
|
||||
from django.db import models
|
||||
|
||||
class CurrentSiteManager(models.Manager):
|
||||
creation_counter: int
|
||||
model: None
|
||||
name: None
|
||||
use_in_migrations: bool = ...
|
||||
def __init__(self, field_name: Optional[str] = ...) -> None: ...
|
||||
def check(self, **kwargs: Any) -> List[Error]: ...
|
||||
def get_queryset(self) -> QuerySet: ...
|
||||
|
||||
@@ -52,7 +52,6 @@ class BaseExpression:
|
||||
is_summary: bool = ...
|
||||
filterable: bool = ...
|
||||
window_compatible: bool = ...
|
||||
output_field: Field
|
||||
def __init__(self, output_field: Optional[_OutputField] = ...) -> None: ...
|
||||
def get_db_converters(self, connection: Any) -> List[Callable]: ...
|
||||
def get_source_expressions(self) -> List[Any]: ...
|
||||
@@ -74,6 +73,8 @@ class BaseExpression:
|
||||
@property
|
||||
def field(self) -> Field: ...
|
||||
@property
|
||||
def output_field(self) -> Field: ...
|
||||
@property
|
||||
def convert_value(self) -> Callable: ...
|
||||
def get_lookup(self, lookup: str) -> Optional[Type[Lookup]]: ...
|
||||
def get_transform(self, name: str) -> Optional[Type[Expression]]: ...
|
||||
|
||||
@@ -1,13 +1,27 @@
|
||||
import decimal
|
||||
import uuid
|
||||
from datetime import date, datetime, time, timedelta
|
||||
from typing import Any, Callable, Dict, Generic, Iterable, Optional, Tuple, Type, TypeVar, Union, Sequence, List
|
||||
from typing import (
|
||||
Any,
|
||||
Callable,
|
||||
Dict,
|
||||
Generic,
|
||||
Iterable,
|
||||
Optional,
|
||||
Tuple,
|
||||
Type,
|
||||
TypeVar,
|
||||
Union,
|
||||
Sequence,
|
||||
List,
|
||||
overload,
|
||||
)
|
||||
|
||||
from django.core import checks
|
||||
|
||||
from django.db.models import Model
|
||||
from django.core.exceptions import FieldDoesNotExist as FieldDoesNotExist
|
||||
from django.db.models.expressions import Combinable
|
||||
from django.db.models.expressions import Combinable, Col
|
||||
from django.db.models.query_utils import RegisterLookupMixin
|
||||
from django.forms import Field as FormField, Widget
|
||||
|
||||
@@ -20,6 +34,7 @@ _FieldChoices = Iterable[Union[_Choice, _ChoiceNamedGroup]]
|
||||
_ValidatorCallable = Callable[..., None]
|
||||
_ErrorMessagesToOverride = Dict[str, Any]
|
||||
|
||||
_T = TypeVar("_T", bound="Field")
|
||||
# __set__ value type
|
||||
_ST = TypeVar("_ST")
|
||||
# __get__ return type
|
||||
@@ -36,7 +51,7 @@ class Field(RegisterLookupMixin, Generic[_ST, _GT]):
|
||||
auto_created: bool
|
||||
primary_key: bool
|
||||
remote_field: Field
|
||||
max_length: Optional[int]
|
||||
max_length: int
|
||||
model: Type[Model]
|
||||
name: str
|
||||
verbose_name: str
|
||||
@@ -72,6 +87,11 @@ class Field(RegisterLookupMixin, Generic[_ST, _GT]):
|
||||
error_messages: Optional[_ErrorMessagesToOverride] = ...,
|
||||
): ...
|
||||
def __set__(self, instance, value: _ST) -> None: ...
|
||||
# class access
|
||||
@overload
|
||||
def __get__(self: _T, instance: None, owner) -> _T: ...
|
||||
# instance access
|
||||
@overload
|
||||
def __get__(self, instance, owner) -> _GT: ...
|
||||
def deconstruct(self) -> Any: ...
|
||||
def set_attributes_from_name(self, name: str) -> None: ...
|
||||
@@ -96,6 +116,10 @@ class Field(RegisterLookupMixin, Generic[_ST, _GT]):
|
||||
def check(self, **kwargs: Any) -> List[checks.Error]: ...
|
||||
@property
|
||||
def validators(self) -> List[_ValidatorCallable]: ...
|
||||
def get_col(self, alias: str, output_field: Optional[Field] = ...) -> Col: ...
|
||||
@property
|
||||
def cached_col(self) -> Col: ...
|
||||
def value_from_object(self, obj: Model) -> _GT: ...
|
||||
|
||||
class IntegerField(Field[_ST, _GT]):
|
||||
_pyi_private_set_type: Union[float, int, str, Combinable]
|
||||
|
||||
@@ -1,39 +1,25 @@
|
||||
from typing import (
|
||||
Type,
|
||||
Union,
|
||||
TypeVar,
|
||||
Any,
|
||||
Generic,
|
||||
List,
|
||||
Optional,
|
||||
Dict,
|
||||
Callable,
|
||||
Tuple,
|
||||
Sequence,
|
||||
TYPE_CHECKING,
|
||||
Iterable,
|
||||
)
|
||||
from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, TYPE_CHECKING, Tuple, Type, TypeVar, Union
|
||||
from uuid import UUID
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Field, Model, QuerySet
|
||||
from django.db.models.expressions import Combinable
|
||||
from django.db.models.fields.mixins import FieldCacheMixin
|
||||
from django.db.models.query_utils import PathInfo, Q
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Field, Model
|
||||
from django.db.models.fields.related_descriptors import (
|
||||
ReverseManyToOneDescriptor as ReverseManyToOneDescriptor,
|
||||
ReverseOneToOneDescriptor as ReverseOneToOneDescriptor,
|
||||
ForwardManyToOneDescriptor as ForwardManyToOneDescriptor,
|
||||
ForwardOneToOneDescriptor as ForwardOneToOneDescriptor,
|
||||
ForwardManyToOneDescriptor as ForwardManyToOneDescriptor,
|
||||
ManyToManyDescriptor as ManyToManyDescriptor,
|
||||
ReverseOneToOneDescriptor as ReverseOneToOneDescriptor,
|
||||
ReverseManyToOneDescriptor as ReverseManyToOneDescriptor,
|
||||
)
|
||||
from django.db.models.fields.reverse_related import (
|
||||
ForeignObjectRel as ForeignObjectRel,
|
||||
ManyToManyRel as ManyToManyRel,
|
||||
ManyToOneRel as ManyToOneRel,
|
||||
OneToOneRel as OneToOneRel,
|
||||
ManyToOneRel as ManyToOneRel,
|
||||
ManyToManyRel as ManyToManyRel,
|
||||
)
|
||||
from django.db.models.query_utils import PathInfo, Q
|
||||
|
||||
from django.db.models.expressions import Combinable
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from django.db.models.manager import RelatedManager
|
||||
@@ -61,14 +47,11 @@ class RelatedField(FieldCacheMixin, Field[_ST, _GT]):
|
||||
many_to_one: bool = ...
|
||||
@property
|
||||
def related_model(self) -> Union[Type[Model], str]: ...
|
||||
def check(self, **kwargs: Any) -> List[Any]: ...
|
||||
opts: Any = ...
|
||||
def get_forward_related_filter(self, obj: Model) -> Dict[str, Union[int, UUID]]: ...
|
||||
def get_reverse_related_filter(self, obj: Model) -> Q: ...
|
||||
@property
|
||||
def swappable_setting(self) -> Optional[str]: ...
|
||||
name: Any = ...
|
||||
verbose_name: Any = ...
|
||||
def set_attributes_from_rel(self) -> None: ...
|
||||
def do_related_class(self, other: Type[Model], cls: Type[Model]) -> None: ...
|
||||
def get_limit_choices_to(self) -> Dict[str, int]: ...
|
||||
@@ -188,7 +171,14 @@ class ManyToManyField(RelatedField[_ST, _GT]):
|
||||
rel_class: Any = ...
|
||||
description: Any = ...
|
||||
has_null_arg: Any = ...
|
||||
swappable: Any = ...
|
||||
swappable: bool = ...
|
||||
m2m_db_table: str = ...
|
||||
m2m_column_name: str = ...
|
||||
m2m_reverse_name: str = ...
|
||||
m2m_field_name: str = ...
|
||||
m2m_reverse_field_name: str = ...
|
||||
m2m_target_field_name: str = ...
|
||||
m2m_reverse_target_field_name: str = ...
|
||||
def __init__(
|
||||
self,
|
||||
to: Union[Type[_T], str],
|
||||
@@ -223,19 +213,9 @@ class ManyToManyField(RelatedField[_ST, _GT]):
|
||||
validators: Iterable[_ValidatorCallable] = ...,
|
||||
error_messages: Optional[_ErrorMessagesToOverride] = ...,
|
||||
) -> None: ...
|
||||
def check(self, **kwargs: Any) -> List[Any]: ...
|
||||
def __get__(self, instance, owner) -> _GT: ... # type: ignore
|
||||
def get_path_info(self, filtered_relation: None = ...) -> List[PathInfo]: ...
|
||||
def get_reverse_path_info(self, filtered_relation: None = ...) -> List[PathInfo]: ...
|
||||
m2m_db_table: Any = ...
|
||||
m2m_column_name: Any = ...
|
||||
m2m_reverse_name: Any = ...
|
||||
m2m_field_name: Any = ...
|
||||
m2m_reverse_field_name: Any = ...
|
||||
m2m_target_field_name: Any = ...
|
||||
m2m_reverse_target_field_name: Any = ...
|
||||
def contribute_to_related_class(self, cls: Type[Model], related: RelatedField) -> None: ...
|
||||
def set_attributes_from_rel(self) -> None: ...
|
||||
def value_from_object(self, obj: Model) -> List[Model]: ...
|
||||
def save_form_data(self, instance: Model, data: QuerySet) -> None: ...
|
||||
|
||||
def create_many_to_many_intermediary_model(field: Type[Field], klass: Type[Model]) -> Type[Model]: ...
|
||||
|
||||
@@ -10,13 +10,10 @@ from django.db.models.sql.where import WhereNode
|
||||
from .mixins import FieldCacheMixin
|
||||
|
||||
class ForeignObjectRel(FieldCacheMixin):
|
||||
hidden: bool
|
||||
many_to_many: bool
|
||||
many_to_one: bool
|
||||
name: str
|
||||
one_to_many: bool
|
||||
one_to_one: bool
|
||||
related_model: Type[Model]
|
||||
auto_created: bool = ...
|
||||
concrete: bool = ...
|
||||
editable: bool = ...
|
||||
@@ -43,6 +40,12 @@ class ForeignObjectRel(FieldCacheMixin):
|
||||
on_delete: Optional[Callable] = ...,
|
||||
) -> None: ...
|
||||
@property
|
||||
def hidden(self) -> bool: ...
|
||||
@property
|
||||
def name(self) -> str: ...
|
||||
@property
|
||||
def related_model(self) -> Type[Model]: ...
|
||||
@property
|
||||
def remote_field(self) -> RelatedField: ...
|
||||
@property
|
||||
def target_field(self) -> AutoField: ...
|
||||
@@ -63,22 +66,6 @@ class ForeignObjectRel(FieldCacheMixin):
|
||||
def get_path_info(self, filtered_relation: Optional[FilteredRelation] = ...) -> List[PathInfo]: ...
|
||||
|
||||
class ManyToOneRel(ForeignObjectRel):
|
||||
field: RelatedField
|
||||
hidden: bool
|
||||
limit_choices_to: Any
|
||||
many_to_many: bool
|
||||
many_to_one: bool
|
||||
model: Union[Type[Model], str]
|
||||
multiple: bool
|
||||
name: str
|
||||
on_delete: Callable
|
||||
one_to_many: bool
|
||||
one_to_one: bool
|
||||
parent_link: bool
|
||||
related_model: Type[Model]
|
||||
related_name: Optional[str]
|
||||
related_query_name: Optional[str]
|
||||
symmetrical: bool
|
||||
def __init__(
|
||||
self,
|
||||
field: ForeignKey,
|
||||
@@ -91,25 +78,8 @@ class ManyToOneRel(ForeignObjectRel):
|
||||
on_delete: Callable = ...,
|
||||
) -> None: ...
|
||||
def get_related_field(self) -> Field: ...
|
||||
def set_field_name(self) -> None: ...
|
||||
|
||||
class OneToOneRel(ManyToOneRel):
|
||||
field_name: Optional[str]
|
||||
hidden: bool
|
||||
limit_choices_to: Dict[str, str]
|
||||
many_to_many: bool
|
||||
many_to_one: bool
|
||||
model: Union[Type[Model], str]
|
||||
name: str
|
||||
on_delete: Callable
|
||||
one_to_many: bool
|
||||
one_to_one: bool
|
||||
parent_link: bool
|
||||
related_model: Type[Model]
|
||||
related_name: Optional[str]
|
||||
related_query_name: Optional[str]
|
||||
symmetrical: bool
|
||||
multiple: bool = ...
|
||||
def __init__(
|
||||
self,
|
||||
field: OneToOneField,
|
||||
@@ -123,14 +93,8 @@ class OneToOneRel(ManyToOneRel):
|
||||
) -> None: ...
|
||||
|
||||
class ManyToManyRel(ForeignObjectRel):
|
||||
field_name: None
|
||||
multiple: bool
|
||||
name: str
|
||||
parent_link: bool
|
||||
related_model: Type[Model]
|
||||
through: Optional[Union[Type[Model], str]] = ...
|
||||
through_fields: Optional[Tuple[str, str]] = ...
|
||||
symmetrical: bool = ...
|
||||
db_constraint: bool = ...
|
||||
def __init__(
|
||||
self,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from collections import OrderedDict
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional, Tuple, Type, Union, Iterable
|
||||
from typing import Any, Dict, Iterable, List, Optional, Tuple, Type, Union, Mapping
|
||||
|
||||
from django.db.backends.sqlite3.base import DatabaseWrapper
|
||||
from django.db.models.expressions import Combinable, Expression, Func
|
||||
@@ -10,22 +10,21 @@ from django.db.models.sql.query import Query
|
||||
from django.utils.datastructures import OrderedSet
|
||||
from django.utils.safestring import SafeText
|
||||
|
||||
from django.db.models import lookups
|
||||
from django.db.models.fields import TextField, related_lookups, Field
|
||||
from django.db.models.fields import TextField, related_lookups
|
||||
|
||||
class Lookup:
|
||||
lookup_name: Any = ...
|
||||
lookup_name: str = ...
|
||||
prepare_rhs: bool = ...
|
||||
can_use_none_as_rhs: bool = ...
|
||||
lhs: Any = ...
|
||||
rhs: Any = ...
|
||||
bilateral_transforms: Any = ...
|
||||
bilateral_transforms: List[Type[Transform]] = ...
|
||||
def __init__(self, lhs: Union[Expression, TextField, related_lookups.MultiColSource], rhs: Any) -> None: ...
|
||||
def apply_bilateral_transforms(self, value: Expression) -> Transform: ...
|
||||
def batch_process_rhs(
|
||||
self, compiler: SQLCompiler, connection: DatabaseWrapper, rhs: Optional[OrderedSet] = ...
|
||||
) -> Tuple[List[str], List[str]]: ...
|
||||
def get_source_expressions(self) -> List[Expression]: ...
|
||||
lhs: Any = ...
|
||||
def set_source_expressions(self, new_exprs: List[Expression]) -> None: ...
|
||||
def get_prep_lookup(self) -> Any: ...
|
||||
def get_db_prep_lookup(self, value: Union[int, str], connection: DatabaseWrapper) -> Tuple[str, List[SafeText]]: ...
|
||||
@@ -36,20 +35,16 @@ class Lookup:
|
||||
self, compiler: SQLCompiler, connection: DatabaseWrapper
|
||||
) -> Tuple[str, Union[List[Union[int, str]], Tuple[int, int]]]: ...
|
||||
def rhs_is_direct_value(self) -> bool: ...
|
||||
def relabeled_clone(
|
||||
self, relabels: Union[Dict[Optional[str], str], OrderedDict]
|
||||
) -> Union[BuiltinLookup, FieldGetDbPrepValueMixin]: ...
|
||||
def relabeled_clone(self, relabels: Mapping[str, str]) -> Union[BuiltinLookup, FieldGetDbPrepValueMixin]: ...
|
||||
def get_group_by_cols(self) -> List[Expression]: ...
|
||||
def as_sql(self, compiler: Any, connection: Any) -> None: ...
|
||||
def as_sql(self, compiler: Any, connection: Any) -> Any: ...
|
||||
def contains_aggregate(self) -> bool: ...
|
||||
def contains_over_clause(self) -> bool: ...
|
||||
@property
|
||||
def is_summary(self): ...
|
||||
def is_summary(self) -> bool: ...
|
||||
|
||||
class Transform(RegisterLookupMixin, Func):
|
||||
bilateral: bool = ...
|
||||
arity: int = ...
|
||||
output_field: Field
|
||||
@property
|
||||
def lhs(self) -> Expression: ...
|
||||
def get_bilateral_transforms(self) -> List[Type[Transform]]: ...
|
||||
@@ -61,122 +56,51 @@ class FieldGetDbPrepValueMixin:
|
||||
get_db_prep_lookup_value_is_iterable: bool = ...
|
||||
|
||||
class FieldGetDbPrepValueIterableMixin(FieldGetDbPrepValueMixin):
|
||||
get_db_prep_lookup_value_is_iterable: bool = ...
|
||||
def get_prep_lookup(self) -> Iterable[Any]: ...
|
||||
def resolve_expression_parameter(
|
||||
self, compiler: SQLCompiler, connection: DatabaseWrapper, sql: str, param: Optional[Union[Combinable, int, str]]
|
||||
) -> Tuple[str, List[None]]: ...
|
||||
self, compiler: SQLCompiler, connection: DatabaseWrapper, sql: str, param: Any
|
||||
) -> Any: ...
|
||||
|
||||
class Exact(FieldGetDbPrepValueMixin, BuiltinLookup):
|
||||
bilateral_transforms: List[Type[lookups.Transform]]
|
||||
lookup_name: str = ...
|
||||
|
||||
class IExact(BuiltinLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
|
||||
class GreaterThan(FieldGetDbPrepValueMixin, BuiltinLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
|
||||
class GreaterThanOrEqual(FieldGetDbPrepValueMixin, BuiltinLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
|
||||
class LessThan(FieldGetDbPrepValueMixin, BuiltinLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
|
||||
class LessThanOrEqual(FieldGetDbPrepValueMixin, BuiltinLookup):
|
||||
bilateral_transforms: List[Type[lookups.Transform]]
|
||||
lookup_name: str = ...
|
||||
class Exact(FieldGetDbPrepValueMixin, BuiltinLookup): ...
|
||||
class IExact(BuiltinLookup): ...
|
||||
class GreaterThan(FieldGetDbPrepValueMixin, BuiltinLookup): ...
|
||||
class GreaterThanOrEqual(FieldGetDbPrepValueMixin, BuiltinLookup): ...
|
||||
class LessThan(FieldGetDbPrepValueMixin, BuiltinLookup): ...
|
||||
class LessThanOrEqual(FieldGetDbPrepValueMixin, BuiltinLookup): ...
|
||||
|
||||
class IntegerFieldFloatRounding:
|
||||
rhs: Any = ...
|
||||
def get_prep_lookup(self) -> Union[Combinable, Query, int]: ...
|
||||
def get_prep_lookup(self) -> Any: ...
|
||||
|
||||
class IntegerGreaterThanOrEqual(IntegerFieldFloatRounding, GreaterThanOrEqual): ...
|
||||
class IntegerLessThan(IntegerFieldFloatRounding, LessThan): ...
|
||||
|
||||
class In(FieldGetDbPrepValueIterableMixin, BuiltinLookup):
|
||||
bilateral_transforms: List[Type[lookups.Transform]]
|
||||
lookup_name: str = ...
|
||||
def get_rhs_op(self, connection: DatabaseWrapper, rhs: str) -> str: ...
|
||||
def split_parameter_list_as_sql(self, compiler: Any, connection: Any): ...
|
||||
|
||||
class PatternLookup(BuiltinLookup):
|
||||
param_pattern: str = ...
|
||||
prepare_rhs: bool = ...
|
||||
def get_rhs_op(self, connection: DatabaseWrapper, rhs: str) -> str: ...
|
||||
|
||||
class Contains(PatternLookup):
|
||||
bilateral_transforms: List[Type[lookups.Transform]]
|
||||
lookup_name: str = ...
|
||||
|
||||
class IContains(Contains):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
|
||||
class StartsWith(PatternLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
param_pattern: str = ...
|
||||
|
||||
class IStartsWith(StartsWith):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
|
||||
class EndsWith(PatternLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
param_pattern: str = ...
|
||||
|
||||
class IEndsWith(EndsWith):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
|
||||
class Range(FieldGetDbPrepValueIterableMixin, BuiltinLookup):
|
||||
bilateral_transforms: List[Type[lookups.Transform]]
|
||||
lookup_name: str = ...
|
||||
|
||||
class IsNull(BuiltinLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
prepare_rhs: bool = ...
|
||||
|
||||
class Regex(BuiltinLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
prepare_rhs: bool = ...
|
||||
|
||||
class IRegex(Regex):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
class Contains(PatternLookup): ...
|
||||
class IContains(Contains): ...
|
||||
class StartsWith(PatternLookup): ...
|
||||
class IStartsWith(StartsWith): ...
|
||||
class EndsWith(PatternLookup): ...
|
||||
class IEndsWith(EndsWith): ...
|
||||
class Range(FieldGetDbPrepValueIterableMixin, BuiltinLookup): ...
|
||||
class IsNull(BuiltinLookup): ...
|
||||
class Regex(BuiltinLookup): ...
|
||||
class IRegex(Regex): ...
|
||||
|
||||
class YearLookup(Lookup):
|
||||
def year_lookup_bounds(self, connection: DatabaseWrapper, year: int) -> List[str]: ...
|
||||
|
||||
class YearComparisonLookup(YearLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
def get_rhs_op(self, connection: DatabaseWrapper, rhs: str) -> str: ...
|
||||
def get_bound(self, start: datetime, finish: datetime) -> Any: ...
|
||||
|
||||
class YearExact(YearLookup, Exact):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
|
||||
class YearGt(YearComparisonLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
|
||||
class YearGte(YearComparisonLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
|
||||
class YearLt(YearComparisonLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
|
||||
class YearLte(YearComparisonLookup):
|
||||
bilateral_transforms: List[Any]
|
||||
lookup_name: str = ...
|
||||
class YearExact(YearLookup, Exact): ...
|
||||
class YearGt(YearComparisonLookup): ...
|
||||
class YearGte(YearComparisonLookup): ...
|
||||
class YearLt(YearComparisonLookup): ...
|
||||
class YearLte(YearComparisonLookup): ...
|
||||
|
||||
@@ -11,7 +11,6 @@ class BaseManager(QuerySet[_T, _T]):
|
||||
use_in_migrations: bool = ...
|
||||
model: Optional[Any] = ...
|
||||
name: Optional[Any] = ...
|
||||
def __new__(cls: Type[BaseManager], *args: Any, **kwargs: Any) -> BaseManager: ...
|
||||
def __init__(self) -> None: ...
|
||||
def deconstruct(self) -> Tuple[bool, str, None, Tuple, Dict[str, int]]: ...
|
||||
def check(self, **kwargs: Any) -> List[Any]: ...
|
||||
|
||||
@@ -29,7 +29,7 @@ def make_immutable_fields_list(
|
||||
name: str, data: Union[Iterator[Any], List[Union[ArrayField, CIText]], List[Union[Field, FieldCacheMixin]]]
|
||||
) -> ImmutableList: ...
|
||||
|
||||
_M = TypeVar('_M', bound=Model)
|
||||
_M = TypeVar("_M", bound=Model)
|
||||
|
||||
class Options(Generic[_M]):
|
||||
base_manager: Manager
|
||||
@@ -81,6 +81,8 @@ class Options(Generic[_M]):
|
||||
related_fkey_lookups: List[Any] = ...
|
||||
apps: Apps = ...
|
||||
default_related_name: None = ...
|
||||
model: Type[Model] = ...
|
||||
original_attrs: Dict[str, Any] = ...
|
||||
def __init__(self, meta: Optional[type], app_label: Optional[str] = ...) -> None: ...
|
||||
@property
|
||||
def label(self) -> str: ...
|
||||
@@ -90,8 +92,6 @@ class Options(Generic[_M]):
|
||||
def app_config(self) -> AppConfig: ...
|
||||
@property
|
||||
def installed(self): ...
|
||||
model: Type[Model] = ...
|
||||
original_attrs: Dict[str, Union[List[str], Apps, str]] = ...
|
||||
def contribute_to_class(self, cls: Type[Model], name: str) -> None: ...
|
||||
def add_manager(self, manager: Manager) -> None: ...
|
||||
def add_field(self, field: Union[GenericForeignKey, Field], private: bool = ...) -> None: ...
|
||||
@@ -102,8 +102,10 @@ class Options(Generic[_M]):
|
||||
def verbose_name_raw(self) -> Any: ...
|
||||
@property
|
||||
def swapped(self) -> Optional[str]: ...
|
||||
def many_to_many(self) -> ImmutableList: ...
|
||||
def fields_map(self) -> Dict[str, ForeignObjectRel]: ...
|
||||
@property
|
||||
def many_to_many(self) -> List[ManyToManyField]: ...
|
||||
@property
|
||||
def fields_map(self) -> Dict[str, Union[Field, ForeignObjectRel]]: ...
|
||||
def get_field(self, field_name: Union[Callable, str]) -> Field: ...
|
||||
def get_base_chain(self, model: Type[Model]) -> List[Type[Model]]: ...
|
||||
def get_parent_list(self) -> List[Type[Model]]: ...
|
||||
|
||||
@@ -88,16 +88,20 @@ class QuerySet(Generic[_T, _Row], Collection[_Row], Sized):
|
||||
) -> Tuple[_T, bool]: ...
|
||||
def earliest(self, *fields: Any, field_name: Optional[Any] = ...) -> _Row: ...
|
||||
def latest(self, *fields: Any, field_name: Optional[Any] = ...) -> _Row: ...
|
||||
def first(self) -> Optional[_Row]: ...
|
||||
def last(self) -> Optional[_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 _update(self, values: Any) -> Optional[Any]: ...
|
||||
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: None = ...
|
||||
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]]: ...
|
||||
|
||||
@@ -20,7 +20,7 @@ class QueryWrapper:
|
||||
contains_aggregate: bool = ...
|
||||
data: Tuple[str, List[Any]] = ...
|
||||
def __init__(self, sql: str, params: List[Any]) -> None: ...
|
||||
def as_sql(self, compiler: SQLCompiler = ..., connection: Any = ...) -> Tuple[str, List[Any]]: ...
|
||||
def as_sql(self, compiler: SQLCompiler = ..., connection: Any = ...) -> Any: ...
|
||||
|
||||
class Q(tree.Node):
|
||||
children: Union[List[Dict[str, str]], List[Tuple[str, Any]], List[Q]]
|
||||
@@ -84,4 +84,4 @@ class FilteredRelation:
|
||||
def __init__(self, relation_name: str, *, condition: Any = ...) -> None: ...
|
||||
def clone(self) -> FilteredRelation: ...
|
||||
def resolve_expression(self, *args: Any, **kwargs: Any) -> None: ...
|
||||
def as_sql(self, compiler: SQLCompiler, connection: Any) -> Tuple[str, List[Union[int, str]]]: ...
|
||||
def as_sql(self, compiler: SQLCompiler, connection: Any) -> Any: ...
|
||||
|
||||
@@ -98,7 +98,7 @@ class Query:
|
||||
def get_initial_alias(self) -> str: ...
|
||||
def count_active_tables(self) -> int: ...
|
||||
def resolve_expression(self, query: Query, *args: Any, **kwargs: Any) -> Query: ...
|
||||
def as_sql(self, compiler: SQLCompiler, connection: Any) -> Tuple[str, Tuple]: ...
|
||||
def as_sql(self, compiler: SQLCompiler, connection: Any) -> Any: ...
|
||||
def resolve_lookup_value(self, value: Any, can_reuse: Optional[Set[str]], allow_joins: bool) -> Any: ...
|
||||
def solve_lookup_type(self, lookup: str) -> Tuple[Sequence[str], Sequence[str], bool]: ...
|
||||
def build_filter(
|
||||
|
||||
@@ -18,7 +18,7 @@ class WhereNode(tree.Node):
|
||||
resolved: bool = ...
|
||||
conditional: bool = ...
|
||||
def split_having(self, negated: bool = ...) -> Tuple[Optional[WhereNode], Optional[WhereNode]]: ...
|
||||
def as_sql(self, compiler: SQLCompiler, connection: Any) -> Tuple[str, List[Union[int, str]]]: ...
|
||||
def as_sql(self, compiler: SQLCompiler, connection: Any) -> Any: ...
|
||||
def get_group_by_cols(self) -> List[Expression]: ...
|
||||
def relabel_aliases(self, change_map: Union[Dict[Optional[str], str], OrderedDict]) -> None: ...
|
||||
def clone(self) -> WhereNode: ...
|
||||
|
||||
@@ -204,6 +204,12 @@ class NewSemanalDjangoPlugin(Plugin):
|
||||
return partial(settings.get_type_of_settings_attribute,
|
||||
django_context=self.django_context)
|
||||
|
||||
# def get_type_analyze_hook(self, fullname: str
|
||||
# ( ):
|
||||
# info = self._get_typeinfo_or_none(fullname)
|
||||
# if info and info.has_base(fullnames.QUERYSET_CLASS_FULLNAME):
|
||||
# return partial(querysets.set_first_generic_param_as_default_for_second, fullname=fullname)
|
||||
|
||||
|
||||
def plugin(version):
|
||||
return NewSemanalDjangoPlugin
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from typing import Optional, Tuple, cast
|
||||
|
||||
from mypy.nodes import MypyFile, TypeInfo
|
||||
from mypy.nodes import MypyFile, TypeInfo, Var, AssignmentStmt, SymbolTableNode, MDEF
|
||||
from mypy.plugin import FunctionContext
|
||||
from mypy.types import AnyType, CallableType, Instance, Type as MypyType, TypeOfAny
|
||||
|
||||
@@ -15,9 +15,9 @@ def get_referred_to_model_fullname(ctx: FunctionContext, django_context: DjangoC
|
||||
return to_arg_type.ret_type.type.fullname()
|
||||
|
||||
outer_model_info = ctx.api.scope.active_class()
|
||||
if not outer_model_info or not outer_model_info.has_base(fullnames.MODEL_CLASS_FULLNAME):
|
||||
# not inside models.Model class
|
||||
return None
|
||||
# if not outer_model_info or not outer_model_info.has_base(fullnames.MODEL_CLASS_FULLNAME):
|
||||
# # not inside models.Model class
|
||||
# return None
|
||||
assert isinstance(outer_model_info, TypeInfo)
|
||||
|
||||
to_arg_expr = helpers.get_call_argument_by_name(ctx, 'to')
|
||||
@@ -101,6 +101,12 @@ def transform_into_proper_return_type(ctx: FunctionContext, django_context: Djan
|
||||
default_return_type = ctx.default_return_type
|
||||
assert isinstance(default_return_type, Instance)
|
||||
|
||||
outer_model_info = ctx.api.scope.active_class()
|
||||
if not outer_model_info or not outer_model_info.has_base(fullnames.MODEL_CLASS_FULLNAME):
|
||||
# not inside models.Model class
|
||||
return ctx.default_return_type
|
||||
assert isinstance(outer_model_info, TypeInfo)
|
||||
|
||||
if helpers.has_any_of_bases(default_return_type.type, fullnames.RELATED_FIELDS_CLASSES):
|
||||
return fill_descriptor_types_for_related_field(ctx, django_context)
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from typing import cast, Type
|
||||
from typing import Type, cast
|
||||
|
||||
from django.db.models.base import Model
|
||||
from django.db.models.fields.related import ForeignKey
|
||||
@@ -18,7 +17,7 @@ from mypy_django_plugin.transformers import fields
|
||||
from mypy_django_plugin.transformers.fields import get_field_descriptor_types
|
||||
|
||||
|
||||
class ModelClassInitializer(metaclass=ABCMeta):
|
||||
class ModelClassInitializer:
|
||||
def __init__(self, ctx: ClassDefContext, django_context: DjangoContext):
|
||||
self.api = cast(NewSemanticAnalyzer, ctx.api)
|
||||
self.model_classdef = ctx.cls
|
||||
@@ -52,7 +51,6 @@ class ModelClassInitializer(metaclass=ABCMeta):
|
||||
return
|
||||
self.run_with_model_cls(model_cls)
|
||||
|
||||
@abstractmethod
|
||||
def run_with_model_cls(self, model_cls):
|
||||
pass
|
||||
|
||||
@@ -70,7 +68,7 @@ class InjectAnyAsBaseForNestedMeta(ModelClassInitializer):
|
||||
to get around incompatible Meta inner classes for different models.
|
||||
"""
|
||||
|
||||
def run_with_model_cls(self, model_cls: Type[Model])-> None:
|
||||
def run(self) -> None:
|
||||
meta_node = helpers.get_nested_meta_node_for_current_class(self.model_classdef.info)
|
||||
if meta_node is None:
|
||||
return None
|
||||
@@ -78,7 +76,7 @@ class InjectAnyAsBaseForNestedMeta(ModelClassInitializer):
|
||||
|
||||
|
||||
class AddDefaultPrimaryKey(ModelClassInitializer):
|
||||
def run_with_model_cls(self, model_cls: Type[Model])-> None:
|
||||
def run_with_model_cls(self, model_cls: Type[Model]) -> None:
|
||||
auto_field = model_cls._meta.auto_field
|
||||
if auto_field and not self.model_classdef.info.has_readable_member(auto_field.attname):
|
||||
# autogenerated field
|
||||
@@ -91,7 +89,7 @@ class AddDefaultPrimaryKey(ModelClassInitializer):
|
||||
|
||||
|
||||
class AddRelatedModelsId(ModelClassInitializer):
|
||||
def run_with_model_cls(self, model_cls: Type[Model])-> None:
|
||||
def run_with_model_cls(self, model_cls: Type[Model]) -> None:
|
||||
for field in model_cls._meta.get_fields():
|
||||
if isinstance(field, ForeignKey):
|
||||
rel_primary_key_field = self.django_context.get_primary_key_field(field.related_model)
|
||||
@@ -103,7 +101,7 @@ class AddRelatedModelsId(ModelClassInitializer):
|
||||
|
||||
|
||||
class AddManagers(ModelClassInitializer):
|
||||
def run_with_model_cls(self, model_cls: Type[Model])-> None:
|
||||
def run_with_model_cls(self, model_cls: Type[Model]) -> None:
|
||||
for manager_name, manager in model_cls._meta.managers_map.items():
|
||||
if manager_name not in self.model_classdef.info.names:
|
||||
manager_fullname = helpers.get_class_fullname(manager.__class__)
|
||||
@@ -140,7 +138,7 @@ class AddManagers(ModelClassInitializer):
|
||||
|
||||
|
||||
class AddExtraFieldMethods(ModelClassInitializer):
|
||||
def run_with_model_cls(self, model_cls: Type[Model])-> None:
|
||||
def run_with_model_cls(self, model_cls: Type[Model]) -> None:
|
||||
# get_FOO_display for choices
|
||||
for field in self.django_context.get_model_fields(model_cls):
|
||||
if field.choices:
|
||||
@@ -172,7 +170,7 @@ class AddExtraFieldMethods(ModelClassInitializer):
|
||||
|
||||
|
||||
class AddMetaOptionsAttribute(ModelClassInitializer):
|
||||
def run_with_model_cls(self, model_cls: Type[Model])-> None:
|
||||
def run_with_model_cls(self, model_cls: Type[Model]) -> None:
|
||||
if '_meta' not in self.model_classdef.info.names:
|
||||
options_info = self.lookup_typeinfo_or_incomplete_defn_error(fullnames.OPTIONS_CLASS_FULLNAME)
|
||||
self.add_new_node_to_model_class('_meta',
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from collections import OrderedDict
|
||||
from typing import Optional, Tuple, Type, Sequence, List, Union
|
||||
from typing import Optional, Tuple, Type, Sequence, List, Union, cast
|
||||
|
||||
from django.core.exceptions import FieldError
|
||||
from django.db.models.base import Model
|
||||
from django.db.models.fields.related import ForeignKey
|
||||
from mypy.newsemanal.typeanal import TypeAnalyser
|
||||
from mypy.nodes import NameExpr, Expression
|
||||
from mypy.plugin import AnalyzeTypeContext, FunctionContext, MethodContext
|
||||
from mypy.types import AnyType, Instance, Type as MypyType, TypeOfAny
|
||||
@@ -13,24 +14,20 @@ from mypy_django_plugin.lib import fullnames, helpers
|
||||
|
||||
|
||||
def set_first_generic_param_as_default_for_second(ctx: AnalyzeTypeContext, fullname: str) -> MypyType:
|
||||
info = helpers.lookup_fully_qualified_typeinfo(ctx.api.api, fullname)
|
||||
if info is None:
|
||||
if not ctx.api.api.final_iteration:
|
||||
ctx.api.api.defer()
|
||||
|
||||
if not ctx.type.args:
|
||||
try:
|
||||
return ctx.api.named_type(fullname, [AnyType(TypeOfAny.explicit),
|
||||
AnyType(TypeOfAny.explicit)])
|
||||
except KeyError:
|
||||
# really should never happen
|
||||
return AnyType(TypeOfAny.explicit)
|
||||
return Instance(info, [AnyType(TypeOfAny.explicit), AnyType(TypeOfAny.explicit)])
|
||||
|
||||
args = ctx.type.args
|
||||
if len(args) == 1:
|
||||
args = [args[0], args[0]]
|
||||
|
||||
analyzed_args = [ctx.api.analyze_type(arg) for arg in args]
|
||||
ctx.api.analyze_type(ctx.type)
|
||||
try:
|
||||
return ctx.api.named_type(fullname, analyzed_args)
|
||||
except KeyError:
|
||||
return AnyType(TypeOfAny.explicit)
|
||||
return Instance(info, analyzed_args)
|
||||
|
||||
|
||||
def determine_proper_manager_type(ctx: FunctionContext) -> MypyType:
|
||||
|
||||
@@ -77,23 +77,6 @@
|
||||
class User(models.Model):
|
||||
my_pk = models.IntegerField(primary_key=True)
|
||||
|
||||
- case: test_primary_key_on_optional_queryset_method
|
||||
main: |
|
||||
from myapp.models import User
|
||||
reveal_type(User.objects.first().id)
|
||||
out: |
|
||||
main:2: note: Revealed type is 'Union[builtins.int*, Any]'
|
||||
main:2: error: Item "None" of "Optional[User]" has no attribute "id"
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
pass
|
||||
|
||||
- case: blank_and_null_char_field_allows_none
|
||||
main: |
|
||||
from myapp.models import MyModel
|
||||
@@ -127,3 +110,17 @@
|
||||
from django.db import models
|
||||
class MyModel(models.Model):
|
||||
notnulltext=models.CharField(max_length=1, blank=True, null=False)
|
||||
|
||||
- case: if_field_called_on_class_return_field_itself
|
||||
main: |
|
||||
from myapp.models import MyUser
|
||||
reveal_type(MyUser.name) # N: Revealed type is 'django.db.models.fields.CharField[Union[builtins.str, builtins.int, django.db.models.expressions.Combinable], builtins.str]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyUser(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
@@ -7,7 +7,7 @@
|
||||
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 'Union[myapp.models.Blog*, None]'
|
||||
reveal_type(qs.first()) # N: Revealed type is 'myapp.models.Blog*'
|
||||
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*]'
|
||||
|
||||
@@ -212,10 +212,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 'Union[myapp.models.UnrelatedModel*, None]'
|
||||
reveal_type(UnrelatedModel.objects.first()) # N: Revealed type is 'myapp.models.UnrelatedModel*'
|
||||
|
||||
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 'Union[myapp.models.MyModel*, None]'
|
||||
reveal_type(MyModel.objects.first()) # N: Revealed type is 'myapp.models.MyModel*'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
@@ -233,10 +233,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 'Union[myapp.models.UnrelatedModel2*, None]'
|
||||
reveal_type(UnrelatedModel2.objects.first()) # N: Revealed type is 'myapp.models.UnrelatedModel2*'
|
||||
|
||||
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 'Union[myapp.models.MyModel2*, None]'
|
||||
reveal_type(MyModel2.objects.first()) # N: Revealed type is 'myapp.models.MyModel2*'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
@@ -254,10 +254,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 'Union[myapp.models.ParentOfMyModel3*, None]'
|
||||
reveal_type(ParentOfMyModel3.objects.first()) # N: Revealed type is 'myapp.models.ParentOfMyModel3*'
|
||||
|
||||
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 'Union[myapp.models.MyModel3*, None]'
|
||||
reveal_type(MyModel3.objects.first()) # N: Revealed type is 'myapp.models.MyModel3*'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
@@ -275,10 +275,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 'Union[myapp.models.ParentOfMyModel4*, None]'
|
||||
reveal_type(ParentOfMyModel4.objects.first()) # N: Revealed type is 'myapp.models.ParentOfMyModel4*'
|
||||
|
||||
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 'Union[myapp.models.MyModel4*, None]'
|
||||
reveal_type(MyModel4.objects.first()) # N: Revealed type is 'myapp.models.MyModel4*'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
@@ -291,3 +291,30 @@
|
||||
|
||||
class MyModel4(ParentOfMyModel4):
|
||||
objects = models.Manager['MyModel4']()
|
||||
|
||||
# TODO: make it work someday
|
||||
#- case: inheritance_of_two_models_with_custom_objects_manager
|
||||
# main: |
|
||||
# from myapp.models import MyBaseUser, MyUser
|
||||
# reveal_type(MyBaseUser.objects) # N: Revealed type is 'myapp.models.MyBaseManager[myapp.models.MyBaseUser]'
|
||||
# reveal_type(MyBaseUser.objects.get()) # N: Revealed type is 'myapp.models.MyBaseUser'
|
||||
#
|
||||
# reveal_type(MyUser.objects) # N: Revealed type is 'myapp.models.MyManager[myapp.models.MyUser]'
|
||||
# reveal_type(MyUser.objects.get()) # N: Revealed type is 'myapp.models.MyUser'
|
||||
# installed_apps:
|
||||
# - myapp
|
||||
# files:
|
||||
# - path: myapp/__init__.py
|
||||
# - path: myapp/models.py
|
||||
# content: |
|
||||
# from django.db import models
|
||||
#
|
||||
# class MyBaseManager(models.Manager):
|
||||
# pass
|
||||
# class MyBaseUser(models.Model):
|
||||
# objects = MyBaseManager()
|
||||
#
|
||||
# class MyManager(models.Manager):
|
||||
# pass
|
||||
# class MyUser(MyBaseUser):
|
||||
# objects = MyManager()
|
||||
@@ -15,12 +15,14 @@
|
||||
- case: get_field_returns_proper_field_type
|
||||
main: |
|
||||
from myapp.models import MyUser
|
||||
reveal_type(MyUser._meta.get_field('base_name')) # N: Revealed type is 'django.db.models.fields.CharField[Any, Any]'
|
||||
reveal_type(MyUser._meta.get_field('name')) # N: Revealed type is 'django.db.models.fields.CharField[Any, Any]'
|
||||
reveal_type(MyUser._meta.get_field('age')) # N: Revealed type is 'django.db.models.fields.IntegerField[Any, Any]'
|
||||
reveal_type(MyUser._meta.get_field('unknown'))
|
||||
reveal_type(MyUser._meta.get_field('to_user')) # N: Revealed type is 'django.db.models.fields.related.ForeignKey[Any, Any]'
|
||||
out: |
|
||||
main:4: note: Revealed type is 'Any'
|
||||
main:4: error: MyUser has no field named 'unknown'
|
||||
main:5: note: Revealed type is 'Any'
|
||||
main:5: error: MyUser has no field named 'unknown'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
@@ -28,6 +30,9 @@
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class MyUser(models.Model):
|
||||
class MyBaseUser(models.Model):
|
||||
base_name = models.CharField(max_length=100)
|
||||
class MyUser(MyBaseUser):
|
||||
name = models.CharField(max_length=100)
|
||||
age = models.IntegerField()
|
||||
to_user = models.ForeignKey('self', on_delete=models.SET_NULL)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
class MyModel(models.Model):
|
||||
user = models.ForeignKey('auth.User', on_delete=models.CASCADE)
|
||||
if TYPE_CHECKING:
|
||||
reveal_type(MyModel.user) # N: Revealed type is 'django.contrib.auth.models.User*'
|
||||
reveal_type(MyModel().user) # N: Revealed type is 'django.contrib.auth.models.User*'
|
||||
|
||||
- case: generate_pyproject_toml_and_settings_file_from_installed_apps_key
|
||||
main: |
|
||||
|
||||
Reference in New Issue
Block a user