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
strategy:
matrix:
python-version: ['3.7']
python-version: ['3.8']
steps:
- uses: actions/checkout@v2
- 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_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)

View File

@@ -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 = ...

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): ...

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.mime.base import MIMEBase
from email.mime.message import MIMEMessage

View File

@@ -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: ...

View File

@@ -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

View File

@@ -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: ...

View File

@@ -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

View File

@@ -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)

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:
""" 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)

View File

@@ -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):

View File

@@ -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

View File

@@ -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

View File

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

View File

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