diff --git a/pyls/plugins/jedi_lint.py b/pyls/plugins/jedi_lint.py new file mode 100644 index 00000000..739092cd --- /dev/null +++ b/pyls/plugins/jedi_lint.py @@ -0,0 +1,26 @@ +from pyls import hookimpl, lsp + + +@hookimpl +def pyls_lint(document): + errors = document.jedi_script().get_syntax_errors() + diagnostics = [] + + for error in errors: + err_range = { + 'start': { + 'line': error.line - 1, + 'character': error.column, + }, + 'end': { + 'line': error.until_line - 1, + 'character': error.until_column, + }, + } + diagnostics.append({ + 'source': 'jedi', + 'range': err_range, + 'message': error.get_message(), + 'severity': lsp.DiagnosticSeverity.Error, + }) + return diagnostics diff --git a/setup.py b/setup.py index 12782990..7a4dc490 100755 --- a/setup.py +++ b/setup.py @@ -97,6 +97,7 @@ 'jedi_rename = pyls.plugins.jedi_rename', 'jedi_signature_help = pyls.plugins.signature', 'jedi_symbols = pyls.plugins.symbols', + 'jedi_lint = pyls.plugins.jedi_lint', 'mccabe = pyls.plugins.mccabe_lint', 'preload = pyls.plugins.preload_imports', 'pycodestyle = pyls.plugins.pycodestyle_lint', diff --git a/test/plugins/test_jedi_lint.py b/test/plugins/test_jedi_lint.py new file mode 100644 index 00000000..db7fee59 --- /dev/null +++ b/test/plugins/test_jedi_lint.py @@ -0,0 +1,60 @@ +from pyls import lsp, uris +from pyls.workspace import Document +from pyls.plugins import jedi_lint + +DOC_URI = uris.from_fs_path(__file__) +DOC = """import sys + +def hello(): +\tpass + +import json +""" + +DOC_SYNTAX_ERR = """def hello() + pass +""" + +DOC_INDENT_ERR = """def hello(): + x = 1 + pass +""" + +DOC_ENCODING = u"""# encoding=utf-8 +import sys +""" + + +def test_jedi_lint(workspace): + doc = Document(DOC_URI, workspace, DOC) + diags = jedi_lint.pyls_lint(doc) + + assert not diags + + +def test_syntax_error_jedi(workspace): + doc = Document(DOC_URI, workspace, DOC_SYNTAX_ERR) + diag = jedi_lint.pyls_lint(doc)[0] + + assert diag['message'] == 'SyntaxError: invalid syntax' + assert diag['range']['start'] == {'line': 0, 'character': 11} + assert diag['range']['end'] == {'line': 1, 'character': 0} + assert diag['severity'] == lsp.DiagnosticSeverity.Error + + +def test_indent_error_jedi(workspace): + doc = Document(DOC_URI, workspace, DOC_INDENT_ERR) + diag = jedi_lint.pyls_lint(doc)[0] + + assert diag['message'] == "IndentationError: unindent does not match \ +any outer indentation level" + assert diag['range']['start'] == {'line': 2, 'character': 0} + assert diag['range']['end'] == {'line': 2, 'character': 2} + assert diag['severity'] == lsp.DiagnosticSeverity.Error + + +def test_encoding_jedi(workspace): + doc = Document(DOC_URI, workspace, DOC_ENCODING) + diags = jedi_lint.pyls_lint(doc) + + assert not diags