From 4424a5a507c7721f7eacd4d1e2fb6238d3955523 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Sat, 26 Mar 2022 15:56:10 -0500 Subject: [PATCH 1/2] Fix Yapf formatting with CRLF line endings Also add a test for CRLF eols with Autopep8 --- pylsp/plugins/yapf_format.py | 14 +++++++------- test/plugins/test_autopep8_format.py | 9 ++++++--- test/plugins/test_yapf_format.py | 9 ++++++--- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/pylsp/plugins/yapf_format.py b/pylsp/plugins/yapf_format.py index 1c90f965..7c477816 100644 --- a/pylsp/plugins/yapf_format.py +++ b/pylsp/plugins/yapf_format.py @@ -37,14 +37,14 @@ def pylsp_format_range(document, range): # pylint: disable=redefined-builtin def _format(document, lines=None): - # Yapf doesn't work with CR line endings, so we replace them by '\n' + # Yapf doesn't work with CRLF/CR line endings, so we replace them by '\n' # and restore them below. - replace_cr = False + replace_eols = False source = document.source eol_chars = get_eol_chars(source) - if eol_chars == '\r': - replace_cr = True - source = source.replace('\r', '\n') + if eol_chars in ['\r', '\r\n']: + replace_eols = True + source = source.replace(eol_chars, '\n') new_source, changed = FormatCode( source, @@ -58,8 +58,8 @@ def _format(document, lines=None): if not changed: return [] - if replace_cr: - new_source = new_source.replace('\n', '\r') + if replace_eols: + new_source = new_source.replace('\n', eol_chars) # I'm too lazy at the moment to parse diffs into TextEdit items # So let's just return the entire file... diff --git a/test/plugins/test_autopep8_format.py b/test/plugins/test_autopep8_format.py index 1e790aaa..bb5bc31b 100644 --- a/test/plugins/test_autopep8_format.py +++ b/test/plugins/test_autopep8_format.py @@ -1,6 +1,8 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. +import pytest + from pylsp import uris from pylsp.plugins.autopep8_format import pylsp_format_document, pylsp_format_range from pylsp.workspace import Document @@ -73,8 +75,9 @@ def test_hanging_indentation(config, workspace): assert res[0]['newText'] == CORRECT_INDENTED_DOC -def test_cr_line_endings(config, workspace): - doc = Document(DOC_URI, workspace, 'import os;import sys\r\rdict(a=1)') +@pytest.mark.parametrize('newline', ['\r\n', '\r']) +def test_line_endings(config, workspace, newline): + doc = Document(DOC_URI, workspace, f'import os;import sys{2 * newline}dict(a=1)') res = pylsp_format_document(config, doc) - assert res[0]['newText'] == 'import os\rimport sys\r\rdict(a=1)\r' + assert res[0]['newText'] == f'import os{newline}import sys{2 * newline}dict(a=1){newline}' diff --git a/test/plugins/test_yapf_format.py b/test/plugins/test_yapf_format.py index 4346985c..94f619e8 100644 --- a/test/plugins/test_yapf_format.py +++ b/test/plugins/test_yapf_format.py @@ -1,6 +1,8 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. +import pytest + from pylsp import uris from pylsp.plugins.yapf_format import pylsp_format_document, pylsp_format_range from pylsp.workspace import Document @@ -60,8 +62,9 @@ def test_config_file(tmpdir, workspace): assert pylsp_format_document(doc)[0]['newText'] == "A = [\n 'h', 'w',\n 'a'\n]\n\nB = ['h', 'w']\n" -def test_cr_line_endings(workspace): - doc = Document(DOC_URI, workspace, 'import os;import sys\r\rdict(a=1)') +@pytest.mark.parametrize('newline', ['\r\n', '\r']) +def test_line_endings(workspace, newline): + doc = Document(DOC_URI, workspace, f'import os;import sys{2 * newline}dict(a=1)') res = pylsp_format_document(doc) - assert res[0]['newText'] == 'import os\rimport sys\r\rdict(a=1)\r' + assert res[0]['newText'] == f'import os{newline}import sys{2 * newline}dict(a=1){newline}' From a38339494cb9d37c20a4df9c90503e9e49570bd2 Mon Sep 17 00:00:00 2001 From: Carlos Cordoba Date: Sat, 26 Mar 2022 16:05:27 -0500 Subject: [PATCH 2/2] Fix lint issues --- pylsp/plugins/flake8_lint.py | 2 +- pylsp/plugins/pylint_lint.py | 2 +- test/plugins/test_flake8_lint.py | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pylsp/plugins/flake8_lint.py b/pylsp/plugins/flake8_lint.py index 9617e372..3707222f 100644 --- a/pylsp/plugins/flake8_lint.py +++ b/pylsp/plugins/flake8_lint.py @@ -81,7 +81,7 @@ def run_flake8(flake8_executable, args, document): try: cmd = [flake8_executable] cmd.extend(args) - p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) # pylint: disable=consider-using-with + p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) except IOError: log.debug("Can't execute %s. Trying with '%s -m flake8'", flake8_executable, sys.executable) cmd = [sys.executable, '-m', 'flake8'] diff --git a/pylsp/plugins/pylint_lint.py b/pylsp/plugins/pylint_lint.py index cbbf01da..d974a2f8 100644 --- a/pylsp/plugins/pylint_lint.py +++ b/pylsp/plugins/pylint_lint.py @@ -246,7 +246,7 @@ def _run_pylint_stdio(pylint_executable, document, flags): cmd = [pylint_executable] cmd.extend(flags) cmd.extend(['--from-stdin', document.path]) - p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) # pylint: disable=consider-using-with + 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'] diff --git a/test/plugins/test_flake8_lint.py b/test/plugins/test_flake8_lint.py index e82a2268..59a776a1 100644 --- a/test/plugins/test_flake8_lint.py +++ b/test/plugins/test_flake8_lint.py @@ -43,8 +43,8 @@ def test_flake8_unsaved(workspace): def test_flake8_lint(workspace): + name, doc = temp_document(DOC, workspace) try: - name, doc = temp_document(DOC, workspace) diags = flake8_lint.pylsp_lint(workspace, doc) msg = 'F841 local variable \'a\' is assigned to but never used' unused_var = [d for d in diags if d['message'] == msg][0] @@ -54,7 +54,6 @@ def test_flake8_lint(workspace): assert unused_var['range']['start'] == {'line': 5, 'character': 1} assert unused_var['range']['end'] == {'line': 5, 'character': 11} assert unused_var['severity'] == lsp.DiagnosticSeverity.Warning - finally: os.remove(name)