mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-14 07:47:09 +08:00
* Fix stubs related to `(Async)RequestFactory` and `(Async)Client`
* Revert incorrect removal.
* Allow set as `unique_together`, use shared type alias.
* Revert `Q.__init__` to use only `*args, **kwargs` to remove false-positive with `Q(**{...})`
* Add abstract methods to `HttpResponseBase` to create common interface.
* Remove monkey-patched attributes from `HttpResponseBase` subclasses.
* Add QueryDict mutability checks (+ plugin support)
* Fix lint
* Return back GenericForeignKey to `Options.get_fields`
* Minor fixup
* Make plugin code typecheck with `--warn-unreachable`, minor performance increase.
* Better types for `{unique, index}_together` and Options.
* Fix odd type of `URLResolver.urlconf_name` which isn't a str actually.
* Better types for field migration operations.
* Revert form.files to `MultiValueDict[str, UploadedFile]`
* Compatibility fix (#916)
* Do not assume that `Annotated` is always related to django-stubs (fixes #893)
* Restrict `FormView.get_form` return type to `_FormT` (class type argument). Now it is resolved to `form_class` argument if present, but also errors if it is not subclass of _FormT
* Fix CI (make test runnable on 3.8)
* Fix CI (make test runnable on 3.8 _again_)
This commit is contained in:
@@ -32,6 +32,7 @@ from mypy_django_plugin.transformers.models import (
|
||||
process_model_class,
|
||||
set_auth_user_model_boolean_fields,
|
||||
)
|
||||
from mypy_django_plugin.transformers.request import check_querydict_is_mutable
|
||||
|
||||
|
||||
def transform_model_class(ctx: ClassDefContext, django_context: DjangoContext) -> None:
|
||||
@@ -187,12 +188,21 @@ class NewSemanalDjangoPlugin(Plugin):
|
||||
|
||||
def get_method_hook(self, fullname: str) -> Optional[Callable[[MethodContext], MypyType]]:
|
||||
class_fullname, _, method_name = fullname.rpartition(".")
|
||||
if method_name == "get_form_class":
|
||||
# It is looked up very often, specialcase this method for minor speed up
|
||||
if method_name == "__init_subclass__":
|
||||
return None
|
||||
|
||||
if class_fullname.endswith("QueryDict"):
|
||||
info = self._get_typeinfo_or_none(class_fullname)
|
||||
if info and info.has_base(fullnames.QUERYDICT_CLASS_FULLNAME):
|
||||
return partial(check_querydict_is_mutable, django_context=self.django_context)
|
||||
|
||||
elif method_name == "get_form_class":
|
||||
info = self._get_typeinfo_or_none(class_fullname)
|
||||
if info and info.has_base(fullnames.FORM_MIXIN_CLASS_FULLNAME):
|
||||
return forms.extract_proper_type_for_get_form_class
|
||||
|
||||
if method_name == "get_form":
|
||||
elif method_name == "get_form":
|
||||
info = self._get_typeinfo_or_none(class_fullname)
|
||||
if info and info.has_base(fullnames.FORM_MIXIN_CLASS_FULLNAME):
|
||||
return forms.extract_proper_type_for_get_form
|
||||
@@ -204,30 +214,30 @@ class NewSemanalDjangoPlugin(Plugin):
|
||||
if info and info.has_base(fullnames.QUERYSET_CLASS_FULLNAME) or class_fullname in manager_classes:
|
||||
return partial(querysets.extract_proper_type_queryset_values, django_context=self.django_context)
|
||||
|
||||
if method_name == "values_list":
|
||||
elif method_name == "values_list":
|
||||
info = self._get_typeinfo_or_none(class_fullname)
|
||||
if info and info.has_base(fullnames.QUERYSET_CLASS_FULLNAME) or class_fullname in manager_classes:
|
||||
return partial(querysets.extract_proper_type_queryset_values_list, django_context=self.django_context)
|
||||
|
||||
if method_name == "annotate":
|
||||
elif method_name == "annotate":
|
||||
info = self._get_typeinfo_or_none(class_fullname)
|
||||
if info and info.has_base(fullnames.QUERYSET_CLASS_FULLNAME) or class_fullname in manager_classes:
|
||||
return partial(querysets.extract_proper_type_queryset_annotate, django_context=self.django_context)
|
||||
|
||||
if method_name == "get_field":
|
||||
elif method_name == "get_field":
|
||||
info = self._get_typeinfo_or_none(class_fullname)
|
||||
if info and info.has_base(fullnames.OPTIONS_CLASS_FULLNAME):
|
||||
return partial(meta.return_proper_field_type_from_get_field, django_context=self.django_context)
|
||||
|
||||
if class_fullname in manager_classes and method_name == "create":
|
||||
elif class_fullname in manager_classes and method_name == "create":
|
||||
return partial(init_create.redefine_and_typecheck_model_create, django_context=self.django_context)
|
||||
if class_fullname in manager_classes and method_name in {"filter", "get", "exclude"}:
|
||||
elif class_fullname in manager_classes and method_name in {"filter", "get", "exclude"}:
|
||||
return partial(
|
||||
mypy_django_plugin.transformers.orm_lookups.typecheck_queryset_filter,
|
||||
django_context=self.django_context,
|
||||
)
|
||||
|
||||
if method_name == "from_queryset":
|
||||
elif method_name == "from_queryset":
|
||||
info = self._get_typeinfo_or_none(class_fullname)
|
||||
if info and info.has_base(fullnames.BASE_MANAGER_CLASS_FULLNAME):
|
||||
return fail_if_manager_type_created_in_model_body
|
||||
|
||||
Reference in New Issue
Block a user