Update typecheck_tests to django 2.2 branch, remove unused ignores (#98)

* update typecheck_tests to django 2.2 branch, remove unused ignores

* lint fixes
This commit is contained in:
Maxim Kurnikov
2019-07-01 18:44:34 +03:00
committed by GitHub
parent 4e1c32f6a3
commit a77d5b27d8
14 changed files with 124 additions and 215 deletions

View File

@@ -1,10 +1,10 @@
from typing import Any, Dict, List, Optional, Set, Tuple, Union from typing import Any, Dict, Optional, Tuple, Union
from uuid import UUID from uuid import UUID
from django.contrib.admin.sites import AdminSite from django.contrib.admin.sites import AdminSite
from django.db.models.fields.reverse_related import ForeignObjectRel, ManyToOneRel from django.db.models.fields.reverse_related import ForeignObjectRel, ManyToOneRel
from django.forms.models import ModelChoiceIterator from django.forms.models import ModelChoiceIterator
from django.forms.widgets import ChoiceWidget, Media from django.forms.widgets import Media
from django import forms from django import forms
@@ -43,7 +43,7 @@ class ManyToManyRawIdWidget(ForeignKeyRawIdWidget): ...
class RelatedFieldWidgetWrapper(forms.Widget): class RelatedFieldWidgetWrapper(forms.Widget):
template_name: str = ... template_name: str = ...
choices: ModelChoiceIterator = ... choices: ModelChoiceIterator = ...
widget: AutocompleteSelect = ... widget: forms.Widget = ...
rel: ManyToOneRel = ... rel: ManyToOneRel = ...
can_add_related: bool = ... can_add_related: bool = ...
can_change_related: bool = ... can_change_related: bool = ...
@@ -52,7 +52,7 @@ class RelatedFieldWidgetWrapper(forms.Widget):
admin_site: AdminSite = ... admin_site: AdminSite = ...
def __init__( def __init__(
self, self,
widget: ChoiceWidget, widget: forms.Widget,
rel: ForeignObjectRel, rel: ForeignObjectRel,
admin_site: AdminSite, admin_site: AdminSite,
can_add_related: Optional[bool] = ..., can_add_related: Optional[bool] = ...,

View File

@@ -42,10 +42,14 @@ class BaseCommand:
stderr: OutputWrapper = ... stderr: OutputWrapper = ...
style: Style = ... style: Style = ...
def __init__( def __init__(
self, stdout: Optional[StringIO] = ..., stderr: Optional[StringIO] = ..., no_color: bool = ... self,
stdout: Optional[StringIO] = ...,
stderr: Optional[StringIO] = ...,
no_color: bool = ...,
force_color: bool = ...,
) -> None: ... ) -> None: ...
def get_version(self) -> str: ... def get_version(self) -> str: ...
def create_parser(self, prog_name: str, subcommand: str) -> CommandParser: ... def create_parser(self, prog_name: str, subcommand: str, **kwargs: Any) -> CommandParser: ...
def add_arguments(self, parser: CommandParser) -> None: ... def add_arguments(self, parser: CommandParser) -> None: ...
def print_help(self, prog_name: str, subcommand: str) -> None: ... def print_help(self, prog_name: str, subcommand: str) -> None: ...
def run_from_argv(self, argv: List[str]) -> None: ... def run_from_argv(self, argv: List[str]) -> None: ...

View File

@@ -47,7 +47,7 @@ class MigrationGraph:
def iterative_dfs(self, start: Any, forwards: bool = ...): ... def iterative_dfs(self, start: Any, forwards: bool = ...): ...
def root_nodes(self, app: Optional[str] = ...) -> List[Tuple[str, str]]: ... def root_nodes(self, app: Optional[str] = ...) -> List[Tuple[str, str]]: ...
def leaf_nodes(self, app: Optional[str] = ...) -> List[Tuple[str, str]]: ... def leaf_nodes(self, app: Optional[str] = ...) -> List[Tuple[str, str]]: ...
def ensure_not_cyclic(self, start: Union[Tuple[str, str], Node], get_children: Callable) -> None: ... def ensure_not_cyclic(self) -> None: ...
def make_state( def make_state(
self, nodes: Optional[Tuple[str, str]] = ..., at_end: bool = ..., real_apps: List[str] = ... self, nodes: Optional[Tuple[str, str]] = ..., at_end: bool = ..., real_apps: List[str] = ...
) -> ProjectState: ... ) -> ProjectState: ...

View File

@@ -8,7 +8,7 @@ MIGRATIONS_MODULE_NAME: str
class MigrationLoader: class MigrationLoader:
connection: Any = ... connection: Any = ...
disk_migrations: Dict[Tuple[str, str], Migration] = ... disk_migrations: Dict[Tuple[str, str], Migration] = ...
applied_migrations: None = ... applied_migrations: Set[Tuple[str, str]] = ...
ignore_no_migrations: bool = ... ignore_no_migrations: bool = ...
def __init__(self, connection: Any, load: bool = ..., ignore_no_migrations: bool = ...) -> None: ... def __init__(self, connection: Any, load: bool = ..., ignore_no_migrations: bool = ...) -> None: ...
@classmethod @classmethod

View File

@@ -1,20 +1,20 @@
from typing import Any from typing import Any, Optional
from django.db.models.fields import Field from django.db.models.fields import Field
from .base import Operation from .base import Operation
class FieldOperation(Operation): class FieldOperation(Operation):
model_name: Any = ... model_name: str = ...
model_name_lower: str model_name_lower: str
name: Any = ... name: str = ...
def __init__(self, model_name: str, name: str) -> None: ... def __init__(self, model_name: str, name: str, field: Optional[Field] = ...) -> None: ...
def name_lower(self) -> str: ... def name_lower(self) -> str: ...
def is_same_model_operation(self, operation: FieldOperation) -> bool: ... def is_same_model_operation(self, operation: FieldOperation) -> bool: ...
def is_same_field_operation(self, operation: AddField) -> bool: ... def is_same_field_operation(self, operation: AddField) -> bool: ...
class AddField(FieldOperation): class AddField(FieldOperation):
field: Any = ... field: Field = ...
preserve_default: Any = ... preserve_default: bool = ...
def __init__(self, model_name: str, name: str, field: Field, preserve_default: bool = ...) -> None: ... def __init__(self, model_name: str, name: str, field: Field, preserve_default: bool = ...) -> None: ...
class RemoveField(FieldOperation): ... class RemoveField(FieldOperation): ...

View File

@@ -21,7 +21,7 @@ class OperationWriter:
class MigrationWriter: class MigrationWriter:
migration: Migration = ... migration: Migration = ...
needs_manual_porting: bool = ... needs_manual_porting: bool = ...
def __init__(self, migration: Union[type, Migration]) -> None: ... def __init__(self, migration: Union[type, Migration], include_header: bool = ...) -> None: ...
def as_string(self) -> str: ... def as_string(self) -> str: ...
@property @property
def basedir(self) -> str: ... def basedir(self) -> str: ...

View File

@@ -1,21 +1,14 @@
from typing import Any, Optional from typing import Any, Optional
from django.db.models.expressions import Func from django.db.models.expressions import Func
from django.db.models.query_utils import Q
class Aggregate(Func): class Aggregate(Func):
name: Any = ...
filter_template: str = ... filter_template: str = ...
window_compatible: bool = ...
filter: Any = ... filter: Any = ...
def __init__(self, *args: Any, filter: Optional[Any] = ..., **kwargs: Any) -> None: ... def __init__(self, *expressions: Any, distinct: bool = ..., filter: Optional[Any] = ..., **extra: Any) -> None: ...
class Avg(Aggregate): ... class Avg(Aggregate): ...
class Count(Aggregate): ...
class Count(Aggregate):
template: str = ...
def __init__(self, expression: str, distinct: bool = ..., filter: Optional[Q] = ..., **extra: Any) -> None: ...
class Max(Aggregate): ... class Max(Aggregate): ...
class Min(Aggregate): ... class Min(Aggregate): ...
class StdDev(Aggregate): ... class StdDev(Aggregate): ...

View File

@@ -10,4 +10,6 @@ def PROTECT(collector, field, sub_objs, using): ...
def SET(value: Any) -> Callable: ... def SET(value: Any) -> Callable: ...
class ProtectedError(IntegrityError): ... class ProtectedError(IntegrityError): ...
class Collector: ...
class Collector:
def __init__(self, using: str) -> None: ...

View File

@@ -25,13 +25,15 @@ class Length(Transform): ...
class Lower(Transform): ... class Lower(Transform): ...
class LPad(BytesToCharFieldConversionMixin, Func): class LPad(BytesToCharFieldConversionMixin, Func):
def __init__(self, expression: str, length: Union[Length, int], fill_text: Value = ..., **extra: Any) -> None: ... def __init__(
self, expression: str, length: Optional[Union[Length, int]], fill_text: Value = ..., **extra: Any
) -> None: ...
class LTrim(Transform): ... class LTrim(Transform): ...
class Ord(Transform): ... class Ord(Transform): ...
class Repeat(BytesToCharFieldConversionMixin, Func): class Repeat(BytesToCharFieldConversionMixin, Func):
def __init__(self, expression: Union[Value, str], number: Union[Length, int], **extra: Any) -> None: ... def __init__(self, expression: Union[Value, str], number: Optional[Union[Length, int]], **extra: Any) -> None: ...
class Replace(Func): class Replace(Func):
def __init__(self, expression: Combinable, text: Value, replacement: Value = ..., **extra: Any) -> None: ... def __init__(self, expression: Combinable, text: Value, replacement: Value = ..., **extra: Any) -> None: ...

View File

@@ -1,23 +1,34 @@
from typing import Any, Dict, List, Optional, Tuple, Type, Union from typing import Any, List, Optional, Sequence, Tuple, Type
from django.db.backends.base.schema import BaseDatabaseSchemaEditor from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from django.db.backends.ddl_references import Statement from django.db.backends.ddl_references import Statement
from django.db.models.base import Model from django.db.models.base import Model
from django.db.models.query_utils import Q
class Index: class Index:
model: Type[Model] model: Type[Model]
suffix: str = ... suffix: str = ...
max_name_length: int = ... max_name_length: int = ...
fields: List[str] = ... fields: Sequence[str] = ...
fields_orders: List[Tuple[str, str]] = ... fields_orders: Sequence[Tuple[str, str]] = ...
name: str = ... name: str = ...
db_tablespace: Optional[str] = ... db_tablespace: Optional[str] = ...
def __init__(self, *, fields: Any = ..., name: Optional[Any] = ..., db_tablespace: Optional[Any] = ...) -> None: ... opclasses: Sequence[str] = ...
condition: Optional[Q] = ...
def __init__(
self,
*,
fields: Sequence[str] = ...,
name: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
opclasses: Sequence[str] = ...,
condition: Optional[Q] = ...
) -> None: ...
def check_name(self) -> List[str]: ... def check_name(self) -> List[str]: ...
def create_sql( def create_sql(
self, model: Type[Model], schema_editor: BaseDatabaseSchemaEditor, using: str = ... self, model: Type[Model], schema_editor: BaseDatabaseSchemaEditor, using: str = ...
) -> Statement: ... ) -> Statement: ...
def remove_sql(self, model: Type[Model], schema_editor: BaseDatabaseSchemaEditor) -> str: ... def remove_sql(self, model: Type[Model], schema_editor: BaseDatabaseSchemaEditor) -> str: ...
def deconstruct(self) -> Tuple[str, Tuple, Dict[str, Union[List[str], str]]]: ... def deconstruct(self) -> Any: ...
def clone(self) -> Index: ... def clone(self) -> Index: ...
def set_name_with_model(self, model: Type[Model]) -> None: ... def set_name_with_model(self, model: Type[Model]) -> None: ...

View File

@@ -79,7 +79,9 @@ class QuerySet(Generic[_T, _Row], Collection[_Row], Sized):
def aggregate(self, *args: Any, **kwargs: Any) -> Dict[str, Any]: ... def aggregate(self, *args: Any, **kwargs: Any) -> Dict[str, Any]: ...
def get(self, *args: Any, **kwargs: Any) -> _Row: ... def get(self, *args: Any, **kwargs: Any) -> _Row: ...
def create(self, **kwargs: Any) -> _T: ... def create(self, **kwargs: Any) -> _T: ...
def bulk_create(self, objs: Iterable[Model], batch_size: Optional[int] = ...) -> List[_T]: ... def bulk_create(
self, objs: Iterable[Model], batch_size: Optional[int] = ..., ignore_conflicts: bool = ...
) -> List[_T]: ...
def get_or_create(self, defaults: Optional[MutableMapping[str, Any]] = ..., **kwargs: Any) -> Tuple[_T, bool]: ... def get_or_create(self, defaults: Optional[MutableMapping[str, Any]] = ..., **kwargs: Any) -> Tuple[_T, bool]: ...
def update_or_create( def update_or_create(
self, defaults: Optional[MutableMapping[str, Any]] = ..., **kwargs: Any self, defaults: Optional[MutableMapping[str, Any]] = ..., **kwargs: Any

View File

@@ -48,7 +48,7 @@ def last(value: List[str]) -> str: ...
def length(value: Any) -> int: ... def length(value: Any) -> int: ...
def length_is(value: Optional[Any], arg: Union[SafeText, int]) -> Union[bool, str]: ... def length_is(value: Optional[Any], arg: Union[SafeText, int]) -> Union[bool, str]: ...
def random(value: List[str]) -> str: ... def random(value: List[str]) -> str: ...
def slice_filter(value: Any, arg: str) -> Any: ... def slice_filter(value: Any, arg: Union[str, int]) -> Any: ...
def unordered_list(value: Any, autoescape: bool = ...) -> Any: ... def unordered_list(value: Any, autoescape: bool = ...) -> Any: ...
def add(value: Any, arg: Any) -> Any: ... def add(value: Any, arg: Any) -> Any: ...
def get_digit(value: Any, arg: int) -> Any: ... def get_digit(value: Any, arg: int) -> Any: ...

View File

@@ -1,11 +1,8 @@
from typing import Any, Callable, List, Optional, Tuple, Union from typing import Any, List, Optional, Tuple
from .resolvers import URLPattern, URLResolver from .resolvers import URLResolver
def include( def include(arg: Any, namespace: Optional[str] = ...) -> Tuple[List[URLResolver], Optional[str], Optional[str]]: ...
arg: Union[List[Tuple[str, Callable]], List[URLPattern], List[URLResolver], Tuple[List[URLResolver], str], str],
namespace: Optional[str] = ...,
) -> Tuple[List[URLResolver], Optional[str], Optional[str]]: ...
path: Any path: Any
re_path: Any re_path: Any

View File

@@ -1,6 +1,7 @@
import itertools import itertools
import os import os
import re import re
import shutil
import sys import sys
from contextlib import contextmanager from contextlib import contextmanager
from pathlib import Path from pathlib import Path
@@ -13,10 +14,10 @@ from mypy.main import process_options
PROJECT_DIRECTORY = Path(__file__).parent.parent PROJECT_DIRECTORY = Path(__file__).parent.parent
# Django branch to typecheck against # Django branch to typecheck against
DJANGO_BRANCH = 'stable/2.1.x' DJANGO_BRANCH = 'stable/2.2.x'
# Specific commit in the Django repository to check against # Specific commit in the Django repository to check against
DJANGO_COMMIT_SHA = '8fe63dc4cd637c1422a9bf3e3421d64388e14afd' DJANGO_COMMIT_SHA = '395cf7c37514b642c4bcf30e01fc1a2c4f82b2fe'
# Some errors occur for the test suite itself, and cannot be addressed via django-stubs. They should be ignored # Some errors occur for the test suite itself, and cannot be addressed via django-stubs. They should be ignored
# using this constant. # using this constant.
@@ -60,40 +61,19 @@ IGNORED_ERRORS = {
+ 'expected "Union[str, bytes, bytearray]"', + 'expected "Union[str, bytes, bytearray]"',
'Incompatible types in assignment (expression has type "None", variable has type Module)', 'Incompatible types in assignment (expression has type "None", variable has type Module)',
'note:', 'note:',
# Suppress false-positive error due to mypy being overly strict with base class compatibility checks even though
# objects/_default_manager are redefined in the subclass to be compatible with the base class definition.
# Can be removed when mypy issue is fixed: https://github.com/python/mypy/issues/2619
re.compile(r'Definition of "(objects|_default_manager)" in base class "[A-Za-z0-9]+" is incompatible with '
r'definition in base class "[A-Za-z0-9]+"'),
],
'admin_changelist': [
'Incompatible types in assignment (expression has type "FilteredChildAdmin", variable has type "ChildAdmin")'
], ],
'admin_scripts': [ 'admin_scripts': [
'Incompatible types in assignment (expression has type "Callable[' 'Incompatible types in assignment (expression has type "Callable['
], ],
'admin_widgets': [
'Incompatible types in assignment (expression has type "RelatedFieldWidgetWrapper", '
+ 'variable has type "AdminRadioSelect")',
'Incompatible types in assignment (expression has type "Union[Widget, Any]", '
+ 'variable has type "AutocompleteSelect")'
],
'admin_utils': [ 'admin_utils': [
re.compile(r'Argument [0-9] to "lookup_field" has incompatible type'), re.compile(r'Argument [0-9] to "lookup_field" has incompatible type'),
'MockModelAdmin', 'MockModelAdmin',
'Incompatible types in assignment (expression has type "str", variable has type "Callable[..., Any]")', 'Incompatible types in assignment (expression has type "str", variable has type "Callable[..., Any]")',
'Dict entry 0 has incompatible type "str": "Tuple[str, str, List[str]]"; expected "str": '
+ '"Tuple[str, str, Tuple[str, str]]"',
'Incompatible types in assignment (expression has type "bytes", variable has type "str")'
], ],
'admin_views': [ 'admin_views': [
'Argument 1 to "FileWrapper" has incompatible type "StringIO"; expected "IO[bytes]"', 'Argument 1 to "FileWrapper" has incompatible type "StringIO"; expected "IO[bytes]"',
'Incompatible types in assignment', 'Incompatible types in assignment',
'"object" not callable', '"object" not callable',
'Incompatible type for "pk" of "Collector" (got "int", expected "str")',
re.compile('Unexpected attribute "[a-z]+" for model "Model"'),
'Unexpected attribute "two_id" for model "CyclicOne"',
'Argument "is_dst" to "localize" of "BaseTzInfo" has incompatible type "None"; expected "bool"'
], ],
'aggregation': [ 'aggregation': [
'"as_sql" undefined in superclass', '"as_sql" undefined in superclass',
@@ -101,13 +81,12 @@ IGNORED_ERRORS = {
'Incompatible type for "publisher" of "Book" (got "Optional[Publisher]", ' 'Incompatible type for "publisher" of "Book" (got "Optional[Publisher]", '
+ 'expected "Union[Publisher, Combinable]")' + 'expected "Union[Publisher, Combinable]")'
], ],
'apps': [
'Incompatible types in assignment (expression has type "str", target has type "type")',
'"Callable[[bool, bool], List[Type[Model]]]" has no attribute "cache_clear"'
],
'annotations': [ 'annotations': [
'Incompatible type for "store" of "Employee" (got "Optional[Store]", expected "Union[Store, Combinable]")' 'Incompatible type for "store" of "Employee" (got "Optional[Store]", expected "Union[Store, Combinable]")'
], ],
'apps': [
'Incompatible types in assignment (expression has type "str", target has type "type")',
],
'auth_tests': [ 'auth_tests': [
'"PasswordValidator" has no attribute "min_length"', '"PasswordValidator" has no attribute "min_length"',
'"validate_password" does not return a value', '"validate_password" does not return a value',
@@ -117,25 +96,11 @@ IGNORED_ERRORS = {
], ],
'basic': [ 'basic': [
'Unexpected keyword argument "unknown_kwarg" for "refresh_from_db" of "Model"', 'Unexpected keyword argument "unknown_kwarg" for "refresh_from_db" of "Model"',
'"refresh_from_db" of "Model" defined here',
'Unexpected attribute "foo" for model "Article"' 'Unexpected attribute "foo" for model "Article"'
], ],
'builtin_server': [
'has no attribute "getvalue"'
],
'custom_lookups': [ 'custom_lookups': [
'in base class "SQLFuncMixin"' 'in base class "SQLFuncMixin"'
], ],
'custom_managers': [
'_filter_CustomQuerySet',
'_filter_CustomManager',
re.compile(r'Cannot determine type of \'(abstract_persons|cars|plain_manager)\''),
# TODO: remove after 'objects' and '_default_manager' are handled in the plugin
'Incompatible types in assignment (expression has type "CharField", '
+ 'base class "Model" defined the type as "Manager[Model]")',
# TODO: remove after from_queryset() handled in the plugin
'Invalid base class'
],
'csrf_tests': [ 'csrf_tests': [
'Incompatible types in assignment (expression has type "property", ' + 'Incompatible types in assignment (expression has type "property", ' +
'base class "HttpRequest" defined the type as "QueryDict")' 'base class "HttpRequest" defined the type as "QueryDict")'
@@ -152,14 +117,10 @@ IGNORED_ERRORS = {
'deprecation': [ 'deprecation': [
re.compile('"(old|new)" undefined in superclass') re.compile('"(old|new)" undefined in superclass')
], ],
'db_typecasts': [ 'db_functions': [
'"object" has no attribute "__iter__"; maybe "__str__" or "__dir__"? (not iterable)' 'for **',
], 'expected "float"',
'from_db_value': [ 'Incompatible types in assignment (expression has type "Optional[FloatModel]", variable has type "FloatModel")'
'has no attribute "vendor"'
],
'field_deconstruction': [
'Incompatible types in assignment (expression has type "ForeignKey[Any]", variable has type "CharField")'
], ],
'file_uploads': [ 'file_uploads': [
'"handle_uncaught_exception" undefined in superclass' '"handle_uncaught_exception" undefined in superclass'
@@ -201,33 +162,24 @@ IGNORED_ERRORS = {
'Argument 1 to "update_or_create" of "QuerySet" has incompatible type "**Dict[str, object]"; ' 'Argument 1 to "update_or_create" of "QuerySet" has incompatible type "**Dict[str, object]"; '
+ 'expected "Optional[MutableMapping[str, Any]]"' + 'expected "Optional[MutableMapping[str, Any]]"'
], ],
'httpwrappers': [
'Argument 2 to "appendlist" of "QueryDict" has incompatible type "List[str]"; expected "str"'
],
'humanize_tests': [ 'humanize_tests': [
'Argument 1 to "append" of "list" has incompatible type "None"; expected "str"' 'Argument 1 to "append" of "list" has incompatible type "None"; expected "str"'
], ],
'invalid_models_tests': [
'Argument "max_length" to "CharField" has incompatible type "str"; expected "Optional[int]"',
'Argument "choices" to "CharField" has incompatible type "str"'
],
'logging_tests': [ 'logging_tests': [
re.compile('"(setUpClass|tearDownClass)" undefined in superclass') re.compile('"(setUpClass|tearDownClass)" undefined in superclass')
], ],
'lookup': [ 'lookup': [
'Unexpected keyword argument "headline__startswith" for "in_bulk" of "QuerySet"', 'Unexpected keyword argument "headline__startswith" for "in_bulk" of "QuerySet"',
], ],
'm2o_recursive': [
'Incompatible type for "id" of "Category" (got "None", expected "int")'
],
'many_to_one': [ 'many_to_one': [
'Incompatible type for "parent" of "Child" (got "None", expected "Union[Parent, Combinable]")', 'Incompatible type for "parent" of "Child" (got "None", expected "Union[Parent, Combinable]")',
'Incompatible type for "parent" of "Child" (got "Child", expected "Union[Parent, Combinable]")' 'Incompatible type for "parent" of "Child" (got "Child", expected "Union[Parent, Combinable]")'
], ],
'model_meta': [ 'middleware_exceptions': [
'"object" has no attribute "items"', 'Argument 1 to "append" of "list" has incompatible type "Tuple[Any, Any]"; expected "str"'
'"Field" has no attribute "many_to_many"',
],
'model_forms': [
'Argument "instance" to "InvalidModelForm" has incompatible type "Type[Category]"; expected "Optional[Model]"',
'Invalid type "NewForm"'
], ],
'model_fields': [ 'model_fields': [
'Incompatible types in assignment (expression has type "Type[Person]", variable has type', 'Incompatible types in assignment (expression has type "Type[Person]", variable has type',
@@ -242,22 +194,19 @@ IGNORED_ERRORS = {
'Incompatible types in assignment (expression has type "FloatModel", variable has type ' 'Incompatible types in assignment (expression has type "FloatModel", variable has type '
'"Union[float, int, str, Combinable]")', '"Union[float, int, str, Combinable]")',
], ],
'model_formsets': [ 'model_indexes': [
'Incompatible types in string interpolation (expression has type "object", ' 'Argument "condition" to "Index" has incompatible type "str"; expected "Optional[Q]"'
+ 'placeholder has type "Union[int, float]")'
],
'model_formsets_regress': [
'Incompatible types in assignment (expression has type "Model", variable has type "User")'
], ],
'model_regress': [ 'model_regress': [
'Too many arguments for "Worker"',
re.compile(r'Incompatible type for "[a-z]+" of "Worker" \(got "int", expected') re.compile(r'Incompatible type for "[a-z]+" of "Worker" \(got "int", expected')
], ],
'modeladmin': [ 'modeladmin': [
'BandAdmin', 'BandAdmin',
'base class "ModelAdmin" defined the type a', 'base class "ModelAdmin" defined the type a',
'base class "InlineModelAdmin" defined the type a', 'base class "InlineModelAdmin" defined the type a',
'List item 0 has incompatible type "Type[ValidationTestInline]"; expected "Type[InlineModelAdmin]"' 'List item 0 has incompatible type',
'Incompatible types in assignment (expression has type "None", base class "AdminBase" '
+ 'defined the type as "List[str]")'
], ],
'migrate_signals': [ 'migrate_signals': [
'Value of type "None" is not indexable', 'Value of type "None" is not indexable',
@@ -265,40 +214,25 @@ IGNORED_ERRORS = {
], ],
'migrations': [ 'migrations': [
'FakeMigration', 'FakeMigration',
'Incompatible types in assignment (expression has type "TextField", base class "Model" '
+ 'defined the type as "Manager[Model]")',
'Incompatible types in assignment (expression has type "DeleteModel", variable has type "RemoveField")',
'Argument "bases" to "CreateModel" has incompatible type "Tuple[Type[Mixin], Type[Mixin]]"; '
+ 'expected "Optional[Sequence[Union[Type[Model], str]]]"',
'Argument 1 to "RunPython" has incompatible type "str"; expected "Callable[..., Any]"',
'FakeLoader', 'FakeLoader',
'Dict entry 0 has incompatible type "Any": "Set[Tuple[Any, ...]]"; expected "Any": "str"',
'Argument 1 to "RunPython" has incompatible type "str"; expected "Callable[..., Any]"',
'Argument 1 to "append" of "list" has incompatible type "AddIndex"; expected "CreateModel"', 'Argument 1 to "append" of "list" has incompatible type "AddIndex"; expected "CreateModel"',
'Unsupported operand types for - ("Set[Any]" and "None")',
],
'middleware_exceptions': [
'Argument 1 to "append" of "list" has incompatible type "Tuple[Any, Any]"; expected "str"'
], ],
'multiple_database': [ 'multiple_database': [
'Unexpected attribute "extra_arg" for model "Book"',
'Too many arguments for "create" of "QuerySet"' 'Too many arguments for "create" of "QuerySet"'
], ],
'queryset_pickle': [
'"None" has no attribute "somefield"'
],
'postgres_tests': [ 'postgres_tests': [
'Cannot assign multiple types to name',
'Incompatible types in assignment (expression has type "Type[Field[Any, Any]]',
'DummyArrayField', 'DummyArrayField',
'DummyJSONField', 'DummyJSONField',
'Cannot assign multiple types to name',
'Incompatible types in assignment (expression has type "Type[Field[Any, Any]]',
'Argument "encoder" to "JSONField" has incompatible type "DjangoJSONEncoder"; ' 'Argument "encoder" to "JSONField" has incompatible type "DjangoJSONEncoder"; '
+ 'expected "Optional[Type[JSONEncoder]]"', + 'expected "Optional[Type[JSONEncoder]]"',
'for model "CITestModel"',
'Incompatible type for "field" of "IntegerArrayModel" (got "None", ' 'Incompatible type for "field" of "IntegerArrayModel" (got "None", '
+ 'expected "Union[Sequence[int], Combinable]")', + 'expected "Union[Sequence[int], Combinable]")',
re.compile(r'Incompatible types in assignment \(expression has type "Type\[.+?\]", base class "UnaccentTest" ' re.compile(r'Incompatible types in assignment \(expression has type "Type\[.+?\]", '
r'defined the type as "Type\[CharFieldModel\]"\)'), r'base class "(UnaccentTest|TrigramTest)" defined the type as "Type\[CharFieldModel\]"\)'),
'Incompatible types in assignment (expression has type "Type[TextFieldModel]", base class "TrigramTest" '
'defined the type as "Type[CharFieldModel]")',
], ],
'properties': [ 'properties': [
re.compile('Unexpected attribute "(full_name|full_name_2)" for model "Person"') re.compile('Unexpected attribute "(full_name|full_name_2)" for model "Person"')
@@ -314,33 +248,18 @@ IGNORED_ERRORS = {
'Incompatible type for "objectb" of "ObjectC" (got "ObjectA", expected' 'Incompatible type for "objectb" of "ObjectC" (got "ObjectA", expected'
' "Union[ObjectB, Combinable, None, None]")', ' "Union[ObjectB, Combinable, None, None]")',
], ],
'prefetch_related': [
'Incompatible types in assignment (expression has type "List[Room]", variable has type "QuerySet[Room, Room]")',
],
'proxy_model_inheritance': [
'Incompatible import of "ProxyModel"'
],
'requests': [ 'requests': [
'Incompatible types in assignment (expression has type "Dict[str, str]", variable has type "QueryDict")' 'Incompatible types in assignment (expression has type "Dict[str, str]", variable has type "QueryDict")'
], ],
'responses': [ 'responses': [
'Argument 1 to "TextIOWrapper" has incompatible type "HttpResponse"; expected "IO[bytes]"' 'Argument 1 to "TextIOWrapper" has incompatible type "HttpResponse"; expected "IO[bytes]"'
], ],
'prefetch_related': [
'Incompatible types in assignment (expression has type "List[Room]", variable has type "QuerySet[Room, Room]")',
'"None" has no attribute "__iter__"',
'has no attribute "read_by"'
],
'proxy_model_inheritance': [
'Incompatible import of "ProxyModel"'
],
'signals': [
'Argument 1 to "append" of "list" has incompatible type "Tuple[Any, Any, Optional[Any], Any]"; '
+ 'expected "Tuple[Any, Any, Any]"'
],
'syndication_tests': [
'List or tuple expected as variable arguments'
],
'staticfiles_tests': [
'Value of type "stat_result" is not indexable',
'"setUp" undefined in superclass',
'Argument 1 to "write" of "IO" has incompatible type "bytes"; expected "str"',
'Value of type "object" is not indexable'
],
'schema': [ 'schema': [
'Incompatible type for "info" of "Note" (got "None", expected "Union[str, Combinable]")', 'Incompatible type for "info" of "Note" (got "None", expected "Union[str, Combinable]")',
'Incompatible type for "detail_info" of "NoteRename" (got "None", expected "Union[str, Combinable]")', 'Incompatible type for "detail_info" of "NoteRename" (got "None", expected "Union[str, Combinable]")',
@@ -349,12 +268,34 @@ IGNORED_ERRORS = {
'settings_tests': [ 'settings_tests': [
'Argument 1 to "Settings" has incompatible type "Optional[str]"; expected "str"' 'Argument 1 to "Settings" has incompatible type "Optional[str]"; expected "str"'
], ],
'transactions': [ 'signals': [
'Incompatible types in assignment (expression has type "Thread", variable has type "Callable[[], Any]")' 'Argument 1 to "append" of "list" has incompatible type "Tuple[Any, Any, Optional[Any], Any]"; '
+ 'expected "Tuple[Any, Any, Any]"'
],
'syndication_tests': [
'List or tuple expected as variable arguments'
],
'sessions_tests': [
'base class "SessionTestsMixin" defined the type as "None")',
'Incompatible types in assignment (expression has type "None", variable has type "int")',
],
'select_related_onetoone': [
'Incompatible types in assignment (expression has type "Parent2", variable has type "Parent1")',
],
'servers': [
re.compile('Argument [0-9] to "WSGIRequestHandler"')
],
'template_tests': [
re.compile(r'Argument 1 to "[a-zA-Z_]+" has incompatible type "int"; expected "str"'),
'TestObject',
'variable has type "Callable[[Any], Any]',
'Value of type variable "AnyStr" of "urljoin" cannot be "Optional[str]"'
],
'template_backends': [
'Incompatible import of "Jinja2" (imported name has type "Type[Jinja2]", local name has type "object")',
'TemplateStringsTests',
], ],
'test_client': [ 'test_client': [
'Incompatible types in assignment (expression has type "StreamingHttpResponse", '
+ 'variable has type "HttpResponse")',
'Incompatible types in assignment (expression has type "HttpResponse", ' 'Incompatible types in assignment (expression has type "HttpResponse", '
+ 'variable has type "StreamingHttpResponse")' + 'variable has type "StreamingHttpResponse")'
], ],
@@ -362,70 +303,23 @@ IGNORED_ERRORS = {
'Incompatible types in assignment (expression has type "Dict[<nothing>, <nothing>]", ' 'Incompatible types in assignment (expression has type "Dict[<nothing>, <nothing>]", '
+ 'variable has type "SessionBase")', + 'variable has type "SessionBase")',
'Unsupported left operand type for + ("None")', 'Unsupported left operand type for + ("None")',
'Both left and right operands are unions'
], ],
'timezones': [ 'timezones': [
'Too few arguments for "render" of "Template"' 'Too few arguments for "render" of "Template"'
], ],
'test_runner': [ 'test_runner': [
'Value of type "TestSuite" is not indexable',
'"TestSuite" has no attribute "_tests"',
'Argument "result" to "run" of "TestCase" has incompatible type "RemoteTestResult"; ' 'Argument "result" to "run" of "TestCase" has incompatible type "RemoteTestResult"; '
+ 'expected "Optional[TestResult]"', + 'expected "Optional[TestResult]"',
'Item "TestSuite" of "Union[TestCase, TestSuite]" has no attribute "id"',
'MockTestRunner',
'Incompatible types in assignment (expression has type "Tuple[Union[TestCase, TestSuite], ...]", '
+ 'variable has type "TestSuite")'
], ],
'template_tests': [ 'transactions': [
'Xtemplate', 'Incompatible types in assignment (expression has type "Thread", variable has type "Callable[[], Any]")'
re.compile(r'Argument 1 to "[a-zA-Z_]+" has incompatible type "int"; expected "str"'),
'TestObject',
'variable has type "Callable[[Any], Any]',
'template_debug',
'"yield from" can\'t be applied to',
re.compile(r'List item [0-9] has incompatible type "URLResolver"; expected "URLPattern"'),
'"WSGIRequest" has no attribute "current_app"',
'Value of type variable "AnyStr" of "urljoin" cannot be "Optional[str]"'
],
'template_backends': [
'Incompatible import of "Jinja2" (imported name has type "Type[Jinja2]", local name has type "object")',
'TemplateStringsTests',
], ],
'urlpatterns': [ 'urlpatterns': [
'"object" has no attribute "__iter__"; maybe "__str__" or "__dir__"? (not iterable)',
'"object" not callable' '"object" not callable'
], ],
'user_commands': [ 'user_commands': [
'Incompatible types in assignment (expression has type "Callable[[Any, KwArg(Any)], Any]", variable has type' 'Incompatible types in assignment (expression has type "Callable[[Any, KwArg(Any)], Any]", variable has type'
], ],
'utils_tests': [
re.compile(r'Argument ([1-9]) to "__get__" of "classproperty" has incompatible type')
],
'urlpatterns_reverse': [
'to "reverse" has incompatible type "object"',
'Module has no attribute "_translations"',
"'django.urls.resolvers.ResolverMatch' object is not iterable"
],
'sessions_tests': [
'base class "SessionTestsMixin" defined the type as "None")',
'Incompatible types in assignment (expression has type "None", variable has type "int")',
],
'select_related_onetoone': [
'"None" has no attribute',
'Incompatible types in assignment (expression has type "Parent2", variable has type "Parent1")',
],
'servers': [
re.compile('Argument [0-9] to "WSGIRequestHandler"')
],
'sitemaps_tests': [
'Incompatible types in assignment (expression has type "str", '
+ 'base class "Sitemap" defined the type as "Callable[[Sitemap, Model], str]")'
],
'view_tests': [
'"Handler" has no attribute "include_html"',
'"EmailMessage" has no attribute "alternatives"'
]
} }
# Test folders to typecheck # Test folders to typecheck
TESTS_DIRS = [ TESTS_DIRS = [
@@ -520,10 +414,8 @@ TESTS_DIRS = [
'inline_formsets', 'inline_formsets',
'inspectdb', 'inspectdb',
'introspection', 'introspection',
# not practical # not practical
# 'invalid_models_tests', # 'invalid_models_tests',
'known_related_objects', 'known_related_objects',
'logging_tests', 'logging_tests',
'lookup', 'lookup',
@@ -701,6 +593,7 @@ def get_absolute_path_for_test(test_dirname: str):
if __name__ == '__main__': if __name__ == '__main__':
mypy_config_file = (PROJECT_DIRECTORY / 'scripts' / 'mypy.ini').absolute() mypy_config_file = (PROJECT_DIRECTORY / 'scripts' / 'mypy.ini').absolute()
repo_directory = PROJECT_DIRECTORY / 'django-sources' repo_directory = PROJECT_DIRECTORY / 'django-sources'
mypy_cache_dir = Path(__file__).parent / '.mypy_cache'
tests_root = repo_directory / 'tests' tests_root = repo_directory / 'tests'
global_rc = 0 global_rc = 0
@@ -718,12 +611,17 @@ if __name__ == '__main__':
else: else:
tests_to_run = TESTS_DIRS tests_to_run = TESTS_DIRS
for dirname in tests_to_run: try:
abs_path = get_absolute_path_for_test(dirname) for dirname in tests_to_run:
print(f'Checking {abs_path}') abs_path = get_absolute_path_for_test(dirname)
print(f'Checking {abs_path}')
rc = check_with_mypy(abs_path, mypy_config_file) rc = check_with_mypy(abs_path, mypy_config_file)
if rc != 0: if rc != 0:
global_rc = 1 global_rc = 1
sys.exit(global_rc) sys.exit(global_rc)
except BaseException as exc:
shutil.rmtree(mypy_cache_dir, ignore_errors=True)
raise exc