From adf69755d62facbad2e267868d91dd0509575a3d Mon Sep 17 00:00:00 2001 From: Marti Raudsepp Date: Thu, 5 Oct 2023 10:14:54 +0300 Subject: [PATCH] Harmonize `mypy.ini` config with django-stubs (#479) * Most of the overrides in `tests/plugins.ini` are no longer needed * Removed lots of unneeded `# type: ignore` comments * Will create a separate PR to update `disallow_untyped_defs` and `disallow_incomplete_defs` too --- mypy.ini | 18 ++++++++++++++---- pytest.ini | 2 +- rest_framework-stubs/compat.pyi | 10 +++++----- rest_framework-stubs/permissions.pyi | 4 ++-- rest_framework-stubs/relations.pyi | 4 ++-- rest_framework-stubs/request.pyi | 4 ++-- rest_framework-stubs/serializers.pyi | 14 +++++++------- rest_framework-stubs/views.pyi | 2 +- tests/plugins.ini | 25 ------------------------- 9 files changed, 34 insertions(+), 49 deletions(-) delete mode 100644 tests/plugins.ini diff --git a/mypy.ini b/mypy.ini index 273db4ae1..8d0b8fa75 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,10 +1,17 @@ [mypy] -strict_optional = true -ignore_missing_imports = true -check_untyped_defs = true -show_traceback = true allow_redefinition = true +check_untyped_defs = true +ignore_missing_imports = true incremental = true +strict_optional = true +show_traceback = true +warn_unused_ignores = true +warn_redundant_casts = true +warn_unused_configs = true +warn_unreachable = true +# TODO: enable disallow_*_defs later +disallow_untyped_defs = false +disallow_incomplete_defs = false disable_error_code = empty-body # TODO: update our test error messages to match new mypy output show_error_codes = false @@ -17,3 +24,6 @@ plugins = [mypy.plugins.django-stubs] django_settings_module = scripts.drf_tests_settings + +[mypy-uritemplate.*] +warn_unreachable = false diff --git a/pytest.ini b/pytest.ini index 2f71e564b..b7b79b42d 100644 --- a/pytest.ini +++ b/pytest.ini @@ -6,5 +6,5 @@ addopts = -s -v --cache-clear - --mypy-ini-file=./tests/plugins.ini + --mypy-ini-file=mypy.ini --mypy-extension-hook=scripts.tests_extension_hook.django_plugin_hook diff --git a/rest_framework-stubs/compat.pyi b/rest_framework-stubs/compat.pyi index cf9b99a35..24ad69ff6 100644 --- a/rest_framework-stubs/compat.pyi +++ b/rest_framework-stubs/compat.pyi @@ -10,7 +10,7 @@ except ImportError: try: import coreapi except ImportError: - coreapi = None # type: ignore + coreapi = None try: import uritemplate except ImportError: @@ -18,7 +18,7 @@ except ImportError: try: import coreschema except ImportError: - coreschema = None # type: ignore + coreschema = None try: import yaml except ImportError: @@ -30,9 +30,9 @@ except ImportError: try: import pygments except ImportError: - pygments = None # type: ignore + pygments = None try: - import markdown # type: ignore + import markdown def apply_markdown(text: str): ... except ImportError: @@ -40,7 +40,7 @@ except ImportError: markdown = None # type: ignore if markdown is not None and pygments is not None: - from markdown.preprocessors import Preprocessor # type: ignore + from markdown.preprocessors import Preprocessor class CodeBlockPreprocessor(Preprocessor): pattern: Any diff --git a/rest_framework-stubs/permissions.pyi b/rest_framework-stubs/permissions.pyi index 295bb1394..c9f758f93 100644 --- a/rest_framework-stubs/permissions.pyi +++ b/rest_framework-stubs/permissions.pyi @@ -46,9 +46,9 @@ class OR(_SupportsHasPermission): class NOT(_SupportsHasPermission): def __init__(self, op1: _SupportsHasPermission) -> None: ... -class BasePermissionMetaclass(OperationHolderMixin, type): ... # type: ignore[misc] +class BasePermissionMetaclass(OperationHolderMixin, type): ... # type: ignore[misc,unused-ignore] -class BasePermission(metaclass=BasePermissionMetaclass): # type: ignore[misc] +class BasePermission(metaclass=BasePermissionMetaclass): def has_permission(self, request: Request, view: APIView) -> bool: ... def has_object_permission(self, request: Request, view: APIView, obj: Any) -> bool: ... diff --git a/rest_framework-stubs/relations.pyi b/rest_framework-stubs/relations.pyi index d51c8e510..da10fe749 100644 --- a/rest_framework-stubs/relations.pyi +++ b/rest_framework-stubs/relations.pyi @@ -67,7 +67,7 @@ class RelatedField(Generic[_MT, _DT, _PT], Field[_MT, _DT, _PT, Any]): @property def grouped_choices(self) -> dict: ... def iter_options(self) -> Iterable[Option]: ... - def get_attribute(self, instance: _MT) -> _PT | None: ... # type: ignore[override] + def get_attribute(self, instance: _MT) -> _PT | None: ... def display_value(self, instance: _MT) -> str: ... class StringRelatedField(RelatedField[_MT, _MT, str]): ... @@ -180,7 +180,7 @@ class ManyRelatedField(Field[Sequence[Any], Sequence[Any], list[Any], Any]): allow_empty: bool = ..., child_relation: RelatedField = ..., ): ... - def get_value(self, dictionary: Mapping[Any, Any]) -> list[Any]: ... # type: ignore[override] + def get_value(self, dictionary: Mapping[Any, Any]) -> list[Any]: ... def get_choices(self, cutoff: int | None = ...) -> dict: ... @property def choices(self) -> dict: ... diff --git a/rest_framework-stubs/request.pyi b/rest_framework-stubs/request.pyi index 8ffd7f65b..5befd99bb 100644 --- a/rest_framework-stubs/request.pyi +++ b/rest_framework-stubs/request.pyi @@ -65,8 +65,8 @@ class Request(HttpRequest): def query_params(self) -> _ImmutableQueryDict: ... @property def data(self) -> dict[str, Any]: ... - @property # type: ignore[override] - def user(self) -> AbstractBaseUser | AnonymousUser: ... # type: ignore[override] + @property + def user(self) -> AbstractBaseUser | AnonymousUser: ... @user.setter def user(self, value: AbstractBaseUser | AnonymousUser) -> None: ... @property diff --git a/rest_framework-stubs/serializers.pyi b/rest_framework-stubs/serializers.pyi index e83845625..67305ca81 100644 --- a/rest_framework-stubs/serializers.pyi +++ b/rest_framework-stubs/serializers.pyi @@ -111,7 +111,7 @@ class BaseSerializer(Generic[_IN], Field[Any, Any, Any, _IN]): def update(self, instance: _IN, validated_data: Any) -> _IN: ... def create(self, validated_data: Any) -> _IN: ... def save(self, **kwargs: Any) -> _IN: ... - def to_representation(self, instance: _IN) -> Any: ... # type: ignore[override] + def to_representation(self, instance: _IN) -> Any: ... class SerializerMetaclass(type): def __new__(cls, name: Any, bases: Any, attrs: Any): ... @@ -189,7 +189,7 @@ class ModelSerializer(Serializer, BaseSerializer[_MT]): serializer_url_field: type[RelatedField] serializer_choice_field: type[Field] url_field_name: str | None - instance: _MT | Sequence[_MT] | None # type: ignore[override] + instance: _MT | Sequence[_MT] | None class Meta: model: type[_MT] # type: ignore @@ -197,7 +197,7 @@ class ModelSerializer(Serializer, BaseSerializer[_MT]): read_only_fields: Sequence[str] | None exclude: Sequence[str] | None depth: int | None - extra_kwargs: dict[str, dict[str, Any]] # type: ignore[override] + extra_kwargs: dict[str, dict[str, Any]] def __init__( self, instance: None | _MT | Sequence[_MT] | QuerySet[_MT] | Manager[_MT] = ..., @@ -219,10 +219,10 @@ class ModelSerializer(Serializer, BaseSerializer[_MT]): allow_null: bool = ..., allow_empty: bool = ..., ): ... - def update(self, instance: _MT, validated_data: Any) -> _MT: ... # type: ignore[override] - def create(self, validated_data: Any) -> _MT: ... # type: ignore[override] - def save(self, **kwargs: Any) -> _MT: ... # type: ignore[override] - def to_representation(self, instance: _MT) -> Any: ... # type: ignore[override] + def update(self, instance: _MT, validated_data: Any) -> _MT: ... + def create(self, validated_data: Any) -> _MT: ... + def save(self, **kwargs: Any) -> _MT: ... + def to_representation(self, instance: _MT) -> Any: ... def get_field_names(self, declared_fields: Mapping[str, Field], info: FieldInfo) -> list[str]: ... def get_default_field_names(self, declared_fields: Mapping[str, Field], model_info: FieldInfo) -> list[str]: ... def build_field( diff --git a/rest_framework-stubs/views.pyi b/rest_framework-stubs/views.pyi index d0b335ddf..0e03149cf 100644 --- a/rest_framework-stubs/views.pyi +++ b/rest_framework-stubs/views.pyi @@ -88,5 +88,5 @@ class APIView(View): def finalize_response(self, request: Request, response: Response, *args: Any, **kwargs: Any) -> Response: ... def handle_exception(self, exc: Exception) -> Response: ... def raise_uncaught_exception(self, exc: Exception) -> NoReturn: ... - def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponseBase: ... # type: ignore[override] + def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponseBase: ... def options(self, request: Request, *args: Any, **kwargs: Any): ... # type: ignore[override] diff --git a/tests/plugins.ini b/tests/plugins.ini deleted file mode 100644 index 81a1459ef..000000000 --- a/tests/plugins.ini +++ /dev/null @@ -1,25 +0,0 @@ -[mypy] -check_untyped_defs = true -disable_error_code = empty-body -plugins = - mypy_django_plugin.main, - mypy_drf_plugin.main -# TODO: update our test error messages to match new mypy output -show_error_codes = false -force_uppercase_builtins = true -force_union_syntax = true - -[mypy-coreapi] -ignore_missing_imports = true - -[mypy-coreschema] -ignore_missing_imports = true - -[mypy-pygments] -ignore_missing_imports = true - -[mypy-psycopg2.extras] -ignore_missing_imports = true - -[mypy-uritemplate] -ignore_missing_imports = true