mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-14 15:57:08 +08:00
Fix CI (#1108)
* Fix CI
* Fix CI
* Fix CI
* Fix CI
* APply black
* APply black
* Fix mypy
* Fix mypy errors in django-stubs
* Fix format
* Fix plugin
* Do not patch builtins by default
* Fix mypy
* Only run mypy on 3.10 for now
* Only run mypy on 3.10 for now
* WHAT THE HELL
* Enable strict mode in mypy
* Enable strict mode in mypy
* Fix tests
* Fix tests
* Debug
* Debug
* Fix tests
* Fix tests
* Add TYPE_CHECKING debug
* Caching maybe?
* Caching maybe?
* Try explicit `${{ matrix.python-version }}`
* Remove debug
* Fix typing
* Finally
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
import builtins
|
||||
import os
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from contextlib import contextmanager
|
||||
from typing import TYPE_CHECKING, Dict, Iterable, Iterator, Optional, Set, Tuple, Type, Union
|
||||
from typing import TYPE_CHECKING, Any, Dict, Iterable, Iterator, Optional, Set, Tuple, Type, Union
|
||||
|
||||
from django.core.exceptions import FieldError
|
||||
from django.db import models
|
||||
@@ -39,7 +38,7 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
@contextmanager
|
||||
def temp_environ():
|
||||
def temp_environ() -> Iterator[None]:
|
||||
"""Allow the ability to set os.environ temporarily"""
|
||||
environ = dict(os.environ)
|
||||
try:
|
||||
@@ -56,19 +55,6 @@ def initialize_django(settings_module: str) -> Tuple["Apps", "LazySettings"]:
|
||||
# add current directory to sys.path
|
||||
sys.path.append(os.getcwd())
|
||||
|
||||
def noop_class_getitem(cls, key):
|
||||
return cls
|
||||
|
||||
from django.db import models
|
||||
|
||||
models.QuerySet.__class_getitem__ = classmethod(noop_class_getitem) # type: ignore
|
||||
models.Manager.__class_getitem__ = classmethod(noop_class_getitem) # type: ignore
|
||||
|
||||
# Define mypy builtins, to not cause NameError during setting up Django.
|
||||
# TODO: temporary/unpatch
|
||||
builtins.reveal_type = lambda _: None
|
||||
builtins.reveal_locals = lambda: None
|
||||
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
|
||||
@@ -80,8 +66,8 @@ def initialize_django(settings_module: str) -> Tuple["Apps", "LazySettings"]:
|
||||
|
||||
apps.populate(settings.INSTALLED_APPS)
|
||||
|
||||
assert apps.apps_ready
|
||||
assert settings.configured
|
||||
assert apps.apps_ready, "Apps are not ready"
|
||||
assert settings.configured, "Settings are not configured"
|
||||
|
||||
return apps, settings
|
||||
|
||||
@@ -127,7 +113,7 @@ class DjangoContext:
|
||||
return model_cls
|
||||
return None
|
||||
|
||||
def get_model_fields(self, model_cls: Type[Model]) -> Iterator[Field]:
|
||||
def get_model_fields(self, model_cls: Type[Model]) -> Iterator["Field[Any, Any]"]:
|
||||
for field in model_cls._meta.get_fields():
|
||||
if isinstance(field, Field):
|
||||
yield field
|
||||
@@ -137,7 +123,9 @@ class DjangoContext:
|
||||
if isinstance(field, ForeignObjectRel):
|
||||
yield field
|
||||
|
||||
def get_field_lookup_exact_type(self, api: TypeChecker, field: Union[Field, ForeignObjectRel]) -> MypyType:
|
||||
def get_field_lookup_exact_type(
|
||||
self, api: TypeChecker, field: Union["Field[Any, Any]", ForeignObjectRel]
|
||||
) -> MypyType:
|
||||
if isinstance(field, (RelatedField, ForeignObjectRel)):
|
||||
related_model_cls = field.related_model
|
||||
primary_key_field = self.get_primary_key_field(related_model_cls)
|
||||
@@ -155,7 +143,7 @@ class DjangoContext:
|
||||
return AnyType(TypeOfAny.explicit)
|
||||
return helpers.get_private_descriptor_type(field_info, "_pyi_lookup_exact_type", is_nullable=field.null)
|
||||
|
||||
def get_primary_key_field(self, model_cls: Type[Model]) -> Field:
|
||||
def get_primary_key_field(self, model_cls: Type[Model]) -> "Field[Any, Any]":
|
||||
for field in model_cls._meta.get_fields():
|
||||
if isinstance(field, Field):
|
||||
if field.primary_key:
|
||||
@@ -258,11 +246,11 @@ class DjangoContext:
|
||||
def all_registered_model_class_fullnames(self) -> Set[str]:
|
||||
return {helpers.get_class_fullname(cls) for cls in self.all_registered_model_classes}
|
||||
|
||||
def get_attname(self, field: Field) -> str:
|
||||
def get_attname(self, field: "Field[Any, Any]") -> str:
|
||||
attname = field.attname
|
||||
return attname
|
||||
|
||||
def get_field_nullability(self, field: Union[Field, ForeignObjectRel], method: Optional[str]) -> bool:
|
||||
def get_field_nullability(self, field: Union["Field[Any, Any]", ForeignObjectRel], method: Optional[str]) -> bool:
|
||||
if method in ("values", "values_list"):
|
||||
return field.null
|
||||
|
||||
@@ -279,7 +267,9 @@ class DjangoContext:
|
||||
return True
|
||||
return nullable
|
||||
|
||||
def get_field_set_type(self, api: TypeChecker, field: Union[Field, ForeignObjectRel], *, method: str) -> MypyType:
|
||||
def get_field_set_type(
|
||||
self, api: TypeChecker, field: Union["Field[Any, Any]", ForeignObjectRel], *, method: str
|
||||
) -> MypyType:
|
||||
"""Get a type of __set__ for this specific Django field."""
|
||||
target_field = field
|
||||
if isinstance(field, ForeignKey):
|
||||
@@ -297,7 +287,9 @@ class DjangoContext:
|
||||
field_set_type = helpers.convert_any_to_type(field_set_type, argument_field_type)
|
||||
return field_set_type
|
||||
|
||||
def get_field_get_type(self, api: TypeChecker, field: Union[Field, ForeignObjectRel], *, method: str) -> MypyType:
|
||||
def get_field_get_type(
|
||||
self, api: TypeChecker, field: Union["Field[Any, Any]", ForeignObjectRel], *, method: str
|
||||
) -> MypyType:
|
||||
"""Get a type of __get__ for this specific Django field."""
|
||||
field_info = helpers.lookup_class_typeinfo(api, field.__class__)
|
||||
if field_info is None:
|
||||
@@ -321,14 +313,16 @@ class DjangoContext:
|
||||
else:
|
||||
return helpers.get_private_descriptor_type(field_info, "_pyi_private_get_type", is_nullable=is_nullable)
|
||||
|
||||
def get_field_related_model_cls(self, field: Union[RelatedField, ForeignObjectRel]) -> Optional[Type[Model]]:
|
||||
def get_field_related_model_cls(
|
||||
self, field: Union["RelatedField[Any, Any]", ForeignObjectRel]
|
||||
) -> Optional[Type[Model]]:
|
||||
if isinstance(field, RelatedField):
|
||||
related_model_cls = field.remote_field.model
|
||||
else:
|
||||
related_model_cls = field.field.model
|
||||
|
||||
if isinstance(related_model_cls, str):
|
||||
if related_model_cls == "self": # type: ignore[unreachable]
|
||||
if related_model_cls == "self": # type: ignore
|
||||
# same model
|
||||
related_model_cls = field.model
|
||||
elif "." not in related_model_cls:
|
||||
@@ -342,9 +336,9 @@ class DjangoContext:
|
||||
|
||||
def _resolve_field_from_parts(
|
||||
self, field_parts: Iterable[str], model_cls: Type[Model]
|
||||
) -> Union[Field, ForeignObjectRel]:
|
||||
) -> Union["Field[Any, Any]", ForeignObjectRel]:
|
||||
currently_observed_model = model_cls
|
||||
field: Union[Field, ForeignObjectRel, GenericForeignKey, None] = None
|
||||
field: Union["Field[Any, Any]", ForeignObjectRel, GenericForeignKey, None] = None
|
||||
for field_part in field_parts:
|
||||
if field_part == "pk":
|
||||
field = self.get_primary_key_field(currently_observed_model)
|
||||
@@ -364,7 +358,9 @@ class DjangoContext:
|
||||
assert isinstance(field, (Field, ForeignObjectRel))
|
||||
return field
|
||||
|
||||
def resolve_lookup_into_field(self, model_cls: Type[Model], lookup: str) -> Union[Field, ForeignObjectRel]:
|
||||
def resolve_lookup_into_field(
|
||||
self, model_cls: Type[Model], lookup: str
|
||||
) -> Union["Field[Any, Any]", ForeignObjectRel]:
|
||||
query = Query(model_cls)
|
||||
lookup_parts, field_parts, is_expression = query.solve_lookup_type(lookup)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user