add linting script for mypy
This commit is contained in:
parent
e5b3a1e91e
commit
01b52fcca2
2 changed files with 93 additions and 0 deletions
83
lint
Executable file
83
lint
Executable file
|
@ -0,0 +1,83 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
from pathlib import Path
|
||||||
|
from pprint import pprint
|
||||||
|
from itertools import chain
|
||||||
|
from subprocess import check_call, run, PIPE
|
||||||
|
import sys
|
||||||
|
from typing import List, Optional, Iterable
|
||||||
|
|
||||||
|
|
||||||
|
def log(*args):
|
||||||
|
print(*args, file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
DIR = Path(__file__).absolute().parent
|
||||||
|
|
||||||
|
# hmm. I guess I need to check all subpackages separately
|
||||||
|
# otherwise pylint doesn't work and mypy doesn't discover everything
|
||||||
|
|
||||||
|
# TODO could reuse in readme??
|
||||||
|
# returns None if not a package
|
||||||
|
def package_name(p: Path) -> Optional[str]:
|
||||||
|
def mname(p: Path):
|
||||||
|
nosuf = p.with_suffix('')
|
||||||
|
return str(nosuf).replace('/', '.')
|
||||||
|
|
||||||
|
if p.suffix == '.py':
|
||||||
|
return mname(p)
|
||||||
|
|
||||||
|
if p.is_dir() and (p / '__init__.py').exists():
|
||||||
|
return mname(p)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def packages() -> Iterable[str]:
|
||||||
|
for p in sorted(p.relative_to(DIR) for p in (DIR / 'my').iterdir()):
|
||||||
|
res = package_name(p)
|
||||||
|
if res is not None:
|
||||||
|
yield res
|
||||||
|
|
||||||
|
|
||||||
|
def pylint():
|
||||||
|
# TODO ugh. pylint still doesn't like checking my.config or my.books
|
||||||
|
# only top level .py files seem ok??
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def mypy(package: str):
|
||||||
|
return run([
|
||||||
|
'mypy',
|
||||||
|
'--color-output', # TODO eh? doesn't work..
|
||||||
|
'--namespace-packages',
|
||||||
|
'-p', package,
|
||||||
|
], stdout=PIPE, stderr=PIPE)
|
||||||
|
|
||||||
|
|
||||||
|
def mypy_all() -> Iterable[Exception]:
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
pkgs = list(packages())
|
||||||
|
log(f"Checking {pkgs}")
|
||||||
|
with ThreadPoolExecutor() as pool:
|
||||||
|
for p, res in zip(pkgs, pool.map(mypy, pkgs)):
|
||||||
|
ret = res.returncode
|
||||||
|
if ret > 0:
|
||||||
|
log(f'FAILED: {p}')
|
||||||
|
else:
|
||||||
|
log(f'OK: {p}')
|
||||||
|
print(res.stdout.decode('utf8'))
|
||||||
|
print(res.stderr.decode('utf8'), file=sys.stderr)
|
||||||
|
try:
|
||||||
|
res.check_returncode()
|
||||||
|
except Exception as e:
|
||||||
|
yield e
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
errors = list(mypy_all())
|
||||||
|
if len(errors) > 0:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
10
mypy.ini
Normal file
10
mypy.ini
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[mypy]
|
||||||
|
mypy_path=~/.config/my
|
||||||
|
pretty = True
|
||||||
|
show_error_context = True
|
||||||
|
show_error_codes = True
|
||||||
|
check_untyped_defs = True
|
||||||
|
|
||||||
|
# it's not controled by me, so for now just ignore..
|
||||||
|
[mypy-my.config.repos.pdfannots.pdfannots]
|
||||||
|
ignore_errors = True
|
Loading…
Add table
Reference in a new issue