mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-18 18:05:58 +08:00
Make SomeModel._default_manager return a BaseManager[SomeModel] instead of BaseManager[Model] (#817)
* _default_manager has more specific type for TypeVars * remove unnecessary # type: ignore * add test for _base_manager * add overloads for classproperty.__get__ * readd # type: ignore for WSGIRequestHandler.connection, fails in github's pipeline * fix _base_manager test: mypy reveals an inferred type Co-authored-by: Michael Pöhle <michael.poehle@polyteia.de>
This commit is contained in:
@@ -5,6 +5,7 @@ from django.core.exceptions import MultipleObjectsReturned as BaseMultipleObject
|
|||||||
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
||||||
from django.db.models.manager import BaseManager
|
from django.db.models.manager import BaseManager
|
||||||
from django.db.models.options import Options
|
from django.db.models.options import Options
|
||||||
|
from django.utils.functional import classproperty
|
||||||
|
|
||||||
_Self = TypeVar("_Self", bound="Model")
|
_Self = TypeVar("_Self", bound="Model")
|
||||||
|
|
||||||
@@ -22,8 +23,12 @@ class Model(metaclass=ModelBase):
|
|||||||
class MultipleObjectsReturned(BaseMultipleObjectsReturned): ...
|
class MultipleObjectsReturned(BaseMultipleObjectsReturned): ...
|
||||||
class Meta: ...
|
class Meta: ...
|
||||||
_meta: Options[Any]
|
_meta: Options[Any]
|
||||||
_default_manager: BaseManager[Model]
|
@classproperty
|
||||||
_base_manager: BaseManager[Model]
|
@classmethod
|
||||||
|
def _default_manager(cls: Type[_Self]) -> BaseManager[_Self]: ...
|
||||||
|
@classproperty
|
||||||
|
@classmethod
|
||||||
|
def _base_manager(cls: Type[_Self]) -> BaseManager[_Self]: ...
|
||||||
objects: BaseManager[Any]
|
objects: BaseManager[Any]
|
||||||
pk: Any = ...
|
pk: Any = ...
|
||||||
_state: ModelState
|
_state: ModelState
|
||||||
|
|||||||
@@ -62,8 +62,14 @@ def partition(
|
|||||||
predicate: Callable, values: List[_PartitionMember]
|
predicate: Callable, values: List[_PartitionMember]
|
||||||
) -> Tuple[List[_PartitionMember], List[_PartitionMember]]: ...
|
) -> Tuple[List[_PartitionMember], List[_PartitionMember]]: ...
|
||||||
|
|
||||||
class classproperty:
|
_Get = TypeVar("_Get")
|
||||||
fget: Optional[Callable] = ...
|
_Self = TypeVar("_Self")
|
||||||
def __init__(self, method: Optional[Callable] = ...) -> None: ...
|
|
||||||
def __get__(self, instance: Any, cls: Optional[type] = ...) -> Any: ...
|
class classproperty(Generic[_Get]):
|
||||||
def getter(self, method: Callable) -> classproperty: ...
|
fget: Optional[Callable[[Type[_Self]], _Get]] = ...
|
||||||
|
def __init__(self, method: Optional[Callable[[Type[_Self]], _Get]] = ...) -> None: ...
|
||||||
|
@overload
|
||||||
|
def __get__(self, instance: None, cls: Type[_Self] = ...) -> _Get: ...
|
||||||
|
@overload
|
||||||
|
def __get__(self, instance: _Self, cls: Type[_Self] = ...) -> _Get: ...
|
||||||
|
def getter(self, method: Callable[[Type[_Self]], _Get]) -> classproperty[_Get]: ...
|
||||||
|
|||||||
@@ -48,13 +48,38 @@
|
|||||||
class Base(Generic[_T]):
|
class Base(Generic[_T]):
|
||||||
def __init__(self, model_cls: Type[_T]):
|
def __init__(self, model_cls: Type[_T]):
|
||||||
self.model_cls = model_cls
|
self.model_cls = model_cls
|
||||||
reveal_type(self.model_cls._default_manager) # N: Revealed type is "django.db.models.manager.BaseManager[django.db.models.base.Model]"
|
reveal_type(self.model_cls._default_manager) # N: Revealed type is "django.db.models.manager.BaseManager[_T`1]"
|
||||||
class MyModel(models.Model):
|
class MyModel(models.Model):
|
||||||
pass
|
pass
|
||||||
class Child(Base[MyModel]):
|
class Child(Base[MyModel]):
|
||||||
def method(self) -> None:
|
def method(self) -> None:
|
||||||
reveal_type(self.model_cls._default_manager) # N: Revealed type is "django.db.models.manager.Manager[myapp.models.MyModel]"
|
reveal_type(self.model_cls._default_manager) # N: Revealed type is "django.db.models.manager.Manager[myapp.models.MyModel]"
|
||||||
|
|
||||||
|
- case: test_base_manager_called_on_model_cls_as_generic_parameter
|
||||||
|
main: |
|
||||||
|
from myapp.models import Base, MyModel
|
||||||
|
base_instance = Base(MyModel)
|
||||||
|
reveal_type(base_instance.model_cls._base_manager) # N: Revealed type is "django.db.models.manager.BaseManager[myapp.models.MyModel*]"
|
||||||
|
installed_apps:
|
||||||
|
- myapp
|
||||||
|
files:
|
||||||
|
- path: myapp/__init__.py
|
||||||
|
- path: myapp/models.py
|
||||||
|
content: |
|
||||||
|
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._base_manager) # N: Revealed type is "django.db.models.manager.BaseManager[_T`1]"
|
||||||
|
class MyModel(models.Model):
|
||||||
|
pass
|
||||||
|
class Child(Base[MyModel]):
|
||||||
|
def method(self) -> None:
|
||||||
|
reveal_type(self.model_cls._base_manager) # N: Revealed type is "django.db.models.manager.BaseManager[myapp.models.MyModel*]"
|
||||||
|
|
||||||
- case: if_custom_manager_defined_it_is_set_to_default_manager
|
- case: if_custom_manager_defined_it_is_set_to_default_manager
|
||||||
main: |
|
main: |
|
||||||
from myapp.models import MyModel
|
from myapp.models import MyModel
|
||||||
|
|||||||
Reference in New Issue
Block a user