python-language-server
Advanced tools
+8
-5
| Metadata-Version: 2.1 | ||
| Name: python-language-server | ||
| Version: 0.34.1 | ||
| Version: 0.35.0 | ||
| Summary: Python Language Server for the Language Server Protocol | ||
@@ -11,8 +11,11 @@ Home-page: https://github.com/palantir/python-language-server | ||
| .. image:: https://circleci.com/gh/palantir/python-language-server.svg?style=shield | ||
| :target: https://circleci.com/gh/palantir/python-language-server | ||
| .. image:: https://github.com/palantir/python-language-server/workflows/Linux%20tests/badge.svg | ||
| :target: https://github.com/palantir/python-language-server/actions?query=workflow%3A%22Linux+tests%22 | ||
| .. image:: https://ci.appveyor.com/api/projects/status/mdacv6fnif7wonl0?svg=true | ||
| :target: https://ci.appveyor.com/project/gatesn/python-language-server | ||
| .. image:: https://github.com/palantir/python-language-server/workflows/Mac%20tests/badge.svg | ||
| :target: https://github.com/palantir/python-language-server/actions?query=workflow%3A%22Mac+tests%22 | ||
| .. image:: https://github.com/palantir/python-language-server/workflows/Windows%20tests/badge.svg | ||
| :target: https://github.com/palantir/python-language-server/actions?query=workflow%3A%22Windows+tests%22 | ||
| .. image:: https://img.shields.io/github/license/palantir/python-language-server.svg | ||
@@ -19,0 +22,0 @@ :target: https://github.com/palantir/python-language-server/blob/master/LICENSE |
+3
-3
@@ -11,7 +11,7 @@ | ||
| { | ||
| "date": "2020-07-02T11:29:43-0500", | ||
| "date": "2020-09-10T20:08:36-0500", | ||
| "dirty": false, | ||
| "error": null, | ||
| "full-revisionid": "78dee3d03fd6027804588fd204df06b2ac57d7d3", | ||
| "version": "0.34.1" | ||
| "full-revisionid": "eb479ff2b214a13fd1c2fb1dcf2993a45c3bb830", | ||
| "version": "0.35.0" | ||
| } | ||
@@ -18,0 +18,0 @@ ''' # END VERSION_JSON |
@@ -19,3 +19,3 @@ # Copyright 2017 Palantir Technologies, Inc. | ||
| { | ||
| 'uri': uris.uri_with(document.uri, path=d.module_path), | ||
| 'uri': uris.uri_with(document.uri, path=str(d.module_path)), | ||
| 'range': { | ||
@@ -22,0 +22,0 @@ 'start': {'line': d.line - 1, 'character': d.column}, |
@@ -17,3 +17,3 @@ # Copyright 2017 Palantir Technologies, Inc. | ||
| def local_to_document(definition): | ||
| return not definition.module_path or definition.module_path == document.path | ||
| return not definition.module_path or str(definition.module_path) == document.path | ||
@@ -20,0 +20,0 @@ return [{ |
@@ -22,3 +22,3 @@ # Copyright 2020 Palantir Technologies, Inc. | ||
| for file_path, changed_file in refactoring.get_changed_files().items(): | ||
| uri = uris.from_fs_path(file_path) | ||
| uri = uris.from_fs_path(str(file_path)) | ||
| doc = workspace.get_maybe_document(uri) | ||
@@ -25,0 +25,0 @@ changes.append({ |
@@ -6,2 +6,4 @@ # Copyright 2018 Google LLC. | ||
| import sys | ||
| import re | ||
| from subprocess import Popen, PIPE | ||
@@ -158,3 +160,8 @@ from pylint.epylint import py_run | ||
| # file to be useful. | ||
| return {'plugins': {'pylint': {'enabled': False, 'args': []}}} | ||
| return {'plugins': {'pylint': { | ||
| 'enabled': False, | ||
| 'args': [], | ||
| # disabled by default as it can slow down the workflow | ||
| 'executable': None, | ||
| }}} | ||
@@ -164,5 +171,137 @@ | ||
| def pyls_lint(config, document, is_saved): | ||
| """Run pylint linter.""" | ||
| settings = config.plugin_settings('pylint') | ||
| log.debug("Got pylint settings: %s", settings) | ||
| # pylint >= 2.5.0 is required for working through stdin and only | ||
| # available with python3 | ||
| if settings.get('executable') and sys.version_info[0] >= 3: | ||
| flags = build_args_stdio(settings) | ||
| pylint_executable = settings.get('executable', 'pylint') | ||
| return pylint_lint_stdin(pylint_executable, document, flags) | ||
| flags = _build_pylint_flags(settings) | ||
| return PylintLinter.lint(document, is_saved, flags=flags) | ||
| def build_args_stdio(settings): | ||
| """Build arguments for calling pylint. | ||
| :param settings: client settings | ||
| :type settings: dict | ||
| :return: arguments to path to pylint | ||
| :rtype: list | ||
| """ | ||
| pylint_args = settings.get('args') | ||
| if pylint_args is None: | ||
| return [] | ||
| return pylint_args | ||
| def pylint_lint_stdin(pylint_executable, document, flags): | ||
| """Run pylint linter from stdin. | ||
| This runs pylint in a subprocess with popen. | ||
| This allows passing the file from stdin and as a result | ||
| run pylint on unsaved files. Can slowdown the workflow. | ||
| :param pylint_executable: path to pylint executable | ||
| :type pylint_executable: string | ||
| :param document: document to run pylint on | ||
| :type document: pyls.workspace.Document | ||
| :param flags: arguments to path to pylint | ||
| :type flags: list | ||
| :return: linting diagnostics | ||
| :rtype: list | ||
| """ | ||
| pylint_result = _run_pylint_stdio(pylint_executable, document, flags) | ||
| return _parse_pylint_stdio_result(document, pylint_result) | ||
| def _run_pylint_stdio(pylint_executable, document, flags): | ||
| """Run pylint in popen. | ||
| :param pylint_executable: path to pylint executable | ||
| :type pylint_executable: string | ||
| :param document: document to run pylint on | ||
| :type document: pyls.workspace.Document | ||
| :param flags: arguments to path to pylint | ||
| :type flags: list | ||
| :return: result of calling pylint | ||
| :rtype: string | ||
| """ | ||
| log.debug("Calling %s with args: '%s'", pylint_executable, flags) | ||
| try: | ||
| cmd = [pylint_executable] | ||
| cmd.extend(flags) | ||
| cmd.extend(['--from-stdin', document.path]) | ||
| p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) | ||
| except IOError: | ||
| log.debug("Can't execute %s. Trying with 'python -m pylint'", pylint_executable) | ||
| cmd = ['python', '-m', 'pylint'] | ||
| cmd.extend(flags) | ||
| cmd.extend(['--from-stdin', document.path]) | ||
| p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) | ||
| (stdout, stderr) = p.communicate(document.source.encode()) | ||
| if stderr: | ||
| log.error("Error while running pylint '%s'", stderr.decode()) | ||
| return stdout.decode() | ||
| def _parse_pylint_stdio_result(document, stdout): | ||
| """Parse pylint results. | ||
| :param document: document to run pylint on | ||
| :type document: pyls.workspace.Document | ||
| :param stdout: pylint results to parse | ||
| :type stdout: string | ||
| :return: linting diagnostics | ||
| :rtype: list | ||
| """ | ||
| diagnostics = [] | ||
| lines = stdout.splitlines() | ||
| for raw_line in lines: | ||
| parsed_line = re.match(r'(.*):(\d*):(\d*): (\w*): (.*)', raw_line) | ||
| if not parsed_line: | ||
| log.debug("Pylint output parser can't parse line '%s'", raw_line) | ||
| continue | ||
| parsed_line = parsed_line.groups() | ||
| if len(parsed_line) != 5: | ||
| log.debug("Pylint output parser can't parse line '%s'", raw_line) | ||
| continue | ||
| _, line, character, code, msg = parsed_line | ||
| line = int(line) - 1 | ||
| character = int(character) | ||
| severity_map = { | ||
| 'C': lsp.DiagnosticSeverity.Information, | ||
| 'E': lsp.DiagnosticSeverity.Error, | ||
| 'F': lsp.DiagnosticSeverity.Error, | ||
| 'R': lsp.DiagnosticSeverity.Hint, | ||
| 'W': lsp.DiagnosticSeverity.Warning, | ||
| } | ||
| severity = severity_map[code[0]] | ||
| diagnostics.append( | ||
| { | ||
| 'source': 'pylint', | ||
| 'code': code, | ||
| 'range': { | ||
| 'start': { | ||
| 'line': line, | ||
| 'character': character | ||
| }, | ||
| 'end': { | ||
| 'line': line, | ||
| # no way to determine the column | ||
| 'character': len(document.lines[line]) - 1 | ||
| } | ||
| }, | ||
| 'message': msg, | ||
| 'severity': severity, | ||
| } | ||
| ) | ||
| return diagnostics |
@@ -19,3 +19,3 @@ # Copyright 2017 Palantir Technologies, Inc. | ||
| return [{ | ||
| 'uri': uris.uri_with(document.uri, path=d.module_path) if d.module_path else document.uri, | ||
| 'uri': uris.uri_with(document.uri, path=str(d.module_path)) if d.module_path else document.uri, | ||
| 'range': { | ||
@@ -22,0 +22,0 @@ 'start': {'line': d.line - 1, 'character': d.column}, |
| Metadata-Version: 2.1 | ||
| Name: python-language-server | ||
| Version: 0.34.1 | ||
| Version: 0.35.0 | ||
| Summary: Python Language Server for the Language Server Protocol | ||
@@ -11,8 +11,11 @@ Home-page: https://github.com/palantir/python-language-server | ||
| .. image:: https://circleci.com/gh/palantir/python-language-server.svg?style=shield | ||
| :target: https://circleci.com/gh/palantir/python-language-server | ||
| .. image:: https://github.com/palantir/python-language-server/workflows/Linux%20tests/badge.svg | ||
| :target: https://github.com/palantir/python-language-server/actions?query=workflow%3A%22Linux+tests%22 | ||
| .. image:: https://ci.appveyor.com/api/projects/status/mdacv6fnif7wonl0?svg=true | ||
| :target: https://ci.appveyor.com/project/gatesn/python-language-server | ||
| .. image:: https://github.com/palantir/python-language-server/workflows/Mac%20tests/badge.svg | ||
| :target: https://github.com/palantir/python-language-server/actions?query=workflow%3A%22Mac+tests%22 | ||
| .. image:: https://github.com/palantir/python-language-server/workflows/Windows%20tests/badge.svg | ||
| :target: https://github.com/palantir/python-language-server/actions?query=workflow%3A%22Windows+tests%22 | ||
| .. image:: https://img.shields.io/github/license/palantir/python-language-server.svg | ||
@@ -19,0 +22,0 @@ :target: https://github.com/palantir/python-language-server/blob/master/LICENSE |
| jedi<0.18.0,>=0.17.0 | ||
| python-jsonrpc-server>=0.3.2 | ||
| python-jsonrpc-server>=0.4.0 | ||
| pluggy | ||
| ujson>=3.0.0 | ||
| [:platform_system != "Windows"] | ||
| ujson<=1.35 | ||
| [:python_version < "3"] | ||
@@ -24,3 +22,3 @@ future>=0.14.0 | ||
| pyflakes<2.3.0,>=2.2.0 | ||
| pylint | ||
| pylint>=2.5.0 | ||
| rope>=0.10.5 | ||
@@ -48,3 +46,3 @@ yapf | ||
| [pylint] | ||
| pylint | ||
| pylint>=2.5.0 | ||
@@ -56,3 +54,3 @@ [rope] | ||
| versioneer | ||
| pylint | ||
| pylint>=2.5.0 | ||
| pytest | ||
@@ -65,2 +63,3 @@ mock | ||
| matplotlib | ||
| flaky | ||
@@ -67,0 +66,0 @@ [test:python_version >= "3"] |
+7
-4
| Python Language Server | ||
| ====================== | ||
| .. image:: https://circleci.com/gh/palantir/python-language-server.svg?style=shield | ||
| :target: https://circleci.com/gh/palantir/python-language-server | ||
| .. image:: https://github.com/palantir/python-language-server/workflows/Linux%20tests/badge.svg | ||
| :target: https://github.com/palantir/python-language-server/actions?query=workflow%3A%22Linux+tests%22 | ||
| .. image:: https://ci.appveyor.com/api/projects/status/mdacv6fnif7wonl0?svg=true | ||
| :target: https://ci.appveyor.com/project/gatesn/python-language-server | ||
| .. image:: https://github.com/palantir/python-language-server/workflows/Mac%20tests/badge.svg | ||
| :target: https://github.com/palantir/python-language-server/actions?query=workflow%3A%22Mac+tests%22 | ||
| .. image:: https://github.com/palantir/python-language-server/workflows/Windows%20tests/badge.svg | ||
| :target: https://github.com/palantir/python-language-server/actions?query=workflow%3A%22Windows+tests%22 | ||
| .. image:: https://img.shields.io/github/license/palantir/python-language-server.svg | ||
@@ -11,0 +14,0 @@ :target: https://github.com/palantir/python-language-server/blob/master/LICENSE |
+25
-14
| #!/usr/bin/env python | ||
| import sys | ||
| from setuptools import find_packages, setup | ||
| import versioneer | ||
| import sys | ||
| README = open('README.rst', 'r').read() | ||
| install_requires = [ | ||
| 'configparser; python_version<"3.0"', | ||
| 'future>=0.14.0; python_version<"3"', | ||
| 'backports.functools_lru_cache; python_version<"3.2"', | ||
| 'jedi>=0.17.0,<0.18.0', | ||
| 'python-jsonrpc-server>=0.4.0', | ||
| 'pluggy'] | ||
| if sys.version_info[0] == 2: | ||
| install_requires.append('ujson<=2.0.3; platform_system!="Windows"') | ||
| else: | ||
| install_requires.append('ujson>=3.0.0') | ||
| setup( | ||
@@ -34,11 +49,3 @@ name='python-language-server', | ||
| # https://packaging.python.org/en/latest/requirements.html | ||
| install_requires=[ | ||
| 'configparser; python_version<"3.0"', | ||
| 'future>=0.14.0; python_version<"3"', | ||
| 'backports.functools_lru_cache; python_version<"3.2"', | ||
| 'jedi>=0.17.0,<0.18.0', | ||
| 'python-jsonrpc-server>=0.3.2', | ||
| 'pluggy', | ||
| 'ujson<=1.35; platform_system!="Windows"' | ||
| ], | ||
| install_requires=install_requires, | ||
@@ -57,3 +64,5 @@ # List additional groups of dependencies here (e.g. development | ||
| 'pyflakes>=2.2.0,<2.3.0', | ||
| 'pylint', | ||
| # pylint >= 2.5.0 is required for working through stdin and only | ||
| # available with python3 | ||
| 'pylint>=2.5.0' if sys.version_info.major >= 3 else 'pylint', | ||
| 'rope>=0.10.5', | ||
@@ -68,8 +77,10 @@ 'yapf', | ||
| 'pyflakes': ['pyflakes>=2.2.0,<2.3.0'], | ||
| 'pylint': ['pylint'], | ||
| 'pylint': [ | ||
| 'pylint>=2.5.0' if sys.version_info.major >= 3 else 'pylint'], | ||
| 'rope': ['rope>0.10.5'], | ||
| 'yapf': ['yapf'], | ||
| 'test': ['versioneer', 'pylint', 'pytest', 'mock', 'pytest-cov', | ||
| 'coverage', 'numpy', 'pandas', 'matplotlib', | ||
| 'pyqt5;python_version>="3"'], | ||
| 'test': ['versioneer', | ||
| 'pylint>=2.5.0' if sys.version_info.major >= 3 else 'pylint', | ||
| 'pytest', 'mock', 'pytest-cov', 'coverage', 'numpy', 'pandas', | ||
| 'matplotlib', 'pyqt5;python_version>="3"', 'flaky'], | ||
| }, | ||
@@ -76,0 +87,0 @@ |
@@ -6,3 +6,3 @@ # Copyright 2018 Google LLC. | ||
| from test import py2_only, py3_only | ||
| from test import py2_only, py3_only, IS_PY3 | ||
| from pyls import lsp, uris | ||
@@ -53,3 +53,17 @@ from pyls.workspace import Document | ||
| if IS_PY3: | ||
| # test running pylint in stdin | ||
| config.plugin_settings('pylint')['executable'] = 'pylint' | ||
| diags = pylint_lint.pyls_lint(config, doc, True) | ||
| msg = 'Unused import sys (unused-import)' | ||
| unused_import = [d for d in diags if d['message'] == msg][0] | ||
| assert unused_import['range']['start'] == { | ||
| 'line': 0, | ||
| 'character': 0, | ||
| } | ||
| assert unused_import['severity'] == lsp.DiagnosticSeverity.Warning | ||
| @py3_only | ||
@@ -65,3 +79,12 @@ def test_syntax_error_pylint_py3(config, workspace): | ||
| # test running pylint in stdin | ||
| config.plugin_settings('pylint')['executable'] = 'pylint' | ||
| diag = pylint_lint.pyls_lint(config, doc, True)[0] | ||
| assert diag['message'].startswith('invalid syntax') | ||
| # Pylint doesn't give column numbers for invalid syntax. | ||
| assert diag['range']['start'] == {'line': 0, 'character': 12} | ||
| assert diag['severity'] == lsp.DiagnosticSeverity.Error | ||
| @py2_only | ||
@@ -68,0 +91,0 @@ def test_syntax_error_pylint_py2(config, workspace): |
@@ -71,3 +71,3 @@ # Copyright 2017 Palantir Technologies, Inc. | ||
| position = {'line': 4, 'character': 7} | ||
| doc2_uri = uris.from_fs_path(os.path.join(tmp_workspace.root_path, DOC2_NAME)) | ||
| doc2_uri = uris.from_fs_path(os.path.join(str(tmp_workspace.root_path), DOC2_NAME)) | ||
| doc2 = Document(doc2_uri, tmp_workspace) | ||
@@ -74,0 +74,0 @@ |
@@ -5,5 +5,5 @@ # Copyright 2017 Palantir Technologies, Inc. | ||
| import multiprocessing | ||
| import sys | ||
| from threading import Thread | ||
| from test import unix_only | ||
| from pyls_jsonrpc.exceptions import JsonRpcMethodNotFound | ||
@@ -15,2 +15,4 @@ import pytest | ||
| CALL_TIMEOUT = 10 | ||
| PY2 = sys.version_info[0] == 2 | ||
| PY3 = sys.version_info[0] == 3 | ||
@@ -30,3 +32,9 @@ | ||
| ParallelKind = multiprocessing.Process if os.name != 'nt' else Thread | ||
| if os.name == 'nt': | ||
| ParallelKind = Thread | ||
| else: | ||
| if sys.version_info[:2] >= (3, 8): | ||
| ParallelKind = multiprocessing.get_context("fork").Process # pylint: disable=no-member | ||
| else: | ||
| ParallelKind = multiprocessing.Process | ||
@@ -79,3 +87,4 @@ self.process = ParallelKind(target=start_io_lang_server, args=( | ||
| @unix_only | ||
| @pytest.mark.skipif(os.name == 'nt' or (sys.platform.startswith('linux') and PY3), | ||
| reason='Skipped on win and fails on linux >=3.6') | ||
| def test_exit_with_parent_process_died(client_exited_server): # pylint: disable=redefined-outer-name | ||
@@ -96,2 +105,4 @@ # language server should have already exited before responding | ||
| @pytest.mark.skipif(sys.platform.startswith('linux') and PY3, | ||
| reason='Fails on linux and py3') | ||
| def test_not_exit_without_check_parent_process_flag(client_server): # pylint: disable=redefined-outer-name | ||
@@ -106,4 +117,5 @@ response = client_server._endpoint.request('initialize', { | ||
| @pytest.mark.skipif(bool(os.environ.get('CI')), reason='This test is hanging on CI') | ||
| def test_missing_message(client_server): # pylint: disable=redefined-outer-name | ||
| with pytest.raises(JsonRpcMethodNotFound): | ||
| client_server._endpoint.request('unknown_method').result(timeout=CALL_TIMEOUT) |
@@ -5,2 +5,3 @@ # Copyright 2017 Palantir Technologies, Inc. | ||
| import mock | ||
| from flaky import flaky | ||
@@ -10,2 +11,3 @@ from pyls import _utils | ||
| @flaky | ||
| def test_debounce(): | ||
@@ -34,2 +36,3 @@ interval = 0.1 | ||
| @flaky | ||
| def test_debounce_keyed_by(): | ||
@@ -36,0 +39,0 @@ interval = 0.1 |
@@ -202,2 +202,3 @@ # Copyright 2017 Palantir Technologies, Inc. | ||
| @pytest.mark.skipif(os.name == 'nt', reason="Fails on Windows") | ||
| def test_workspace_loads_pycodestyle_config(pyls, tmpdir): | ||
@@ -204,0 +205,0 @@ workspace1_dir = tmpdir.mkdir('Test123') |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
294455
2.65%6352
2.62%