mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-06 12:14:28 +08:00
fix problem with TypeVar bound to Model passed as a parameter
This commit is contained in:
@@ -21,12 +21,6 @@ class Permission(models.Model):
|
||||
name: str = ...
|
||||
content_type: Any = ...
|
||||
codename: str = ...
|
||||
objects: Any = ...
|
||||
class Meta:
|
||||
verbose_name: Any = ...
|
||||
verbose_name_plural: Any = ...
|
||||
unique_together: Any = ...
|
||||
ordering: Any = ...
|
||||
def natural_key(self) -> Tuple[str, str, str]: ...
|
||||
|
||||
class GroupManager(models.Manager):
|
||||
@@ -40,10 +34,6 @@ class Group(models.Model):
|
||||
id: None
|
||||
name: str = ...
|
||||
permissions: Any = ...
|
||||
objects: Any = ...
|
||||
class Meta:
|
||||
verbose_name: Any = ...
|
||||
verbose_name_plural: Any = ...
|
||||
def natural_key(self): ...
|
||||
|
||||
class UserManager(BaseUserManager):
|
||||
@@ -77,7 +67,6 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin):
|
||||
email: str = ...
|
||||
is_staff: bool = ...
|
||||
date_joined: datetime.datetime = ...
|
||||
objects: Any = ...
|
||||
EMAIL_FIELD: str = ...
|
||||
USERNAME_FIELD: str = ...
|
||||
def clean(self) -> None: ...
|
||||
@@ -85,9 +74,7 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin):
|
||||
def get_short_name(self) -> str: ...
|
||||
def email_user(self, subject: str, message: str, from_email: str = ..., **kwargs: Any) -> None: ...
|
||||
|
||||
class User(AbstractUser):
|
||||
class Meta(AbstractUser.Meta):
|
||||
swappable: str = ...
|
||||
class User(AbstractUser): ...
|
||||
|
||||
class AnonymousUser:
|
||||
id: Any = ...
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from typing import Any, List, Optional, Set, Tuple, Dict
|
||||
|
||||
class ModelBase(type):
|
||||
pass
|
||||
from django.db.models.manager import Manager
|
||||
|
||||
class ModelBase(type): ...
|
||||
|
||||
class Model(metaclass=ModelBase):
|
||||
class DoesNotExist(Exception):
|
||||
pass
|
||||
pk: Any = ...
|
||||
objects: Manager[Model]
|
||||
def __init__(self, **kwargs) -> None: ...
|
||||
def delete(self, using: Any = ..., keep_parents: bool = ...) -> Tuple[int, Dict[str, int]]: ...
|
||||
def full_clean(self, exclude: Optional[List[str]] = ..., validate_unique: bool = ...) -> None: ...
|
||||
|
||||
@@ -3,7 +3,7 @@ from typing import Any, Dict, List, Optional, Tuple, Type, TypeVar
|
||||
from django.db.models.base import Model
|
||||
from django.db.models.query import QuerySet
|
||||
|
||||
_T = TypeVar("_T", bound=Model)
|
||||
_T = TypeVar("_T", bound=Model, covariant=True)
|
||||
|
||||
class BaseManager(QuerySet[_T]):
|
||||
creation_counter: int = ...
|
||||
@@ -24,7 +24,7 @@ class BaseManager(QuerySet[_T]):
|
||||
class Manager(BaseManager[_T]): ...
|
||||
|
||||
class RelatedManager(Manager[_T]):
|
||||
def add(self, *objs: _T, bulk: bool = ...) -> None: ...
|
||||
def add(self, *objs: Model, bulk: bool = ...) -> None: ...
|
||||
def clear(self) -> None: ...
|
||||
|
||||
class ManagerDescriptor:
|
||||
|
||||
@@ -6,7 +6,7 @@ from django.db import models
|
||||
from django.db.models import Manager
|
||||
from django.db.models.sql.query import Query, RawQuery
|
||||
|
||||
_T = TypeVar("_T", bound=models.Model)
|
||||
_T = TypeVar("_T", bound=models.Model, covariant=True)
|
||||
|
||||
class QuerySet(Iterable[_T], Sized):
|
||||
def __init__(
|
||||
|
||||
@@ -93,8 +93,13 @@ class InjectAnyAsBaseForNestedMeta(ModelClassInitializer):
|
||||
|
||||
|
||||
class AddDefaultObjectsManager(ModelClassInitializer):
|
||||
def is_default_objects_attr(self, sym: SymbolTableNode) -> bool:
|
||||
return sym.fullname == helpers.MODEL_CLASS_FULLNAME + '.' + 'objects'
|
||||
|
||||
def run(self) -> None:
|
||||
if 'objects' in self.model_classdef.info.names:
|
||||
existing_objects_sym = self.model_classdef.info.get('objects')
|
||||
if (existing_objects_sym is not None
|
||||
and not self.is_default_objects_attr(existing_objects_sym)):
|
||||
return None
|
||||
|
||||
if self.is_abstract_model():
|
||||
|
||||
@@ -8,7 +8,7 @@ reveal_type(User.objects.get()) # E: Revealed type is 'main.User*'
|
||||
[CASE test_leave_as_is_if_objects_is_set_and_fill_typevars_with_outer_class]
|
||||
from django.db import models
|
||||
|
||||
class UserManager(models.Manager):
|
||||
class UserManager(models.Manager[User]):
|
||||
def get_or_404(self) -> User:
|
||||
pass
|
||||
|
||||
@@ -19,3 +19,31 @@ reveal_type(User.objects) # E: Revealed type is 'main.UserManager'
|
||||
reveal_type(User.objects.get()) # E: Revealed type is 'main.User*'
|
||||
reveal_type(User.objects.get_or_404()) # E: Revealed type is 'main.User'
|
||||
|
||||
[CASE test_model_objects_attribute_present_in_case_of_model_cls_passed_as_parameter]
|
||||
from typing import Type
|
||||
from django.db import models
|
||||
|
||||
class Base:
|
||||
def __init__(self, model_cls: Type[models.Model]):
|
||||
self.model_cls = model_cls
|
||||
class MyModel(models.Model):
|
||||
pass
|
||||
reveal_type(Base(MyModel).model_cls.objects) # E: Revealed type is 'django.db.models.manager.Manager[django.db.models.base.Model]'
|
||||
|
||||
[CASE test_model_objects_attribute_present_in_case_of_model_cls_passed_as_generic_parameter]
|
||||
from typing import TypeVar, Generic, Type
|
||||
from django.db import models
|
||||
|
||||
_T = TypeVar('_T', bound=models.Model)
|
||||
class Base(Generic[_T]):
|
||||
def __init__(self, model_cls: Type[_T]):
|
||||
self.model_cls = model_cls
|
||||
reveal_type(self.model_cls.objects) # E: Revealed type is 'django.db.models.manager.Manager[django.db.models.base.Model]'
|
||||
class MyModel(models.Model):
|
||||
pass
|
||||
base_instance = Base(MyModel)
|
||||
reveal_type(base_instance.model_cls.objects) # E: Revealed type is 'django.db.models.manager.Manager[main.MyModel]'
|
||||
|
||||
class Child(Base[MyModel]):
|
||||
def method(self) -> None:
|
||||
reveal_type(self.model_cls.objects) # E: Revealed type is 'django.db.models.manager.Manager[main.MyModel]'
|
||||
Reference in New Issue
Block a user