From a97d76020ca747cc2e8c80e6041806b710d0172a Mon Sep 17 00:00:00 2001 From: Maxim Kurnikov Date: Wed, 24 Jul 2019 23:44:57 +0300 Subject: [PATCH] enable tests typechecking using django submodule --- .gitignore | 1 - .gitmodules | 4 + .travis.yml | 3 +- dev-requirements.txt | 2 +- django-sources | 1 + scripts/django_tests_settings.py | 229 ++++++ scripts/enabled_test_modules.py | 337 +++++++++ scripts/mypy.ini | 5 +- scripts/typecheck-tests-requirements.txt | 1 - scripts/typecheck_tests.py | 865 +---------------------- 10 files changed, 609 insertions(+), 839 deletions(-) create mode 100644 .gitmodules create mode 160000 django-sources create mode 100644 scripts/django_tests_settings.py create mode 100644 scripts/enabled_test_modules.py delete mode 100644 scripts/typecheck-tests-requirements.txt diff --git a/.gitignore b/.gitignore index 9668ffe..5f938fd 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ out/ /django .idea/ .mypy_cache/ -django-sources build/ dist/ pip-wheel-metadata/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..4a85142 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "django-sources"] + path = django-sources + url = https://github.com/django/django.git + branch = stable/2.2.x diff --git a/.travis.yml b/.travis.yml index 820a3e0..08aafcc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,5 +30,4 @@ before_install: | # Upgrade pip, setuptools, and wheel pip install -U pip setuptools wheel install: | - pip install -r ./dev-requirements.txt - pip install -r ./scripts/typecheck-tests-requirements.txt \ No newline at end of file + pip install -r ./dev-requirements.txt \ No newline at end of file diff --git a/dev-requirements.txt b/dev-requirements.txt index 24d30a5..b62d198 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,5 +1,5 @@ black -pytest-mypy-plugins +pytest-mypy-plugins==1.0.3 flake8 isort==4.3.4 -e . diff --git a/django-sources b/django-sources new file mode 160000 index 0000000..4d6449e --- /dev/null +++ b/django-sources @@ -0,0 +1 @@ +Subproject commit 4d6449e1258c88b6e4e1ccbb5e84b210371598d2 diff --git a/scripts/django_tests_settings.py b/scripts/django_tests_settings.py new file mode 100644 index 0000000..7c698d8 --- /dev/null +++ b/scripts/django_tests_settings.py @@ -0,0 +1,229 @@ +SECRET_KEY = '1' +SITE_ID = 1 + +INSTALLED_APPS = [ + 'django.contrib.contenttypes', + 'django.contrib.auth', + 'django.contrib.sites', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.admin.apps.SimpleAdminConfig', + 'django.contrib.staticfiles', +] + +test_modules = [ + 'absolute_url_overrides', + 'admin_autodiscover', + 'admin_changelist', + 'admin_checks', + 'admin_custom_urls', + 'admin_default_site', + 'admin_docs', + 'admin_filters', + 'admin_inlines', + 'admin_ordering', + 'admin_registration', + 'admin_scripts', + 'admin_utils', + 'admin_views', + 'admin_widgets', + 'aggregation', + 'aggregation_regress', + 'annotations', + 'app_loading', + 'apps', + 'auth_tests', + 'backends', + 'base', + 'bash_completion', + 'basic', + 'builtin_server', + 'bulk_create', + 'cache', + 'check_framework', + 'choices', + 'conditional_processing', + 'constraints', + 'contenttypes_tests', + 'context_processors', + 'csrf_tests', + 'custom_columns', + 'custom_lookups', + 'custom_managers', + 'custom_methods', + 'custom_migration_operations', + 'custom_pk', + 'datatypes', + 'dates', + 'datetimes', + 'db_functions', + 'db_typecasts', + 'db_utils', + 'dbshell', + 'decorators', + 'defer', + 'defer_regress', + 'delete', + 'delete_regress', + 'deprecation', + 'dispatch', + 'distinct_on_fields', + 'empty', + 'expressions', + 'expressions_case', + 'expressions_window', + 'extra_regress', + 'field_deconstruction', + 'field_defaults', + 'field_subclassing', + 'file_storage', + 'file_uploads', + 'files', + 'filtered_relation', + 'fixtures', + 'fixtures_model_package', + 'fixtures_regress', + 'flatpages_tests', + 'force_insert_update', + 'foreign_object', + 'forms_tests', + 'from_db_value', + 'generic_inline_admin', + 'generic_relations', + 'generic_relations_regress', + 'generic_views', + 'get_earliest_or_latest', + 'get_object_or_404', + 'get_or_create', + 'gis_tests', + 'handlers', + 'httpwrappers', + 'humanize_tests', + 'i18n', + 'import_error_package', + 'indexes', + 'inline_formsets', + 'inspectdb', + 'introspection', + 'invalid_models_tests', + 'known_related_objects', + 'logging_tests', + 'lookup', + 'm2m_and_m2o', + 'm2m_intermediary', + 'm2m_multiple', + 'm2m_recursive', + 'm2m_regress', + 'm2m_signals', + 'm2m_through', + 'm2m_through_regress', + 'm2o_recursive', + 'mail', + 'managers_regress', + 'many_to_many', + 'many_to_one', + 'many_to_one_null', + 'max_lengths', + 'messages_tests', + 'middleware', + 'middleware_exceptions', + 'migrate_signals', + 'migration_test_data_persistence', + 'migrations', + 'migrations2', + 'model_fields', + 'model_forms', + 'model_formsets', + 'model_formsets_regress', + 'model_indexes', + 'model_inheritance', + 'model_inheritance_regress', + 'model_meta', + 'model_options', + 'model_package', + 'model_regress', + 'modeladmin', + 'multiple_database', + 'mutually_referential', + 'nested_foreign_keys', + 'no_models', + 'null_fk', + 'null_fk_ordering', + 'null_queries', + 'one_to_one', + 'or_lookups', + 'order_with_respect_to', + 'ordering', + 'pagination', + 'postgres_tests', + 'prefetch_related', + 'project_template', + 'properties', + 'proxy_model_inheritance', + 'proxy_models', + 'queries', + 'queryset_pickle', + 'raw_query', + 'redirects_tests', + 'requests', + 'reserved_names', + 'resolve_url', + 'responses', + 'reverse_lookup', + 'save_delete_hooks', + 'schema', + 'select_for_update', + 'select_related', + 'select_related_onetoone', + 'select_related_regress', + 'serializers', + 'servers', + 'sessions_tests', + 'settings_tests', + 'shell', + 'shortcuts', + 'signals', + 'signed_cookies_tests', + 'signing', + 'sitemaps_tests', + 'sites_framework', + 'sites_tests', + 'staticfiles_tests', + 'str', + 'string_lookup', + 'swappable_models', + 'syndication_tests', + 'template_backends', + 'template_loader', + 'template_tests', + 'test_client', + 'test_client_regress', + 'test_exceptions', + 'test_runner', + 'test_runner_apps', + 'test_utils', + 'timezones', + 'transaction_hooks', + 'transactions', + 'unmanaged_models', + 'update', + 'update_only_fields', + 'urlpatterns', + 'urlpatterns_reverse', + 'user_commands', + 'utils_tests', + 'validation', + 'validators', + 'version', + 'view_tests', + 'wsgi', +] + +invalid_apps = { + 'import_error_package', +} + +for app in invalid_apps: + test_modules.remove(app) + +INSTALLED_APPS += test_modules diff --git a/scripts/enabled_test_modules.py b/scripts/enabled_test_modules.py new file mode 100644 index 0000000..69ad718 --- /dev/null +++ b/scripts/enabled_test_modules.py @@ -0,0 +1,337 @@ +# Some errors occur for the test suite itself, and cannot be addressed via django-stubs. They should be ignored +# using this constant. +import re + +IGNORED_MODULES = {'schema', 'gis_tests', 'admin_widgets', 'admin_filters', 'migrations', + 'sitemaps_tests', 'staticfiles_tests', 'modeladmin', 'model_forms', + 'generic_views', 'forms_tests', 'flatpages_tests', 'admin_utils', + 'admin_ordering', 'admin_changelist', 'admin_views', 'mail', 'redirects_tests', + 'invalid_models_tests', 'i18n', 'migrate_signals', 'model_formsets', + 'template_tests', 'template_backends', 'test_runner', 'admin_scripts', + 'sites_tests', 'inline_formsets', 'foreign_object', 'cache', 'test_client', 'test_client_regress'} + +MOCK_OBJECTS = ['MockRequest', 'MockCompiler', 'modelz', 'call_count', 'call_args_list', + 'call_args', 'MockUser', 'Xtemplate', 'DummyRequest', 'DummyUser', 'MinimalUser'] +EXTERNAL_MODULES = ['psycopg2', 'PIL', 'selenium', 'oracle', 'mysql', 'sqlite3', 'sqlparse', 'tblib', 'numpy', + 'bcrypt', 'argon2', 'xml.dom'] +IGNORED_ERRORS = { + '__new_common__': [ + *MOCK_OBJECTS, + *EXTERNAL_MODULES, + 'SupportsFloat', + 'Need type annotation for', + 'has no attribute "getvalue"', + 'Cannot assign to a method', + 'Cannot infer type of lambda', + 'already defined (possibly by an import)', + 'already defined on line', + 'Cannot assign to a type', + '"HttpResponse" has no attribute', + '"HttpResponseBase" has no attribute', + # '"HttpRequest" has no attribute', + '"object" has no attribute', + 'defined in the current module', + re.compile(r'"Callable\[(\[(Any(, )?)*((, )?VarArg\(Any\))?((, )?KwArg\(Any\))?\]|\.\.\.), Any\]" ' + r'has no attribute'), + 'has no attribute "deconstruct"', + # private members + re.compile(r'has no attribute ("|\')_[a-zA-Z_]+("|\')'), + "'Settings' object has no attribute", + '**Dict', + re.compile(r"Expression of type '.*' is not supported"), + 'has incompatible type "object"', + 'undefined in superclass', + 'Argument after ** must be a mapping, not "object"', + 'note:', + re.compile(r'Item "None" of "[a-zA-Z_ ,\[\]]+" has no attribute'), + '"Optional[List[_Record]]"', + '"Callable[..., None]" has no attribute', + 'does not return a value', + 'has no attribute "alternatives"', + 'gets multiple values for keyword argument', + '"Handler" has no attribute', + 'Module has no attribute', + "No installed app with label 'missing'", + 'namedtuple', + 'Lookups not supported yet', + 'Argument 1 to "loads" has incompatible type', + # TODO: see test in managers/test_managers.yml + "Cannot determine type of", + 'cache_clear', + 'cache_info', + 'Incompatible types in assignment (expression has type "None", variable has type Module)', + "Module 'django.contrib.messages.storage.fallback' has no attribute 'CookieStorage'", + # TODO: not supported yet + 'GenericRelation', + 'RelatedObjectDoesNotExist', + # Rel's attributes are not accessible from `get_field()` + re.compile(r'"Field\[Any, Any\]" has no attribute ' + r'"(through|field_name|field|get_related_field|related_model|related_name' + r'|get_accessor_name|empty_strings_allowed|many_to_many)"'), + # TODO: multitable inheritance + 'ptr', + 'Incompatible types in assignment (expression has type "Callable[', + 'SimpleLazyObject' + ], + 'apps': [ + 'Incompatible types in assignment (expression has type "str", target has type "type")', + ], + 'auth_tests': [ + '"PasswordValidator" has no attribute "min_length"', + 'AbstractBaseUser', + 'Argument "password_validators" to "password_changed" has incompatible type "Tuple[Validator]"; ' + + 'expected "Optional[Sequence[PasswordValidator]]"', + 'Unsupported right operand type for in ("object")', + 'mock_getpass', + 'Unsupported left operand type for + ("Sequence[str]")', + 'AuthenticationFormWithInactiveUsersOkay', + 'Incompatible types in assignment (expression has type "Dict[str, Any]", variable has type "QueryDict")', + ], + 'basic': [ + 'Unexpected keyword argument "unknown_kwarg" for "refresh_from_db" of "Model"', + 'Unexpected attribute "foo" for model "Article"', + 'has no attribute "touched"' + ], + 'backends': [ + '"DatabaseError" has no attribute "pgcode"' + ], + 'check_framework': [ + 'base class "Model" defined the type as "Callable', + ], + 'constraints': [ + 'Argument "condition" to "UniqueConstraint" has incompatible type "str"; expected "Optional[Q]"' + ], + 'contenttypes_tests': [ + # 'Item "Model" of "Union[GenericForeignKey, Model, None]" has no attribute' + 'base class "BaseOrderWithRespectToTests" defined the type as "None"' + ], + 'custom_lookups': [ + 'in base class "SQLFuncMixin"' + ], + 'custom_pk': [ + '"Employee" has no attribute "id"' + ], + 'custom_managers': [ + 'Unsupported dynamic base class', + '"Book" has no attribute "favorite_avg"', + 'Incompatible types in assignment (expression has type "CharField' + ], + 'csrf_tests': [ + 'Incompatible types in assignment (expression has type "property", ' + + 'base class "HttpRequest" defined the type as "QueryDict")' + ], + 'dates': [ + 'Too few arguments for "dates" of "QuerySet"', + ], + 'defer': [ + 'Too many arguments for "refresh_from_db" of "Model"' + ], + 'dispatch': [ + 'Item "str" of "Union[ValueError, str]" has no attribute "args"' + ], + 'deprecation': [ + '"Manager" has no attribute "old"', + '"Manager" has no attribute "new"' + ], + 'db_functions': [ + '"FloatModel" has no attribute', + ], + 'decorators': [ + '"Type[object]" has no attribute "method"' + ], + 'expressions_case': [ + 'Item "Field[Any, Any]" of "Union[Field[Any, Any], ForeignObjectRel]" has no attribute "is_relation"' + ], + 'expressions_window': [ + 'has incompatible type "str"' + ], + 'file_uploads': [ + '"Iterable[Any]" has no attribute', + '"IO[Any]" has no attribute' + ], + 'file_storage': [ + 'Incompatible types in assignment (expression has type "Callable"' + ], + 'files': [ + 'Incompatible types in assignment (expression has type "IOBase", variable has type "File")', + ], + 'fixtures': [ + 'Incompatible types in assignment (expression has type "int", target has type "Iterable[str]")', + 'Incompatible types in assignment (expression has type "SpyManager[Spy]"' + ], + 'from_db_value': [ + '"Cash" has no attribute' + ], + 'get_object_or_404': [ + 'Argument 1 to "get_object_or_404" has incompatible type "str"; ' + + 'expected "Union[Type[], QuerySet[, ]]"', + 'Argument 1 to "get_list_or_404" has incompatible type "List[Type[Article]]"; ' + + 'expected "Union[Type[], QuerySet[, ]]"', + 'CustomClass' + ], + 'generic_relations_regress': [ + '"Link" has no attribute' + ], + 'httpwrappers': [ + 'Argument 2 to "appendlist" of "QueryDict"', + 'Incompatible types in assignment (expression has type "int", target has type "Union[str, List[str]]")', + 'Argument 1 to "fromkeys" of "QueryDict" has incompatible type "int"' + ], + 'humanize_tests': [ + 'Argument 1 to "append" of "list" has incompatible type "None"; expected "str"' + ], + 'lookup': [ + 'Unexpected keyword argument "headline__startswith" for "in_bulk" of "QuerySet"', + 'is called with more than one field' + ], + 'messages_tests': [ + 'List item 0 has incompatible type "Dict[str, Message]"; expected "Message"' + ], + 'middleware': [ + '"HttpRequest" has no attribute' + ], + 'managers_regress': [ + '"Type[AbstractBase3]" has no attribute "objects"' + ], + 'many_to_one': [ + 'Incompatible type for "parent" of "Child" (got "None", expected "Union[Parent, Combinable]")', + 'Incompatible type for "parent" of "Child" (got "Child", expected "Union[Parent, Combinable]")' + ], + 'middleware_exceptions': [ + 'Argument 1 to "append" of "list" has incompatible type "Tuple[Any, Any]"; expected "str"' + ], + 'model_fields': [ + 'Item "Field[Any, Any]" of "Union[Field[Any, Any], ForeignObjectRel]" has no attribute', + 'has no attribute "field"', + 'Incompatible types in assignment (expression has type "Type[Person', + 'base class "IntegerFieldTests"', + 'ImageFieldTestMixin', + 'Incompatible types in assignment (expression has type "FloatModel", variable has type', + ], + 'model_indexes': [ + 'Argument "condition" to "Index" has incompatible type "str"; expected "Optional[Q]"' + ], + 'model_inheritance': [ + 'base class "AbstractBase" defined', + 'base class "AbstractModel" defined', + 'Definition of "name" in base class "ConcreteParent"', + ' Definition of "name" in base class "AbstractParent"', + 'referent_references' + ], + 'model_meta': [ + 'List item 0 has incompatible type "str"; expected "Union[Field[Any, Any], ForeignObjectRel]"' + ], + 'model_regress': [ + 'Incompatible type for "department" of "Worker"', + '"PickledModel" has no attribute', + '"Department" has no attribute "evaluate"', + ], + 'multiple_database': [ + 'Unexpected attribute "extra_arg" for model "Book"' + ], + 'order_with_respect_to': [ + 'BaseOrderWithRespectToTests', + '"Dimension" has no attribute "set_component_order"', + ], + 'one_to_one': [ + 'expression has type "None", variable has type "UndergroundBar"' + ], + 'postgres_tests': [ + 'DummyArrayField', + 'DummyJSONField', + 'Incompatible types in assignment (expression has type "Type[Field[Any, Any]]', + 'Argument "encoder" to "JSONField" has incompatible type "DjangoJSONEncoder";', + re.compile(r'Incompatible types in assignment \(expression has type "Type\[.+?\]", ' + r'base class "(UnaccentTest|TrigramTest)" defined the type as "Type\[CharFieldModel\]"\)'), + '("None" and "SearchQuery")', + # TODO: + 'django.contrib.postgres.forms', + 'django.contrib.postgres.aggregates', + ], + 'properties': [ + re.compile('Unexpected attribute "(full_name|full_name_2)" for model "Person"') + ], + 'prefetch_related': [ + '"Person" has no attribute "houses_lst"', + '"Book" has no attribute "first_authors"', + '"Book" has no attribute "the_authors"', + 'Incompatible types in assignment (expression has type "List[Room]", variable has type "QuerySet[Room, Room]")', + '"Room" has no attribute "main_room_of_attr"', + '"Room" has no attribute "house_attr"' + ], + 'proxy_models': [ + 'Incompatible types in assignment', + 'in base class "User"' + ], + 'queries': [ + 'Incompatible types in assignment (expression has type "None", variable has type "str")', + 'Invalid index type "Optional[str]" for "Dict[str, int]"; expected type "str"', + 'Unsupported operand types for & ("QuerySet[Author, Author]" and "QuerySet[Tag, Tag]")', + 'Unsupported operand types for | ("QuerySet[Author, Author]" and "QuerySet[Tag, Tag]")', + 'ObjectA', + 'ObjectB', + 'ObjectC', + "'flat' and 'named' can't be used together", + ], + 'requests': [ + 'Incompatible types in assignment (expression has type "Dict[str, str]", variable has type "QueryDict")' + ], + 'responses': [ + 'Argument 1 to "TextIOWrapper" has incompatible type "HttpResponse"; expected "IO[bytes]"' + ], + 'settings_tests': [ + 'Argument 1 to "Settings" has incompatible type "Optional[str]"; expected "str"' + ], + 'signals': [ + 'Argument 1 to "append" of "list" has incompatible type "Tuple[Any, Any, Optional[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")', + '"AbstractBaseSession" has no attribute' + ], + 'select_related_onetoone': [ + 'Incompatible types in assignment (expression has type "Parent2", variable has type "Parent1")', + '"Parent1" has no attribute' + ], + 'servers': [ + re.compile('Argument [0-9] to "WSGIRequestHandler"'), + '"HTTPResponse" has no attribute', + '"type" has no attribute', + '"WSGIRequest" has no attribute "makefile"' + ], + 'serializers': [ + '"SerializersTestBase" defined the type as "None"', + '"Model" has no attribute "data"', + '"Iterable[Any]" has no attribute "content"', + ], + 'transactions': [ + 'Incompatible types in assignment (expression has type "Thread", variable has type "Callable[[], Any]")' + ], + 'urlpatterns': [ + '"object" not callable' + ], + 'urlpatterns_reverse': [ + 'List or tuple expected as variable arguments', + 'No overload variant of "zip" matches argument types "Any", "object"', + 'Argument 1 to "get_callable" has incompatible type "int"' + ], + 'utils_tests': [ + 'Too few arguments for "__init__"', + 'Argument 1 to "activate" has incompatible type "None"; expected "Union[tzinfo, str]"', + 'Incompatible types in assignment (expression has type "None", base class "object" defined the type as', + 'Class', + 'has no attribute "cp"', + 'Argument "name" to "cached_property" has incompatible type "int"; expected "Optional[str]"', + 'has no attribute "sort"', + 'Unsupported target for indexed assignment', + 'defined the type as "None"', + 'Argument 1 to "Path" has incompatible type "Optional[str]"' + ], + 'view_tests': [ + "Module 'django.views.debug' has no attribute 'Path'" + ] +} diff --git a/scripts/mypy.ini b/scripts/mypy.ini index ccc7346..f6070bd 100644 --- a/scripts/mypy.ini +++ b/scripts/mypy.ini @@ -1,6 +1,6 @@ [mypy] strict_optional = True -ignore_missing_imports = False +ignore_missing_imports = True check_untyped_defs = True warn_no_return = False show_traceback = True @@ -9,3 +9,6 @@ incremental = True plugins = mypy_django_plugin.main + +[mypy.plugins.django-stubs] +django_settings_module = 'django_tests_settings' \ No newline at end of file diff --git a/scripts/typecheck-tests-requirements.txt b/scripts/typecheck-tests-requirements.txt deleted file mode 100644 index 5396f9c..0000000 --- a/scripts/typecheck-tests-requirements.txt +++ /dev/null @@ -1 +0,0 @@ -gitpython \ No newline at end of file diff --git a/scripts/typecheck_tests.py b/scripts/typecheck_tests.py index 583d1d2..8a6252c 100644 --- a/scripts/typecheck_tests.py +++ b/scripts/typecheck_tests.py @@ -1,809 +1,23 @@ import itertools -import os -import re import shutil +import subprocess import sys -from contextlib import contextmanager from pathlib import Path -from typing import Pattern +from re import Pattern -from git import Repo -from mypy import build -from mypy.main import process_options +from scripts.enabled_test_modules import IGNORED_ERRORS, IGNORED_MODULES PROJECT_DIRECTORY = Path(__file__).parent.parent -# Django branch to typecheck against -DJANGO_BRANCH = 'stable/2.2.x' - -# Specific commit in the Django repository to check against -DJANGO_COMMIT_SHA = '395cf7c37514b642c4bcf30e01fc1a2c4f82b2fe' - -# Some errors occur for the test suite itself, and cannot be addressed via django-stubs. They should be ignored -# using this constant. -MOCK_OBJECTS = ['MockRequest', 'MockCompiler', 'modelz', 'call_count', 'call_args_list', 'call_args', 'MockUser'] -IGNORED_ERRORS = { - '__common__': [ - *MOCK_OBJECTS, - 'LazySettings', - 'NullTranslations', - 'Need type annotation for', - 'Invalid value for a to= parameter', - 'already defined (possibly by an import)', - 'already defined on line', - 'gets multiple values for keyword argument', - 'Cannot assign to a type', - re.compile(r'Cannot assign to class variable "[a-z_]+" via instance'), - # forms <-> models plugin support - # '"Model" has no attribute', - re.compile(r'Cannot determine type of \'(objects|stuff)\''), - # settings - re.compile(r'Module has no attribute "[A-Z_]+"'), - # attributes assigned to test functions - re.compile( - r'"Callable\[(\[(Any(, )?)*((, )?VarArg\(Any\))?((, )?KwArg\(Any\))?\]|\.\.\.), Any\]" has no attribute'), - # assign empty tuple - re.compile(r'Incompatible types in assignment \(expression has type "Tuple\[\]", ' - r'variable has type "Tuple\[[A-Za-z, ]+\]"'), - # assign method to a method - 'Cannot assign to a method', - 'Cannot infer type of lambda', - re.compile(r'Incompatible types in assignment \(expression has type "Callable\[\[(Any(, )?)+\], Any\]", ' - r'variable has type "Callable\['), - # cookies private attribute - 'full_clean" of "Model" does not return a value', - # private members - re.compile(r'has no attribute ("|\')_[a-zA-Z_]+("|\')'), - 'Invalid base class', - 'ValuesIterable', - 'Value of type "Optional[Dict[str, Any]]" is not indexable', - 'Argument 1 to "len" has incompatible type "Optional[List[_Record]]"; expected "Sized"', - 'Argument 1 to "loads" has incompatible type "Union[bytes, str, None]"; ' - + 'expected "Union[str, bytes, bytearray]"', - 'Incompatible types in assignment (expression has type "None", variable has type Module)', - 'note:', - '\'Settings\' object has no attribute', - re.compile(r'"Type\[Model\]" has no attribute "[a-zA-Z_]+"'), - re.compile(r'Item "None" of "[a-zA-Z_ ,\[\]]+" has no attribute'), - 'Xtemplate', - re.compile(r'has no attribute "get_[a-z_]+_display"'), - re.compile(r'has no attribute "get_next_by_[a-z_]+"'), - re.compile(r'has no attribute "get_previous_by_[a-z_]+"'), - re.compile(r'has no attribute "set_[a-z_]+_order"'), - 'psycopg2', - 'PIL', - 'has no attribute "getvalue"', - 'MySQLdb', - 'sqlparse', - 'selenium', - 'oracle', - 'mysql', - 'sqlite3', - 'LogEntry', - '"HttpResponse" has no attribute', - '"HttpResponseBase" has no attribute', - '"object" has no attribute', - '"HttpRequest" has no attribute', - 'xml.dom', - 'numpy', - 'tblib', - 'bcrypt', - 'argon2', - # TODO: values().annotate() - 'TypedDict', - 'namedtuple', - 'has no attribute "deconstruct"', - '**Dict', - 'undefined in superclass', - 'SimpleLazyObject' - ], - 'admin_scripts': [ - 'Incompatible types in assignment (expression has type "Callable[' - ], - 'admin_utils': [ - re.compile(r'Argument [0-9] to "lookup_field" has incompatible type'), - 'MockModelAdmin', - 'Incompatible types in assignment (expression has type "str", variable has type "Callable[..., Any]")', - '"Article" has no attribute "non_field"' - ], - 'admin_views': [ - 'Argument 1 to "FileWrapper" has incompatible type "StringIO"; expected "IO[bytes]"', - 'Incompatible types in assignment', - '"object" not callable', - '"Type[SubscriberAdmin]" has no attribute "overridden"' - ], - 'admin_ordering': [ - '"Band" has no attribute "field"' - ], - 'aggregation': [ - 'Incompatible type for "contact" of "Book" (got "Optional[Author]", expected "Union[Author, Combinable]")', - 'Incompatible type for "publisher" of "Book" (got "Optional[Publisher]", ' - + 'expected "Union[Publisher, Combinable]")', - 'has no attribute' - ], - 'aggregation_regress': [ - 'has no attribute' - ], - 'annotations': [ - 'Incompatible type for "store" of "Employee" (got "Optional[Store]", expected "Union[Store, Combinable]")', - '"Book" has no attribute', - '"Employee" has no attribute', - 'Item "Book" of', - 'Item "Ticket" of' - ], - 'apps': [ - 'Incompatible types in assignment (expression has type "str", target has type "type")', - '"Callable[[bool, bool], List[Type[Model]]]" has no attribute "cache_clear"' - ], - 'auth_tests': [ - '"PasswordValidator" has no attribute "min_length"', - '"validate_password" does not return a value', - '"password_changed" does not return a value', - re.compile(r'"validate" of "([A-Za-z]+)" does not return a value'), - 'Module has no attribute "SessionStore"', - 'AbstractBaseUser', - 'Argument "user" to "password_changed" has incompatible type "object"', - 'Argument "password_validators" to "password_changed" has incompatible type "Tuple[Validator]"; ' - + 'expected "Optional[Sequence[PasswordValidator]]"', - 'Value of type "Optional[List[_Record]]" is not indexable', - '"Model" has no attribute', - 'Incompatible type for "id" of "User"', - re.compile(r'Module has no attribute "(update|revert)_proxy_model_permissions"'), - 'Unsupported right operand type for in ("object")', - 'mock_getpass', - 'Unsupported left operand type for + ("Sequence[str]")', - 'AuthenticationFormWithInactiveUsersOkay', - 'has no attribute "alternatives"', - 'Incompatible types in assignment (expression has type "Dict[str, Any]", variable has type "QueryDict")' - ], - 'basic': [ - 'Unexpected keyword argument "unknown_kwarg" for "refresh_from_db" of "Model"', - 'Unexpected attribute "foo" for model "Article"', - 'has no attribute' - ], - 'backends': [ - '"DatabaseError" has no attribute "pgcode"' - ], - 'check_framework': [ - 'base class "Model" defined the type as "Callable', - 'Cannot determine type of \'check\'' - ], - 'constraints': [ - 'Argument "condition" to "UniqueConstraint" has incompatible type "str"; expected "Optional[Q]"' - ], - 'contenttypes_tests': [ - 'Item "Model" of "Union[GenericForeignKey, Model, None]" has no attribute' - ], - 'custom_lookups': [ - 'in base class "SQLFuncMixin"' - ], - 'custom_pk': [ - '"Employee" has no attribute "id"' - ], - 'custom_managers': [ - '"Type[Book]" has no attribute "objects"' - ], - 'csrf_tests': [ - 'Incompatible types in assignment (expression has type "property", ' + - 'base class "HttpRequest" defined the type as "QueryDict")' - ], - 'dates': [ - 'Too few arguments for "dates" of "QuerySet"', - ], - 'defer': [ - 'Too many arguments for "refresh_from_db" of "Model"' - ], - 'dispatch': [ - 'Argument 1 to "connect" of "Signal" has incompatible type "object"; expected "Callable[..., Any]"', - 'Item "str" of "Union[ValueError, str]" has no attribute "args"' - ], - 'deprecation': [ - '"Manager" has no attribute "old"', - '"Manager" has no attribute "new"' - ], - 'db_functions': [ - 'for **', - 'expected "float"', - 'Incompatible types in assignment (expression has type "Optional[FloatModel]", variable has type "FloatModel")', - re.compile(r'Item .* has no attribute'), - 'Module has no attribute', - 'Module \'datetime\' has no attribute', - '"DTModel" has no attribute', - '"Author" has no attribute', - '"FloatModel" has no attribute', - '"Article" has no attribute' - ], - 'decorators': [ - 'DummyRequest', - 'DummyUser', - '"Type[object]" has no attribute "method"' - ], - 'defer_regress': [ - '"Base" has no attribute "derived"' - ], - 'delete': [ - '"RChild" has no attribute', - '"Child" has no attribute "parent_ptr"' - ], - 'expressions': [ - 'Item "Experiment" of', - 'Item "Time" of', - '"Experiment" has no attribute', - '"Time" has no attribute', - ], - 'expressions_case': [ - '"CaseTestModel" has no attribute "selected"' - ], - 'expressions_window': [ - 'has incompatible type "str"' - ], - 'extra_regress': [ - '"User" has no attribute "alpha"' - ], - 'file_uploads': [ - '"Iterable[Any]" has no attribute', - '"IO[Any]" has no attribute' - ], - 'file_storage': [ - 'Incompatible types in assignment (expression has type "Callable[[], Any]"' - ], - 'files': [ - '"file_move_safe" does not return a value', - 'Incompatible types in assignment (expression has type "IOBase", variable has type "File")', - 'Module has no attribute "open"' - ], - 'fixtures': [ - 'Incompatible types in assignment (expression has type "int", target has type "Iterable[str]")' - ], - 'flatpages_tests': [ - '"Site" has no attribute "add"', - ], - 'forms_tests': [ - 'List item 0 has incompatible type "Jinja2"; expected "DjangoTemplates"', - 'Not enough arguments for format string', - 'Argument after ** must be a mapping, not "object"', - 'expression has type "None", base class "TestFormParent"', - 'variable has type "SongForm"', - '"full_clean" of "BaseForm" does not return a value', - 'No overload variant of "zip" matches argument types "Tuple[str, str, str]", "object"', - 'Incompatible types in assignment (expression has type "GetDateShowHiddenInitial", ' - + 'variable has type "GetDate")', - re.compile(r'Incompatible types in assignment \(expression has type "[a-zA-Z]+Field", ' - r'base class "BaseForm" defined the type as "Dict\[str, Any\]"\)'), - 'List or tuple expected as variable arguments', - 'Argument 1 to "__init__" of "MultiWidget" has incompatible type "List[object]"; ' - + 'expected "Sequence[Union[Widget, Type[Widget]]]"', - 'Argument 1 to "issubclass" has incompatible type "ModelFormMetaclass"; expected "type"', - 'Incompatible types in assignment (expression has type "List[str]", target has type "str")', - 'Incompatible types in assignment (expression has type "TestForm", variable has type "Person")', - 'Incompatible types in assignment (expression has type "Type[Textarea]", ' - + 'base class "Field" defined the type as "Widget")', - 'Incompatible types in assignment (expression has type "SimpleUploadedFile", variable has type "BinaryIO")', - 'has no attribute', - 'Name \'forms.Field\' is not defined' - ], - 'foreign_object': [ - '"Person" has no attribute', - '"SlugPage" has no attribute' - ], - 'from_db_value': [ - '"Cash" has no attribute' - ], - 'get_object_or_404': [ - 'Argument 1 to "get_object_or_404" has incompatible type "str"; ' - + 'expected "Union[Type[], QuerySet[, ]]"', - 'Argument 1 to "get_list_or_404" has incompatible type "List[Type[Article]]"; ' - + 'expected "Union[Type[], QuerySet[, ]]"', - 'CustomClass' - ], - 'generic_relations': [ - 'has no attribute "id"', - 'has no attribute "pk"' - ], - 'generic_relations_regress': [ - '"HasLinkThing" has no attribute', - '"Link" has no attribute' - ], - 'httpwrappers': [ - 'Argument 2 to "appendlist" of "QueryDict"', - 'Incompatible types in assignment (expression has type "int", target has type "Union[str, List[str]]")', - 'Argument 1 to "fromkeys" of "QueryDict" has incompatible type "int"' - ], - 'humanize_tests': [ - 'Argument 1 to "append" of "list" has incompatible type "None"; expected "str"' - ], - 'inline_formsets': [ - 'has no attribute "form"' - ], - 'i18n': [ - 'Incompatible types in assignment (expression has type "I18nForm", variable has type "SelectDateForm")', - 'has incompatible type "object"', - 'Value of type "Optional[List[_Record]]" is not indexable', - '"Command" has no attribute' - ], - 'logging_tests': [ - '"Handler" has no attribute "stream"' - ], - 'lookup': [ - 'Unexpected keyword argument "headline__startswith" for "in_bulk" of "QuerySet"', - '\'flat\' is not valid when values_list is called with more than one field.' - ], - 'm2o_recursive': [ - 'Incompatible type for "id" of "Category" (got "None", expected "int")' - ], - 'many_to_one': [ - 'Incompatible type for "parent" of "Child" (got "None", expected "Union[Parent, Combinable]")', - 'Incompatible type for "parent" of "Child" (got "Child", expected "Union[Parent, Combinable]")' - ], - 'managers_regress': [ - '"Type[AbstractBase3]" has no attribute "objects"' - ], - 'middleware_exceptions': [ - 'Argument 1 to "append" of "list" has incompatible type "Tuple[Any, Any]"; expected "str"' - ], - 'model_fields': [ - 'Incompatible types in assignment (expression has type "Type[Person]", variable has type', - 'Unexpected keyword argument "name" for "Person"', - 'Cannot assign multiple types to name "PersonTwoImages" without an explicit "Type[...]" annotation', - re.compile( - r'Incompatible types in assignment \(expression has type "Type\[.+?\]", base class "IntegerFieldTests"' - r' defined the type as "Type\[IntegerModel\]"\)'), - re.compile(r'Incompatible types in assignment \(expression has type "Type\[.+?\]", base class' - r' "ImageFieldTestMixin" defined the type as "Type\[PersonWithHeightAndWidth\]"\)'), - 'Incompatible import of "Person"', - 'Incompatible types in assignment (expression has type "FloatModel", variable has type ' - '"Union[float, int, str, Combinable]")', - '"UUIDGrandchild" has no attribute "uuidchild_ptr_id"', - '"Person" has no attribute', - '"Foo" has no attribute', - ], - 'model_formsets': [ - 'has no attribute' - ], - 'model_indexes': [ - 'Argument "condition" to "Index" has incompatible type "str"; expected "Optional[Q]"' - ], - 'model_inheritance_regress': [ - '"Restaurant" has no attribute', - '"ArticleWithAuthor" has no attribute', - '"Person" has no attribute', - '"MessyBachelorParty" has no attribute', - '"Place" has no attribute', - '"ItalianRestaurant" has no attribute' - ], - 'model_meta': [ - '"Field[Any, Any]" has no attribute "many_to_many"' - ], - 'model_regress': [ - re.compile(r'Incompatible type for "[a-z]+" of "Worker" \(got "int", expected'), - '"PickledModel" has no attribute', - '"Department" has no attribute' - ], - 'modeladmin': [ - 'BandAdmin', - 'base class "ModelAdmin" defined the type a', - 'base class "InlineModelAdmin" defined the type a', - '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': [ - 'Value of type "None" is not indexable', - 'Argument 1 to "set" has incompatible type "None"; expected "Iterable[]"' - ], - 'migrations': [ - 'FakeMigration', - '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 2 to "register_serializer" of "MigrationWriter" has incompatible type ' - + '"Type[TestModel1]"; expected "Type[BaseSerializer]"', - 'Argument 1 to "append" of "list" has incompatible type "AddConstraint"; expected "CreateModel"' - ], - 'multiple_database': [ - 'Too many arguments for "create" of "QuerySet"', - '"User" has no attribute "userprofile"', - 'Item "GenericForeignKey" of', - 'Item "Model" of' - ], - 'known_related_objects': [ - '"Pool" has no attribute' - ], - 'one_to_one': [ - '"Place" has no attribute', - '"Type[Place]" has no attribute', - '"ManualPrimaryKey" has no attribute' - ], - 'postgres_tests': [ - 'DummyArrayField', - '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"; ' - + 'expected "Optional[Type[JSONEncoder]]"', - 'Incompatible type for "field" of "IntegerArrayModel" (got "None", ' - + 'expected "Union[Sequence[int], Combinable]")', - re.compile(r'Incompatible types in assignment \(expression has type "Type\[.+?\]", ' - r'base class "(UnaccentTest|TrigramTest)" defined the type as "Type\[CharFieldModel\]"\)'), - '"Type[PostgreSQLModel]" has no attribute "objects"', - '("None" and "SearchQuery")', - # TODO: - 'django.contrib.postgres.forms', - 'django.contrib.postgres.aggregates', - ], - 'properties': [ - re.compile('Unexpected attribute "(full_name|full_name_2)" for model "Person"') - ], - 'prefetch_related': [ - 'Incompatible types in assignment (expression has type "List[Room]", variable has type "QuerySet[Room, Room]")', - '"Person" has no attribute', - '"Author" has no attribute', - '"Book" has no attribute', - 'Item "Room" of', - '"AuthorWithAge" has no attribute', - 'has no attribute "read_by"' - ], - 'proxy_model_inheritance': [ - 'Incompatible import of "ProxyModel"' - ], - 'queries': [ - 'Incompatible types in assignment (expression has type "None", variable has type "str")', - 'Invalid index type "Optional[str]" for "Dict[str, int]"; expected type "str"', - 'No overload variant of "values_list" of "QuerySet" matches argument types "str", "bool", "bool"', - 'Unsupported operand types for & ("QuerySet[Author, Author]" and "QuerySet[Tag, Tag]")', - 'Unsupported operand types for | ("QuerySet[Author, Author]" and "QuerySet[Tag, Tag]")', - 'Incompatible types in assignment (expression has type "ObjectB", variable has type "ObjectA")', - 'Incompatible types in assignment (expression has type "ObjectC", variable has type "ObjectA")', - 'Incompatible type for "objectb" of "ObjectC" (got "ObjectA", expected' - ' "Union[ObjectB, Combinable, None, None]")', - '"Note" has no attribute', - '"Ranking" has no attribute', - '"BaseUser" has no attribute', - '"Item" has no attribute', - "'flat' and 'named' can't be used together.", - ], - 'queryset_pickle': [ - 'RelatedObjectDoesNotExist', - '"Type[Event]" has no attribute "happening"' - ], - 'requests': [ - 'Incompatible types in assignment (expression has type "Dict[str, str]", variable has type "QueryDict")' - ], - 'responses': [ - 'Argument 1 to "TextIOWrapper" has incompatible type "HttpResponse"; expected "IO[bytes]"' - ], - 'schema': [ - '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 "year" of "UniqueTest" (got "None", expected "Union[float, int, str, Combinable]")' - ], - 'settings_tests': [ - 'Argument 1 to "Settings" has incompatible type "Optional[str]"; expected "str"' - ], - 'signals': [ - 'Argument 1 to "append" of "list" has incompatible type "Tuple[Any, Any, Optional[Any], Any]"; ' - + 'expected "Tuple[Any, Any, Any]"' - ], - 'sites_tests': [ - 'Item "RequestSite" of "Union[Site, RequestSite]" has no attribute "id"' - ], - '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")', - '"AbstractBaseSession" has no attribute' - ], - 'select_related': [ - '"Species" has no attribute', - 'Item "object" of "Union[object, Any]" has no attribute "first"' - ], - 'select_related_onetoone': [ - 'Incompatible types in assignment (expression has type "Parent2", variable has type "Parent1")', - 'has no attribute' - ], - 'select_for_update': [ - 'has incompatible type "object"' - ], - 'servers': [ - re.compile('Argument [0-9] to "WSGIRequestHandler"'), - '"HTTPResponse" has no attribute', - '"type" has no attribute', - '"WSGIRequest" has no attribute "makefile"' - ], - '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]"', - 'has no attribute "template_debug"', - "Module 'django.template.base' has no attribute 'TemplateSyntaxError'" - ], - 'template_backends': [ - 'Incompatible import of "Jinja2" (imported name has type "Type[Jinja2]", local name has type "object")', - 'TemplateStringsTests', - "Cannot find module named 'DoesNotExist'" - ], - 'test_client': [ - 'Incompatible types in assignment (expression has type "HttpResponse", ' - + 'variable has type "StreamingHttpResponse")' - ], - 'test_client_regress': [ - 'Incompatible types in assignment (expression has type "Dict[, ]", ' - + 'variable has type "SessionBase")', - 'Unsupported left operand type for + ("None")', - ], - 'test_runner': [ - 'Argument "result" to "run" of "TestCase" has incompatible type "RemoteTestResult"; ' - + 'expected "Optional[TestResult]"', - 'has no attribute "id"', - 'MockTestRunner' - ], - 'transactions': [ - 'Incompatible types in assignment (expression has type "Thread", variable has type "Callable[[], Any]")' - ], - 'urlpatterns': [ - '"object" not callable' - ], - 'user_commands': [ - 'Incompatible types in assignment (expression has type "Callable[[Any, KwArg(Any)], Any]", variable has type', - 'Cannot find module named \'user_commands.management.commands\'' - ], - 'utils_tests': [ - 'a_package_name_that_does_not_exist', - 'Too few arguments for "__init__"', - 'Argument 1 to "activate" has incompatible type "None"; expected "Union[tzinfo, str]"', - 'Module has no attribute "content"', - 'Argument 1 to "int_to_base36" has incompatible type "object"; expected "int"', - 'Argument 1 to "base36_to_int" has incompatible type "object"; expected "str"', - 'Incompatible types in assignment (expression has type "None", base class "object" defined the type as', - 'Invalid type "Class"', - 'has no attribute "cp"', - 'Argument "name" to "cached_property" has incompatible type "int"; expected "Optional[str]"', - 'foo', - '"ImmutableList[int]" has no attribute "sort"', - 'has no attribute "cache_clear"', - 'has no attribute "cache_info"', - 'Argument 1 to "Path" has incompatible type "Optional[str]"; expected "Union[str, _PathLike[str]]"', - 'defined the type as "None"' - ], - 'view_tests': [ - '"EmailMessage" has no attribute "alternatives"', - '"Handler" has no attribute "include_html"', - "Module 'django.views.debug' has no attribute 'Path'" - ] -} -# Test folders to typecheck -TESTS_DIRS = [ - 'absolute_url_overrides', - 'admin_autodiscover', - 'admin_changelist', - 'admin_checks', - 'admin_custom_urls', - 'admin_default_site', - 'admin_docs', - # TODO: 'admin_filters', - 'admin_inlines', - 'admin_ordering', - 'admin_registration', - 'admin_scripts', - 'admin_utils', - 'admin_views', - 'admin_widgets', - 'aggregation', - 'aggregation_regress', - 'annotations', - 'app_loading', - 'apps', - 'auth_tests', - 'backends', - 'base', - 'bash_completion', - 'basic', - 'builtin_server', - 'bulk_create', - # TODO: 'cache', - 'check_framework', - 'choices', - 'conditional_processing', - 'constraints', - 'contenttypes_tests', - 'context_processors', - 'csrf_tests', - 'custom_columns', - 'custom_lookups', - 'custom_managers', - 'custom_methods', - 'custom_migration_operations', - 'custom_pk', - 'datatypes', - 'dates', - 'datetimes', - 'db_functions', - 'db_typecasts', - 'db_utils', - 'dbshell', - 'decorators', - 'defer', - 'defer_regress', - 'delete', - 'delete_regress', - 'deprecation', - 'dispatch', - 'distinct_on_fields', - 'empty', - 'expressions', - 'expressions_case', - 'expressions_window', - 'extra_regress', - 'field_deconstruction', - 'field_defaults', - 'field_subclassing', - 'file_storage', - 'file_uploads', - 'files', - 'filtered_relation', - 'fixtures', - 'fixtures_model_package', - 'fixtures_regress', - 'flatpages_tests', - 'force_insert_update', - 'foreign_object', - 'forms_tests', - 'from_db_value', - 'generic_inline_admin', - 'generic_relations', - 'generic_relations_regress', - # TODO: 'generic_views', - 'get_earliest_or_latest', - 'get_object_or_404', - 'get_or_create', - # TODO: 'gis_tests', - 'handlers', - 'httpwrappers', - 'humanize_tests', - 'i18n', - 'import_error_package', - 'indexes', - 'inline_formsets', - 'inspectdb', - 'introspection', - # not practical - # 'invalid_models_tests', - 'known_related_objects', - 'logging_tests', - 'lookup', - 'm2m_and_m2o', - 'm2m_intermediary', - 'm2m_multiple', - 'm2m_recursive', - 'm2m_regress', - 'm2m_signals', - 'm2m_through', - 'm2m_through_regress', - 'm2o_recursive', - # TODO: 'mail', - 'managers_regress', - 'many_to_many', - 'many_to_one', - 'many_to_one_null', - 'max_lengths', - # TODO: 'messages_tests', - 'middleware', - 'middleware_exceptions', - 'migrate_signals', - 'migration_test_data_persistence', - 'migrations', - 'migrations2', - 'model_fields', - # TODO: 'model_forms', - 'model_formsets', - 'model_formsets_regress', - 'model_indexes', - # TODO: 'model_inheritance', - 'model_inheritance_regress', - 'model_meta', - 'model_options', - 'model_package', - 'model_regress', - 'modeladmin', - 'multiple_database', - 'mutually_referential', - 'nested_foreign_keys', - 'no_models', - 'null_fk', - 'null_fk_ordering', - 'null_queries', - 'one_to_one', - 'or_lookups', - 'order_with_respect_to', - 'ordering', - 'pagination', - 'postgres_tests', - 'prefetch_related', - 'project_template', - 'properties', - 'proxy_model_inheritance', - # TODO: 'proxy_models', - 'queries', - 'queryset_pickle', - 'raw_query', - 'redirects_tests', - 'requests', - 'reserved_names', - 'resolve_url', - 'responses', - 'reverse_lookup', - 'save_delete_hooks', - 'schema', - 'select_for_update', - 'select_related', - 'select_related_onetoone', - 'select_related_regress', - # TODO: 'serializers', - 'servers', - 'sessions_tests', - 'settings_tests', - 'shell', - 'shortcuts', - 'signals', - 'signed_cookies_tests', - 'signing', - # TODO: 'sitemaps_tests', - 'sites_framework', - 'sites_tests', - # TODO: 'staticfiles_tests', - 'str', - 'string_lookup', - 'swappable_models', - 'syndication_tests', - 'template_backends', - 'template_loader', - 'template_tests', - 'test_client', - 'test_client_regress', - 'test_exceptions', - 'test_runner', - 'test_runner_apps', - 'test_utils', - 'timezones', - 'transaction_hooks', - 'transactions', - 'unmanaged_models', - 'update', - 'update_only_fields', - 'urlpatterns', - # not annotatable without annotation in test - # 'urlpatterns_reverse', - 'user_commands', - 'utils_tests', - 'validation', - 'validators', - 'version', - 'view_tests', - 'wsgi', -] - - -@contextmanager -def cd(path): - """Context manager to temporarily change working directories""" - if not path: - return - prev_cwd = Path.cwd().as_posix() - if isinstance(path, Path): - path = path.as_posix() - os.chdir(str(path)) - try: - yield - finally: - os.chdir(prev_cwd) - def is_ignored(line: str, test_folder_name: str) -> bool: - for pattern in itertools.chain(IGNORED_ERRORS['__common__'], + if 'runtests' in line: + return True + + if test_folder_name in IGNORED_MODULES: + return True + + for pattern in itertools.chain(IGNORED_ERRORS['__new_common__'], IGNORED_ERRORS.get(test_folder_name, [])): if isinstance(pattern, Pattern): if pattern.search(line): @@ -828,24 +42,6 @@ def replace_with_clickable_location(error: str, abs_test_folder: Path) -> str: return error.replace(raw_path, clickable_location) -def check_with_mypy(abs_path: Path, config_file_path: Path) -> int: - error_happened = False - with cd(abs_path): - sources, options = process_options(['--cache-dir', str(config_file_path.parent / '.mypy_cache'), - '--config-file', str(config_file_path), - str(abs_path)]) - res = build.build(sources, options) - for error_line in res.errors: - if not is_ignored(error_line, abs_path.name): - error_happened = True - print(replace_with_clickable_location(error_line, abs_test_folder=abs_path)) - return int(error_happened) - - -def get_absolute_path_for_test(test_dirname: str): - return (PROJECT_DIRECTORY / tests_root / test_dirname).absolute() - - if __name__ == '__main__': mypy_config_file = (PROJECT_DIRECTORY / 'scripts' / 'mypy.ini').absolute() repo_directory = PROJECT_DIRECTORY / 'django-sources' @@ -853,28 +49,31 @@ if __name__ == '__main__': tests_root = repo_directory / 'tests' global_rc = 0 - # clone Django repository, if it does not exist - if not repo_directory.exists(): - repo = Repo.clone_from('https://github.com/django/django.git', repo_directory) - else: - repo = Repo(repo_directory) - repo.remotes['origin'].pull(DJANGO_BRANCH) - - repo.git.checkout(DJANGO_COMMIT_SHA) - - if len(sys.argv) > 1: - tests_to_run = sys.argv[1:] - else: - tests_to_run = TESTS_DIRS + # copy django settings to the tests_root directory + shutil.copy(PROJECT_DIRECTORY / 'scripts' / 'django_tests_settings.py', tests_root) try: - for dirname in tests_to_run: - abs_path = get_absolute_path_for_test(dirname) - print(f'Checking {abs_path}') + mypy_options = ['--cache-dir', str(mypy_config_file.parent / '.mypy_cache'), + '--config-file', str(mypy_config_file)] + mypy_options += [str(tests_root)] - rc = check_with_mypy(abs_path, mypy_config_file) - if rc != 0: - global_rc = 1 + import distutils.spawn + + mypy_executable = distutils.spawn.find_executable('mypy') + completed = subprocess.run([mypy_executable, *mypy_options], env={'PYTHONPATH': str(tests_root)}, + stdout=subprocess.PIPE, cwd=str(tests_root)) + sorted_lines = sorted(completed.stdout.decode().splitlines()) + for line in sorted_lines: + try: + module_name = line.split('/')[0] + except IndexError: + module_name = 'unknown' + + if not is_ignored(line, module_name): + if line.startswith(module_name): + print(replace_with_clickable_location(line, abs_test_folder=tests_root)) + else: + print(line) sys.exit(global_rc)