Skip to content
This repository has been archived by the owner on Apr 15, 2020. It is now read-only.

Commit

Permalink
Merged in feature/mypy-lint (pull request #56)
Browse files Browse the repository at this point in the history
Add mypy linter
  • Loading branch information
Lusheng Lv committed Jun 15, 2017
2 parents 46c7b33 + 7144b7c commit 343f2f6
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,5 @@ docs/_build/

# Vagrant
.vagrant/

.mypy_cache/
48 changes: 48 additions & 0 deletions badwolf/lint/linters/mypy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
import logging

from badwolf.utils import run_command
from badwolf.lint import Problem
from badwolf.lint.linters import PythonLinter
from badwolf.lint.utils import in_path


logger = logging.getLogger(__name__)


class MypyLinter(PythonLinter):
name = 'mypy'
default_pattern = '*.py *.pyi'

def is_usable(self):
if not in_path('mypy'):
return False

# mypy only avaiable in Python 3
python_version = self.python_name[6:]
major, *_ = python_version.split('.', 1)
if int(major) < 3:
return False
return True

def lint_files(self, files):
command = [
self.python_name,
'-m',
'mypy',
]
command += files
_, output = run_command(command, split=True, include_errors=True, cwd=self.working_dir)
if not output:
raise StopIteration()

for line in output:
filename, line, level, message = self._parse_line(line)
is_error = level == 'error'
yield Problem(filename, line, message, self.name, is_error=is_error)

def _parse_line(self, line):
"""mypy only generates results as stdout.
Parse the output for real data."""
parts = line.split(':', 3)
return parts[0], int(parts[1]), parts[2].strip(), parts[3].strip()
2 changes: 2 additions & 0 deletions badwolf/lint/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from badwolf.lint.linters.pylint import PylintLinter
from badwolf.lint.linters.sasslint import SassLinter
from badwolf.lint.linters.stylelint import StyleLinter
from badwolf.lint.linters.mypy import MypyLinter


logger = logging.getLogger(__name__)
Expand All @@ -40,6 +41,7 @@ class LintProcessor(object):
'pylint': PylintLinter,
'sasslint': SassLinter,
'stylelint': StyleLinter,
'mypy': MypyLinter,
}

def __init__(self, context, spec, working_dir=None):
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ marshmallow-oneofschema
twine
flake8-bugbear
is-minified-js
mypy
5 changes: 5 additions & 0 deletions tests/fixtures/mypy/a.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
def p() -> None:
print('hello')


a = p()
44 changes: 44 additions & 0 deletions tests/test_lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -815,3 +815,47 @@ def test_stylelint_lint_a_scss(app, caplog):
assert len(lint.problems) == 2
problem = lint.problems[0]
assert problem.filename == 'a.scss'


def test_mypy_lint_a_py(app, caplog):
diff = """diff --git a/a.py b/a.py
new file mode 100644
index 0000000..87604af
--- /dev/null
+++ b/a.py
@@ -0,0 +1,5 @@
+def p() -> None:
+ print('hello')
+
+
+a = p()
"""

context = Context(
'deepanalyzer/badwolf',
None,
'pullrequest',
'message',
{'commit': {'hash': '000000'}},
{'commit': {'hash': '111111'}},
pr_id=1
)
spec = Specification()
spec.linters.append(ObjectDict(name='mypy', pattern=None))
lint = LintProcessor(context, spec, os.path.join(FIXTURES_PATH, 'mypy'))
patch = PatchSet(diff.split('\n'))
with mock.patch.object(lint, 'load_changes') as load_changes,\
mock.patch.object(lint, 'update_build_status') as build_status,\
mock.patch.object(lint, '_report') as report:
load_changes.return_value = patch
build_status.return_value = None
report.return_value = (1, 2)
lint.problems.set_changes(patch)
lint.process()

assert load_changes.called

assert len(lint.problems) == 1
problem = lint.problems[0]
assert problem.line == 5
assert problem.filename == 'a.py'

0 comments on commit 343f2f6

Please sign in to comment.