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
This commit is contained in:
Nikita Sobolev
2021-07-04 15:41:51 +03:00
committed by GitHub
parent d9c63f5e71
commit 552f2ffc0c
16 changed files with 35 additions and 33 deletions

View File

@@ -37,7 +37,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
python-version: ['3.7'] python-version: ['3.8']
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Setup system dependencies - name: Setup system dependencies

View File

@@ -70,7 +70,7 @@ class PermissionsMixin(models.Model):
def has_perms(self, perm_list: Collection[str], obj: Optional[_AnyUser] = ...) -> bool: ... def has_perms(self, perm_list: Collection[str], obj: Optional[_AnyUser] = ...) -> bool: ...
def has_module_perms(self, app_label: str) -> bool: ... def has_module_perms(self, app_label: str) -> bool: ...
class AbstractUser(AbstractBaseUser, PermissionsMixin): # type: ignore class AbstractUser(AbstractBaseUser, PermissionsMixin):
username_validator: UnicodeUsernameValidator = ... username_validator: UnicodeUsernameValidator = ...
username = models.CharField(max_length=150) username = models.CharField(max_length=150)

View File

@@ -2,7 +2,7 @@ from typing import Any
from django.db import models 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): class RangeField(models.Field):
empty_strings_allowed: bool = ... empty_strings_allowed: bool = ...

View File

@@ -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): ... class Command(RunserverCommand): ...

View File

@@ -1,4 +1,4 @@
from email._policybase import Policy # type: ignore from email._policybase import Policy
from email.message import Message from email.message import Message
from email.mime.base import MIMEBase from email.mime.base import MIMEBase
from email.mime.message import MIMEMessage from email.mime.message import MIMEMessage

View File

@@ -1,6 +1,6 @@
from django.core.serializers import base as base from django.core.serializers import base as base
from typing import Any 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): class Serializer(base.Serializer):
def indent(self, level: Any) -> None: ... def indent(self, level: Any) -> None: ...

View File

@@ -1,7 +1,7 @@
import types import types
from datetime import date, datetime, time from datetime import date, datetime, time
from decimal import Decimal 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 from uuid import UUID
logger: Any logger: Any

View File

@@ -94,16 +94,16 @@ class Client(RequestFactory):
def request(self, **request: Any) -> HttpResponse: ... # type: ignore def request(self, **request: Any) -> HttpResponse: ... # type: ignore
def get( # type: ignore def get( # type: ignore
self, path: str, data: Any = ..., follow: bool = ..., secure: bool = ..., **extra: Any self, path: str, data: Any = ..., follow: bool = ..., secure: bool = ..., **extra: Any
) -> HttpResponse: ... # type: ignore ) -> HttpResponse: ...
def post( # type: ignore def post( # type: ignore
self, path: str, data: Any = ..., content_type: str = ..., follow: bool = ..., secure: bool = ..., **extra: Any self, path: str, data: Any = ..., content_type: str = ..., follow: bool = ..., secure: bool = ..., **extra: Any
) -> HttpResponse: ... # type: ignore ) -> HttpResponse: ...
def head( # type: ignore def head( # type: ignore
self, path: str, data: Any = ..., follow: bool = ..., secure: bool = ..., **extra: Any self, path: str, data: Any = ..., follow: bool = ..., secure: bool = ..., **extra: Any
) -> HttpResponse: ... # type: ignore ) -> HttpResponse: ...
def trace( # type: ignore def trace( # type: ignore
self, path: str, follow: bool = ..., secure: bool = ..., **extra: Any self, path: str, follow: bool = ..., secure: bool = ..., **extra: Any
) -> HttpResponse: ... # type: ignore ) -> HttpResponse: ...
def options( # type: ignore def options( # type: ignore
self, self,
path: str, path: str,
@@ -112,16 +112,16 @@ class Client(RequestFactory):
follow: bool = ..., follow: bool = ...,
secure: bool = ..., secure: bool = ...,
**extra: Any **extra: Any
) -> HttpResponse: ... # type: ignore ) -> HttpResponse: ...
def put( # type: ignore def put( # type: ignore
self, path: str, data: Any = ..., content_type: str = ..., follow: bool = ..., secure: bool = ..., **extra: Any self, path: str, data: Any = ..., content_type: str = ..., follow: bool = ..., secure: bool = ..., **extra: Any
) -> HttpResponse: ... # type: ignore ) -> HttpResponse: ...
def patch( # type: ignore def patch( # type: ignore
self, path: str, data: Any = ..., content_type: str = ..., follow: bool = ..., secure: bool = ..., **extra: Any self, path: str, data: Any = ..., content_type: str = ..., follow: bool = ..., secure: bool = ..., **extra: Any
) -> HttpResponse: ... # type: ignore ) -> HttpResponse: ...
def delete( # type: ignore def delete( # type: ignore
self, path: str, data: Any = ..., content_type: str = ..., follow: bool = ..., secure: bool = ..., **extra: Any 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: ... def store_exc_info(self, **kwargs: Any) -> None: ...
@property @property
def session(self) -> SessionBase: ... def session(self) -> SessionBase: ...

View File

@@ -1,11 +1,14 @@
[mypy] [mypy]
strict_optional = True
ignore_missing_imports = True
check_untyped_defs = True
warn_no_return = False
show_traceback = True
allow_redefinition = True allow_redefinition = True
check_untyped_defs = True
ignore_missing_imports = True
incremental = 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 = plugins =
mypy_django_plugin.main mypy_django_plugin.main

View File

@@ -99,7 +99,7 @@ class DjangoContext:
@cached_property @cached_property
def model_modules(self) -> Dict[str, Set[Type[Model]]]: 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: if self.apps_registry is None:
return {} return {}
@@ -251,7 +251,7 @@ class DjangoContext:
return nullable 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, 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 target_field = field
if isinstance(field, ForeignKey): if isinstance(field, ForeignKey):
target_field = field.target_field target_field = field.target_field
@@ -269,7 +269,7 @@ class DjangoContext:
return field_set_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, 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__) field_info = helpers.lookup_class_typeinfo(api, field.__class__)
if field_info is None: if field_info is None:
return AnyType(TypeOfAny.unannotated) return AnyType(TypeOfAny.unannotated)

View File

@@ -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: 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) sym = type_info.get(private_field_name)
if sym is None: if sym is None:
return AnyType(TypeOfAny.explicit) return AnyType(TypeOfAny.explicit)

View File

@@ -126,7 +126,7 @@ def extract_django_settings_module(config_file_path: Optional[str]) -> str:
exit(2) exit(2)
settings = parser.get(section, "django_settings_module", fallback=None) or exit(3) settings = parser.get(section, "django_settings_module", fallback=None) or exit(3)
return cast(str, settings).strip("'\"") return settings.strip("'\"")
class NewSemanalDjangoPlugin(Plugin): class NewSemanalDjangoPlugin(Plugin):

View File

@@ -189,9 +189,12 @@ class AddManagers(ModelClassInitializer):
return custom_manager_type return custom_manager_type
def run_with_model_cls(self, model_cls: Type[Model]) -> None: 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(): for manager_name, manager in model_cls._meta.managers_map.items():
manager_class_name = manager.__class__.__name__ manager_class_name = manager.__class__.__name__
manager_fullname = helpers.get_class_fullname(manager.__class__) manager_fullname = helpers.get_class_fullname(manager.__class__)
try: try:
manager_info = self.lookup_typeinfo_or_incomplete_defn_error(manager_fullname) manager_info = self.lookup_typeinfo_or_incomplete_defn_error(manager_fullname)
except helpers.IncompleteDefnException as exc: except helpers.IncompleteDefnException as exc:
@@ -204,7 +207,7 @@ class AddManagers(ModelClassInitializer):
# not a generated manager, continue with the loop # not a generated manager, continue with the loop
continue continue
real_manager_fullname = generated_managers[manager_fullname] 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: if manager_info is None:
continue continue
manager_class_name = real_manager_fullname.rsplit(".", maxsplit=1)[1] 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) generated_managers = self.get_generated_manager_mappings(base_manager_fullname)
if manager_fullname in generated_managers: if manager_fullname in generated_managers:
real_manager_fullname = generated_managers[manager_fullname] 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: if manager_info:
return Instance(manager_info, [Instance(related_model_info, [])]) return Instance(manager_info, [Instance(related_model_info, [])])
return None return None

View File

@@ -7,5 +7,5 @@ addopts =
-s -s
-v -v
--cache-clear --cache-clear
--mypy-ini-file=./tests/plugins.ini --mypy-ini-file=./mypy.ini
--mypy-extension-hook=scripts.tests_extension_hook.django_plugin_hook --mypy-extension-hook=scripts.tests_extension_hook.django_plugin_hook

View File

@@ -26,6 +26,7 @@ dependencies = [
"django", "django",
"django-stubs-ext", "django-stubs-ext",
"types-pytz", "types-pytz",
"types-PyYAML",
"toml", "toml",
] ]

View File

@@ -1,5 +0,0 @@
[mypy]
incremental = True
strict_optional = True
plugins =
mypy_django_plugin.main