Fix typecheck tests ci (#165)

* remove mention of mypy newsemanal to prepare for 0.730

* make typecheck_tests CI really work

* fix lints

* fix intentional error

* merge stderr in stdout to preserve order

Co-authored-by: Daniel Hahler <github@thequod.de>
This commit is contained in:
Maxim Kurnikov
2019-09-16 14:35:13 +03:00
committed by GitHub
parent e3ea84143f
commit 2b53fa5a1a
5 changed files with 20 additions and 33 deletions

View File

@@ -51,7 +51,7 @@ class Options(Generic[_M]):
verbose_name: Optional[str] = ... verbose_name: Optional[str] = ...
verbose_name_plural: Optional[str] = ... verbose_name_plural: Optional[str] = ...
db_table: str = ... db_table: str = ...
ordering: Optional[List[str]] = ... ordering: Optional[Sequence[str]] = ...
indexes: List[Any] = ... indexes: List[Any] = ...
unique_together: Union[List[Any], Tuple] = ... unique_together: Union[List[Any], Tuple] = ...
index_together: Union[List[Any], Tuple] = ... index_together: Union[List[Any], Tuple] = ...

View File

@@ -1,5 +1,5 @@
from collections import OrderedDict from collections import OrderedDict
from typing import Type, cast from typing import Type
from django.db.models.base import Model from django.db.models.base import Model
from django.db.models.fields import DateField, DateTimeField from django.db.models.fields import DateField, DateTimeField
@@ -7,7 +7,6 @@ from django.db.models.fields.related import ForeignKey
from django.db.models.fields.reverse_related import ( from django.db.models.fields.reverse_related import (
ManyToManyRel, ManyToOneRel, OneToOneRel, ManyToManyRel, ManyToOneRel, OneToOneRel,
) )
from mypy.newsemanal.semanal import NewSemanticAnalyzer
from mypy.nodes import ( from mypy.nodes import (
ARG_STAR2, MDEF, Argument, SymbolTableNode, TypeInfo, Var, ARG_STAR2, MDEF, Argument, SymbolTableNode, TypeInfo, Var,
) )
@@ -23,7 +22,7 @@ from mypy_django_plugin.transformers.fields import get_field_descriptor_types
class ModelClassInitializer: class ModelClassInitializer:
def __init__(self, ctx: ClassDefContext, django_context: DjangoContext): def __init__(self, ctx: ClassDefContext, django_context: DjangoContext):
self.api = cast(NewSemanticAnalyzer, ctx.api) self.api = ctx.api
self.model_classdef = ctx.cls self.model_classdef = ctx.cls
self.django_context = django_context self.django_context = django_context
self.ctx = ctx self.ctx = ctx

View File

@@ -18,13 +18,11 @@ IGNORED_ERRORS = {
'__new_common__': [ '__new_common__': [
*MOCK_OBJECTS, *MOCK_OBJECTS,
*EXTERNAL_MODULES, *EXTERNAL_MODULES,
'SupportsFloat',
'Need type annotation for', 'Need type annotation for',
'has no attribute "getvalue"', 'has no attribute "getvalue"',
'Cannot assign to a method', 'Cannot assign to a method',
'Cannot infer type of lambda', 'Cannot infer type of lambda',
'already defined (possibly by an import)', 'already defined',
'already defined on line',
'Cannot assign to a type', 'Cannot assign to a type',
'"HttpResponse" has no attribute', '"HttpResponse" has no attribute',
'"HttpResponseBase" has no attribute', '"HttpResponseBase" has no attribute',
@@ -53,7 +51,6 @@ IGNORED_ERRORS = {
"No installed app with label 'missing'", "No installed app with label 'missing'",
'namedtuple', 'namedtuple',
'Lookups not supported yet', 'Lookups not supported yet',
'Argument 1 to "loads" has incompatible type',
# TODO: see test in managers/test_managers.yml # TODO: see test in managers/test_managers.yml
"Cannot determine type of", "Cannot determine type of",
'cache_clear', 'cache_clear',
@@ -63,7 +60,6 @@ IGNORED_ERRORS = {
# TODO: not supported yet # TODO: not supported yet
'GenericRelation', 'GenericRelation',
'RelatedObjectDoesNotExist', 'RelatedObjectDoesNotExist',
# Rel's attributes are not accessible from `get_field()`
re.compile(r'"Field\[Any, Any\]" has no attribute ' re.compile(r'"Field\[Any, Any\]" has no attribute '
r'"(through|field_name|field|get_related_field|related_model|related_name' r'"(through|field_name|field|get_related_field|related_model|related_name'
r'|get_accessor_name|empty_strings_allowed|many_to_many)"'), r'|get_accessor_name|empty_strings_allowed|many_to_many)"'),

View File

@@ -51,7 +51,12 @@ if __name__ == '__main__':
try: try:
mypy_options = ['--cache-dir', str(mypy_config_file.parent / '.mypy_cache'), mypy_options = ['--cache-dir', str(mypy_config_file.parent / '.mypy_cache'),
'--config-file', str(mypy_config_file)] '--config-file', str(mypy_config_file),
'--show-traceback',
# '--no-error-summary',
# '--no-pretty',
'--hide-error-context'
]
mypy_options += [str(tests_root)] mypy_options += [str(tests_root)]
import distutils.spawn import distutils.spawn
@@ -62,33 +67,20 @@ if __name__ == '__main__':
mypy_argv, mypy_argv,
env={'PYTHONPATH': str(tests_root)}, env={'PYTHONPATH': str(tests_root)},
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.STDOUT,
) )
rc = completed.returncode output = completed.stdout.decode()
stdout = completed.stdout.decode()
stderr = completed.stderr.decode()
if rc not in (0, 1) or stderr:
import shlex
cmd = " ".join(shlex.quote(s) for s in mypy_argv) sorted_lines = sorted(output.splitlines())
print("Failed to run {} (exitcode {})!".format(cmd, rc), file=sys.stderr)
if stderr:
print("=== Output on stderr: ===\n{}".format(stderr.rstrip("\n")))
if stdout:
print("=== Output on stdout: ===\n{}".format(stdout.rstrip("\n")))
sys.exit(rc or 1)
sorted_lines = sorted(stdout.splitlines())
for line in sorted_lines: for line in sorted_lines:
try: try:
module_name = line.split('/')[0] path_to_error = line.split(':')[0]
test_folder_name = path_to_error.split('/')[2]
except IndexError: except IndexError:
module_name = 'unknown' test_folder_name = 'unknown'
if not is_ignored(line, module_name): if not is_ignored(line, test_folder_name):
if line.startswith(module_name): global_rc = 1
print(replace_with_clickable_location(line, abs_test_folder=tests_root))
else:
print(line) print(line)
sys.exit(global_rc) sys.exit(global_rc)