From 1c31e71ffc4d3ded73864d9b834bfc89ee222fbd Mon Sep 17 00:00:00 2001 From: Maksim Kurnikov Date: Fri, 13 Dec 2019 13:30:21 +0300 Subject: [PATCH] enable 'model_forms' for tests typechecking (#270) --- django-stubs/forms/fields.pyi | 3 +-- django-stubs/forms/models.pyi | 26 ++++++++++++++++++++++++-- django-stubs/views/generic/edit.pyi | 3 ++- scripts/enabled_test_modules.py | 10 +++++++++- scripts/typecheck_tests.py | 4 ++-- 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/django-stubs/forms/fields.pyi b/django-stubs/forms/fields.pyi index fc73fa9..0594b75 100644 --- a/django-stubs/forms/fields.pyi +++ b/django-stubs/forms/fields.pyi @@ -205,10 +205,9 @@ class CallableChoiceIterator: def __iter__(self) -> None: ... class ChoiceField(Field): - choices: Any = ... def __init__( self, - choices: Any = ..., + choices: _FieldChoices = ..., required: bool = ..., widget: Optional[Union[Widget, Type[Widget]]] = ..., label: Optional[Any] = ..., diff --git a/django-stubs/forms/models.pyi b/django-stubs/forms/models.pyi index 3ee18c0..549db20 100644 --- a/django-stubs/forms/models.pyi +++ b/django-stubs/forms/models.pyi @@ -1,5 +1,21 @@ from datetime import datetime -from typing import Any, Callable, Dict, Iterator, List, Mapping, MutableMapping, Optional, Sequence, Tuple, Type, Union +from typing import ( + Any, + Callable, + Dict, + Iterator, + List, + Mapping, + MutableMapping, + Optional, + Sequence, + Tuple, + Type, + Union, + ClassVar, + Container, + TypeVar, +) from unittest.mock import MagicMock from uuid import UUID @@ -24,6 +40,11 @@ _Fields = Union[List[Union[Callable, str]], Sequence[str], Literal["__all__"]] _Labels = Dict[str, str] _ErrorMessages = Dict[str, Dict[str, str]] +_M = TypeVar("_M", bound=Model) + +def construct_instance( + form: BaseForm, instance: _M, fields: Optional[Container[str]] = ..., exclude: Optional[Container[str]] = ... +) -> _M: ... def model_to_dict( instance: Model, fields: Optional[_Fields] = ..., exclude: Optional[_Fields] = ... ) -> Dict[str, Any]: ... @@ -76,7 +97,8 @@ class BaseModelForm(BaseForm): save_m2m: Any = ... def save(self, commit: bool = ...) -> Any: ... -class ModelForm(BaseModelForm): ... +class ModelForm(BaseModelForm, metaclass=ModelFormMetaclass): + base_fields: ClassVar[Dict[str, Field]] = ... def modelform_factory( model: Type[Model], diff --git a/django-stubs/views/generic/edit.pyi b/django-stubs/views/generic/edit.pyi index ef3a23d..219ebed 100644 --- a/django-stubs/views/generic/edit.pyi +++ b/django-stubs/views/generic/edit.pyi @@ -1,11 +1,12 @@ from typing import Any, Callable, Dict, Optional, Sequence, Type, Union from django.forms.forms import BaseForm -from django.http import HttpRequest, HttpResponse from django.views.generic.base import ContextMixin, TemplateResponseMixin, View from django.views.generic.detail import BaseDetailView, SingleObjectMixin, SingleObjectTemplateResponseMixin from typing_extensions import Literal +from django.http import HttpRequest, HttpResponse + class FormMixin(ContextMixin): initial: Dict[str, Any] = ... form_class: Optional[Type[BaseForm]] = ... diff --git a/scripts/enabled_test_modules.py b/scripts/enabled_test_modules.py index da8d4ec..9fd4b20 100644 --- a/scripts/enabled_test_modules.py +++ b/scripts/enabled_test_modules.py @@ -3,7 +3,7 @@ import re IGNORED_MODULES = {'schema', 'gis_tests', 'admin_widgets', 'admin_filters', - 'sitemaps_tests', 'staticfiles_tests', 'modeladmin', 'model_forms', + 'sitemaps_tests', 'staticfiles_tests', 'modeladmin', 'generic_views', 'forms_tests', 'flatpages_tests', 'admin_ordering', 'admin_changelist', 'admin_views', 'invalid_models_tests', 'i18n', 'model_formsets', @@ -283,6 +283,14 @@ IGNORED_ERRORS = { 'Incompatible type for "size" of "FloatModel" (got "object", expected "Union[float, int, str, Combinable]")', 'Incompatible type for "value" of "IntegerModel" (got "object", expected', ], + 'model_forms': [ + '"render" of "Widget"', + "Module 'django.core.validators' has no attribute 'ValidationError'", + 'Incompatible types in assignment', + 'NewForm', + '"type" has no attribute "base_fields"', + 'Argument "instance" to "InvalidModelForm" has incompatible type "Type[Category]"', + ], 'model_indexes': [ 'Argument "condition" to "Index" has incompatible type "str"; expected "Optional[Q]"' ], diff --git a/scripts/typecheck_tests.py b/scripts/typecheck_tests.py index 100ec34..c3d38ca 100644 --- a/scripts/typecheck_tests.py +++ b/scripts/typecheck_tests.py @@ -14,8 +14,8 @@ from scripts.enabled_test_modules import ( ) DJANGO_COMMIT_REFS: Dict[str, Tuple[str, str]] = { - '2.2': ('stable/2.2.x', 'e8b0903976077b951795938b260211214ed7fe41'), - '3.0': ('stable/3.0.x', '7ec5962638144cbf4c2e47ea7d8dc02d1ce44394') + '2.2': ('stable/2.2.x', '86befcc172c23170a720b3e0c06db51a99b3da59'), + '3.0': ('stable/3.0.x', '6cb30414bc0f83b49afc4cae76d4af5656effe9a') } PROJECT_DIRECTORY = Path(__file__).parent.parent DJANGO_SOURCE_DIRECTORY = PROJECT_DIRECTORY / 'django-sources' # type: Path