mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-07 20:54:29 +08:00
move to plain python script for typechecking
This commit is contained in:
96
scripts/typecheck_tests.py
Normal file
96
scripts/typecheck_tests.py
Normal file
@@ -0,0 +1,96 @@
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
|
||||
from git import Repo
|
||||
from mypy import build
|
||||
from mypy.main import process_options
|
||||
|
||||
DJANGO_BRANCH = 'stable/2.1.x'
|
||||
DJANGO_COMMIT_SHA = '03219b5f709dcd5b0bfacd963508625557ec1ef0'
|
||||
IGNORED_ERROR_PATTERNS = [
|
||||
'Need type annotation for',
|
||||
'already defined on',
|
||||
'Cannot assign to a',
|
||||
'cannot perform relative import',
|
||||
'broken_app',
|
||||
'LazySettings',
|
||||
'Cannot infer type of lambda',
|
||||
'Incompatible types in assignment (expression has type "Callable[',
|
||||
'"Callable[[Any], Any]" has no attribute',
|
||||
'"Callable[[Any, Any], Any]" has no attribute',
|
||||
'Invalid value for a to= parameter',
|
||||
'"HttpResponseBase" has no attribute "user"'
|
||||
]
|
||||
TESTS_DIRS = [
|
||||
'absolute_url_overrides',
|
||||
# 'admin_*'
|
||||
]
|
||||
|
||||
|
||||
@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) -> bool:
|
||||
for pattern in IGNORED_ERROR_PATTERNS:
|
||||
if pattern in line:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def check_with_mypy(abs_path: Path, config_file_path: Path) -> int:
|
||||
error_happened = False
|
||||
with cd(abs_path):
|
||||
sources, options = process_options(['--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):
|
||||
error_happened = True
|
||||
print(error_line)
|
||||
return int(error_happened)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
project_directory = Path(__file__).parent.parent
|
||||
mypy_config_file = (project_directory / 'scripts' / 'mypy.ini').absolute()
|
||||
repo_directory = project_directory / 'django-sources'
|
||||
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.remote().pull(DJANGO_COMMIT_SHA)
|
||||
|
||||
branch = repo.heads[DJANGO_BRANCH]
|
||||
branch.checkout()
|
||||
assert repo.active_branch.name == DJANGO_BRANCH
|
||||
assert repo.active_branch.commit.hexsha == DJANGO_COMMIT_SHA
|
||||
|
||||
for dirname in TESTS_DIRS:
|
||||
paths = glob.glob(str(tests_root / dirname))
|
||||
for path in paths:
|
||||
abs_path = (project_directory / path).absolute()
|
||||
|
||||
print(f'Checking {abs_path.as_uri()}')
|
||||
rc = check_with_mypy(abs_path, mypy_config_file)
|
||||
if rc != 0:
|
||||
global_rc = 1
|
||||
|
||||
sys.exit(rc)
|
||||
Reference in New Issue
Block a user