From 552f2ffc0c2481b592b9f634c245c615acf48c7f Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Sun, 4 Jul 2021 15:41:51 +0300 Subject: [PATCH] Adds more rules to mypy config, related #662 (#663) * Adds more rules to mypy config, related #662 * Removes plugin.ini for mypy settings * Fixes build --- .github/workflows/test.yml | 2 +- django-stubs/contrib/auth/models.pyi | 2 +- django-stubs/contrib/postgres/fields/ranges.pyi | 2 +- .../management/commands/runserver.pyi | 2 +- django-stubs/core/mail/message.pyi | 2 +- django-stubs/core/serializers/xml_serializer.pyi | 2 +- django-stubs/db/backends/utils.pyi | 2 +- django-stubs/test/client.pyi | 16 ++++++++-------- mypy.ini | 13 ++++++++----- mypy_django_plugin/django/context.py | 6 +++--- mypy_django_plugin/lib/helpers.py | 2 +- mypy_django_plugin/main.py | 2 +- mypy_django_plugin/transformers/models.py | 7 +++++-- pytest.ini | 2 +- setup.py | 1 + tests/plugins.ini | 5 ----- 16 files changed, 35 insertions(+), 33 deletions(-) delete mode 100644 tests/plugins.ini diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ac6f300..2a1c56e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.7'] + python-version: ['3.8'] steps: - uses: actions/checkout@v2 - name: Setup system dependencies diff --git a/django-stubs/contrib/auth/models.pyi b/django-stubs/contrib/auth/models.pyi index 921841e..11321ad 100644 --- a/django-stubs/contrib/auth/models.pyi +++ b/django-stubs/contrib/auth/models.pyi @@ -70,7 +70,7 @@ class PermissionsMixin(models.Model): def has_perms(self, perm_list: Collection[str], obj: Optional[_AnyUser] = ...) -> bool: ... def has_module_perms(self, app_label: str) -> bool: ... -class AbstractUser(AbstractBaseUser, PermissionsMixin): # type: ignore +class AbstractUser(AbstractBaseUser, PermissionsMixin): username_validator: UnicodeUsernameValidator = ... username = models.CharField(max_length=150) diff --git a/django-stubs/contrib/postgres/fields/ranges.pyi b/django-stubs/contrib/postgres/fields/ranges.pyi index dc71197..7bf1e6e 100644 --- a/django-stubs/contrib/postgres/fields/ranges.pyi +++ b/django-stubs/contrib/postgres/fields/ranges.pyi @@ -2,7 +2,7 @@ from typing import Any from django.db import models -from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange # type: ignore +from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange class RangeField(models.Field): empty_strings_allowed: bool = ... diff --git a/django-stubs/contrib/staticfiles/management/commands/runserver.pyi b/django-stubs/contrib/staticfiles/management/commands/runserver.pyi index 20cfd79..6be2de8 100644 --- a/django-stubs/contrib/staticfiles/management/commands/runserver.pyi +++ b/django-stubs/contrib/staticfiles/management/commands/runserver.pyi @@ -1,3 +1,3 @@ -from django.core.management.commands.runserver import Command as RunserverCommand # type: ignore +from django.core.management.commands.runserver import Command as RunserverCommand class Command(RunserverCommand): ... diff --git a/django-stubs/core/mail/message.pyi b/django-stubs/core/mail/message.pyi index f6b29af..d634795 100644 --- a/django-stubs/core/mail/message.pyi +++ b/django-stubs/core/mail/message.pyi @@ -1,4 +1,4 @@ -from email._policybase import Policy # type: ignore +from email._policybase import Policy from email.message import Message from email.mime.base import MIMEBase from email.mime.message import MIMEMessage diff --git a/django-stubs/core/serializers/xml_serializer.pyi b/django-stubs/core/serializers/xml_serializer.pyi index e81e07a..336c406 100644 --- a/django-stubs/core/serializers/xml_serializer.pyi +++ b/django-stubs/core/serializers/xml_serializer.pyi @@ -1,6 +1,6 @@ from django.core.serializers import base as base from typing import Any -from xml.sax.expatreader import ExpatParser as _ExpatParser # type: ignore +from xml.sax.expatreader import ExpatParser as _ExpatParser class Serializer(base.Serializer): def indent(self, level: Any) -> None: ... diff --git a/django-stubs/db/backends/utils.pyi b/django-stubs/db/backends/utils.pyi index 4a377cb..de07b8e 100644 --- a/django-stubs/db/backends/utils.pyi +++ b/django-stubs/db/backends/utils.pyi @@ -1,7 +1,7 @@ import types from datetime import date, datetime, time from decimal import Decimal -from typing import Any, ContextManager, Dict, List, Mapping, Optional, Sequence, Tuple, Type, Union +from typing import Any, ContextManager, Dict, List, Mapping, Optional, Sequence, Tuple, Type, Union, Iterator from uuid import UUID logger: Any diff --git a/django-stubs/test/client.pyi b/django-stubs/test/client.pyi index 7e0f752..4a3e14c 100644 --- a/django-stubs/test/client.pyi +++ b/django-stubs/test/client.pyi @@ -94,16 +94,16 @@ class Client(RequestFactory): def request(self, **request: Any) -> HttpResponse: ... # type: ignore def get( # type: ignore self, path: str, data: Any = ..., follow: bool = ..., secure: bool = ..., **extra: Any - ) -> HttpResponse: ... # type: ignore + ) -> HttpResponse: ... def post( # type: ignore self, path: str, data: Any = ..., content_type: str = ..., follow: bool = ..., secure: bool = ..., **extra: Any - ) -> HttpResponse: ... # type: ignore + ) -> HttpResponse: ... def head( # type: ignore self, path: str, data: Any = ..., follow: bool = ..., secure: bool = ..., **extra: Any - ) -> HttpResponse: ... # type: ignore + ) -> HttpResponse: ... def trace( # type: ignore self, path: str, follow: bool = ..., secure: bool = ..., **extra: Any - ) -> HttpResponse: ... # type: ignore + ) -> HttpResponse: ... def options( # type: ignore self, path: str, @@ -112,16 +112,16 @@ class Client(RequestFactory): follow: bool = ..., secure: bool = ..., **extra: Any - ) -> HttpResponse: ... # type: ignore + ) -> HttpResponse: ... def put( # type: ignore self, path: str, data: Any = ..., content_type: str = ..., follow: bool = ..., secure: bool = ..., **extra: Any - ) -> HttpResponse: ... # type: ignore + ) -> HttpResponse: ... def patch( # type: ignore self, path: str, data: Any = ..., content_type: str = ..., follow: bool = ..., secure: bool = ..., **extra: Any - ) -> HttpResponse: ... # type: ignore + ) -> HttpResponse: ... def delete( # type: ignore self, path: str, data: Any = ..., content_type: str = ..., follow: bool = ..., secure: bool = ..., **extra: Any - ) -> HttpResponse: ... # type: ignore + ) -> HttpResponse: ... def store_exc_info(self, **kwargs: Any) -> None: ... @property def session(self) -> SessionBase: ... diff --git a/mypy.ini b/mypy.ini index c6f0e17..b6a4d67 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,11 +1,14 @@ [mypy] -strict_optional = True -ignore_missing_imports = True -check_untyped_defs = True -warn_no_return = False -show_traceback = True allow_redefinition = True +check_untyped_defs = True +ignore_missing_imports = True incremental = True +strict_optional = True +show_traceback = True +warn_no_return = False +warn_unused_ignores = True +warn_redundant_casts = True +warn_unused_configs = True plugins = mypy_django_plugin.main diff --git a/mypy_django_plugin/django/context.py b/mypy_django_plugin/django/context.py index acbacb2..b9099c8 100644 --- a/mypy_django_plugin/django/context.py +++ b/mypy_django_plugin/django/context.py @@ -99,7 +99,7 @@ class DjangoContext: @cached_property def model_modules(self) -> Dict[str, Set[Type[Model]]]: - """ All modules that contain Django models. """ + """All modules that contain Django models.""" if self.apps_registry is None: return {} @@ -251,7 +251,7 @@ class DjangoContext: return nullable def get_field_set_type(self, api: TypeChecker, field: Union[Field, ForeignObjectRel], *, method: str) -> MypyType: - """ Get a type of __set__ for this specific Django field. """ + """Get a type of __set__ for this specific Django field.""" target_field = field if isinstance(field, ForeignKey): target_field = field.target_field @@ -269,7 +269,7 @@ class DjangoContext: return field_set_type def get_field_get_type(self, api: TypeChecker, field: Union[Field, ForeignObjectRel], *, method: str) -> MypyType: - """ Get a type of __get__ for this specific Django field. """ + """Get a type of __get__ for this specific Django field.""" field_info = helpers.lookup_class_typeinfo(api, field.__class__) if field_info is None: return AnyType(TypeOfAny.unannotated) diff --git a/mypy_django_plugin/lib/helpers.py b/mypy_django_plugin/lib/helpers.py index 3485ccd..64eeba7 100644 --- a/mypy_django_plugin/lib/helpers.py +++ b/mypy_django_plugin/lib/helpers.py @@ -157,7 +157,7 @@ def iter_bases(info: TypeInfo) -> Iterator[Instance]: def get_private_descriptor_type(type_info: TypeInfo, private_field_name: str, is_nullable: bool) -> MypyType: - """ Return declared type of type_info's private_field_name (used for private Field attributes)""" + """Return declared type of type_info's private_field_name (used for private Field attributes)""" sym = type_info.get(private_field_name) if sym is None: return AnyType(TypeOfAny.explicit) diff --git a/mypy_django_plugin/main.py b/mypy_django_plugin/main.py index c20f653..a00b5e1 100644 --- a/mypy_django_plugin/main.py +++ b/mypy_django_plugin/main.py @@ -126,7 +126,7 @@ def extract_django_settings_module(config_file_path: Optional[str]) -> str: exit(2) settings = parser.get(section, "django_settings_module", fallback=None) or exit(3) - return cast(str, settings).strip("'\"") + return settings.strip("'\"") class NewSemanalDjangoPlugin(Plugin): diff --git a/mypy_django_plugin/transformers/models.py b/mypy_django_plugin/transformers/models.py index 00ad398..4321ee8 100644 --- a/mypy_django_plugin/transformers/models.py +++ b/mypy_django_plugin/transformers/models.py @@ -189,9 +189,12 @@ class AddManagers(ModelClassInitializer): return custom_manager_type def run_with_model_cls(self, model_cls: Type[Model]) -> None: + manager_info: Optional[TypeInfo] + for manager_name, manager in model_cls._meta.managers_map.items(): manager_class_name = manager.__class__.__name__ manager_fullname = helpers.get_class_fullname(manager.__class__) + try: manager_info = self.lookup_typeinfo_or_incomplete_defn_error(manager_fullname) except helpers.IncompleteDefnException as exc: @@ -204,7 +207,7 @@ class AddManagers(ModelClassInitializer): # not a generated manager, continue with the loop continue real_manager_fullname = generated_managers[manager_fullname] - manager_info = self.lookup_typeinfo(real_manager_fullname) # type: ignore + manager_info = self.lookup_typeinfo(real_manager_fullname) if manager_info is None: continue manager_class_name = real_manager_fullname.rsplit(".", maxsplit=1)[1] @@ -310,7 +313,7 @@ class AddRelatedManagers(ModelClassInitializer): generated_managers = self.get_generated_manager_mappings(base_manager_fullname) if manager_fullname in generated_managers: real_manager_fullname = generated_managers[manager_fullname] - manager_info = self.lookup_typeinfo(real_manager_fullname) # type: ignore + manager_info = self.lookup_typeinfo(real_manager_fullname) if manager_info: return Instance(manager_info, [Instance(related_model_info, [])]) return None diff --git a/pytest.ini b/pytest.ini index b874365..ae5aa2b 100644 --- a/pytest.ini +++ b/pytest.ini @@ -7,5 +7,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/setup.py b/setup.py index 9cd9ef6..d137481 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,7 @@ dependencies = [ "django", "django-stubs-ext", "types-pytz", + "types-PyYAML", "toml", ] diff --git a/tests/plugins.ini b/tests/plugins.ini deleted file mode 100644 index b7b510b..0000000 --- a/tests/plugins.ini +++ /dev/null @@ -1,5 +0,0 @@ -[mypy] -incremental = True -strict_optional = True -plugins = - mypy_django_plugin.main