Skip to content

Commit 333125b

Browse files
authored
Merge pull request #4 from haplo/black
Format codebase with black
2 parents 906a3dd + ca189e0 commit 333125b

File tree

7 files changed

+102
-52
lines changed

7 files changed

+102
-52
lines changed

.github/workflows/python-package.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ jobs:
3434
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
3535
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
3636
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
37+
- name: Check black formatting
38+
run: |
39+
# stop the build if black detect any changes
40+
black --check .
3741
- name: Test with pytest
3842
run: |
3943
pytest

.pre-commit-config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# See https://pre-commit.com for more information
2+
# See https://pre-commit.com/hooks.html for more hooks
3+
repos:
4+
- repo: https://github.com/psf/black
5+
rev: 21.5b1
6+
hooks:
7+
- id: black

README.rst

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Configuration
2626

2727
``live_mode`` (default is True) provides type checking as you type. This writes to a tempfile every time a check is done.
2828

29-
Turning off live_mode means you must save your changes for mypy diagnostics to update correctly.
29+
Turning off ``live_mode`` means you must save your changes for mypy diagnostics to update correctly.
3030

3131
Depending on your editor, the configuration (found in a file called mypy-ls.cfg in your workspace or a parent directory) should be roughly like this:
3232

@@ -37,3 +37,26 @@ Depending on your editor, the configuration (found in a file called mypy-ls.cfg
3737
"live_mode": True,
3838
"strict": False
3939
}
40+
41+
Developing
42+
-------------
43+
44+
Install development dependencies with (you might want to create a virtualenv first):
45+
46+
::
47+
48+
pip install -r requirements.txt
49+
50+
The project is formatted with `black`_. You can either configure your IDE to automatically format code with it, run it manually (``black .``) or rely on pre-commit (see below) to format files on git commit.
51+
52+
This project uses `pre-commit`_ to enforce code-quality. After cloning the repository install the pre-commit hooks with:
53+
54+
::
55+
56+
pre-commit install
57+
58+
After that pre-commit will run `all defined hooks`_ on every ``git commit`` and keep you from committing if there are any errors.
59+
60+
.. _black: https://github.com/psf/black
61+
.. _pre-commit: https://pre-commit.com/
62+
.. _all defined hooks: .pre-commit-config.yaml

mypy_ls/plugin.py

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
tmpFile: Optional[IO[str]] = None
2828

2929

30-
def parse_line(line: str, document: Optional[Document] = None) -> Optional[Dict[str, Any]]:
30+
def parse_line(
31+
line: str, document: Optional[Document] = None
32+
) -> Optional[Dict[str, Any]]:
3133
"""
3234
Return a language-server diagnostic from a line of the Mypy error report.
3335
@@ -54,42 +56,44 @@ def parse_line(line: str, document: Optional[Document] = None) -> Optional[Dict[
5456
if file_path != "<string>": # live mode
5557
# results from other files can be included, but we cannot return
5658
# them.
57-
if document and document.path and not document.path.endswith(
58-
file_path):
59-
log.warning("discarding result for %s against %s", file_path,
60-
document.path)
59+
if document and document.path and not document.path.endswith(file_path):
60+
log.warning(
61+
"discarding result for %s against %s", file_path, document.path
62+
)
6163
return None
6264

6365
lineno = int(linenoStr or 1) - 1 # 0-based line number
6466
offset = int(offsetStr or 1) - 1 # 0-based offset
6567
errno = 2
66-
if severity == 'error':
68+
if severity == "error":
6769
errno = 1
6870
diag: Dict[str, Any] = {
69-
'source': 'mypy',
70-
'range': {
71-
'start': {'line': lineno, 'character': offset},
71+
"source": "mypy",
72+
"range": {
73+
"start": {"line": lineno, "character": offset},
7274
# There may be a better solution, but mypy does not provide end
73-
'end': {'line': lineno, 'character': offset + 1}
75+
"end": {"line": lineno, "character": offset + 1},
7476
},
75-
'message': msg,
76-
'severity': errno
77+
"message": msg,
78+
"severity": errno,
7779
}
7880
if document:
7981
# although mypy does not provide the end of the affected range, we
8082
# can make a good guess by highlighting the word that Mypy flagged
81-
word = document.word_at_position(diag['range']['start'])
83+
word = document.word_at_position(diag["range"]["start"])
8284
if word:
83-
diag['range']['end']['character'] = (
84-
diag['range']['start']['character'] + len(word))
85+
diag["range"]["end"]["character"] = diag["range"]["start"][
86+
"character"
87+
] + len(word)
8588

8689
return diag
8790
return None
8891

8992

9093
@hookimpl
91-
def pylsp_lint(config: Config, workspace: Workspace, document: Document,
92-
is_saved: bool) -> List[Dict[str, Any]]:
94+
def pylsp_lint(
95+
config: Config, workspace: Workspace, document: Document, is_saved: bool
96+
) -> List[Dict[str, Any]]:
9397
"""
9498
Lints.
9599
@@ -110,27 +114,25 @@ def pylsp_lint(config: Config, workspace: Workspace, document: Document,
110114
List of the linting data.
111115
112116
"""
113-
settings = config.plugin_settings('mypy-ls')
114-
live_mode = settings.get('live_mode', True)
115-
args = ['--incremental',
116-
'--show-column-numbers',
117-
'--follow-imports', 'silent']
117+
settings = config.plugin_settings("mypy-ls")
118+
live_mode = settings.get("live_mode", True)
119+
args = ["--incremental", "--show-column-numbers", "--follow-imports", "silent"]
118120

119121
global tmpFile
120122
if live_mode and not is_saved and tmpFile:
121123
tmpFile = open(tmpFile.name, "w")
122124
tmpFile.write(document.source)
123125
tmpFile.close()
124-
args.extend(['--shadow-file', document.path, tmpFile.name])
126+
args.extend(["--shadow-file", document.path, tmpFile.name])
125127
elif not is_saved:
126128
return []
127129

128130
if mypyConfigFile:
129-
args.append('--config-file')
131+
args.append("--config-file")
130132
args.append(mypyConfigFile)
131133
args.append(document.path)
132-
if settings.get('strict', False):
133-
args.append('--strict')
134+
if settings.get("strict", False):
135+
args.append("--strict")
134136

135137
report, errors, _ = mypy_api.run(args)
136138

@@ -187,10 +189,11 @@ def init(workspace: str) -> Dict[str, str]:
187189
configuration = eval(file.read())
188190
global mypyConfigFile
189191
mypyConfigFile = findConfigFile(workspace, "mypy.ini")
190-
if (("enabled" not in configuration or configuration["enabled"])
191-
and ("live_mode" not in configuration or configuration["live_mode"])):
192+
if ("enabled" not in configuration or configuration["enabled"]) and (
193+
"live_mode" not in configuration or configuration["live_mode"]
194+
):
192195
global tmpFile
193-
tmpFile = tempfile.NamedTemporaryFile('w', delete=False)
196+
tmpFile = tempfile.NamedTemporaryFile("w", delete=False)
194197
tmpFile.close()
195198
return configuration
196199

pyproject.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[tool.black]
2+
line-length = 90
3+
include = '\.pyi?$'
4+
exclude = '''
5+
/(
6+
\.git
7+
| \.mypy_cache
8+
| \.tox
9+
| \.venv
10+
| _build
11+
| build
12+
| dist
13+
)/
14+
'''

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
python-lsp-server
22
mypy
3+
black
4+
pre-commit

test/test_plugin.py

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@
1212
TYPE_ERR_MSG = '"Dict[<nothing>, <nothing>]" has no attribute "append"'
1313

1414
TEST_LINE = 'test_plugin.py:279:8: error: "Request" has no attribute "id"'
15-
TEST_LINE_WITHOUT_COL = ('test_plugin.py:279: '
16-
'error: "Request" has no attribute "id"')
17-
TEST_LINE_WITHOUT_LINE = ('test_plugin.py: '
18-
'error: "Request" has no attribute "id"')
15+
TEST_LINE_WITHOUT_COL = "test_plugin.py:279: " 'error: "Request" has no attribute "id"'
16+
TEST_LINE_WITHOUT_LINE = "test_plugin.py: " 'error: "Request" has no attribute "id"'
1917

2018

2119
@pytest.fixture
@@ -27,7 +25,6 @@ def workspace(tmpdir):
2725

2826

2927
class FakeConfig(object):
30-
3128
def __init__(self):
3229
self._root_path = "C:"
3330

@@ -50,40 +47,40 @@ def test_plugin(workspace):
5047

5148
assert len(diags) == 1
5249
diag = diags[0]
53-
assert diag['message'] == TYPE_ERR_MSG
54-
assert diag['range']['start'] == {'line': 0, 'character': 0}
55-
assert diag['range']['end'] == {'line': 0, 'character': 1}
50+
assert diag["message"] == TYPE_ERR_MSG
51+
assert diag["range"]["start"] == {"line": 0, "character": 0}
52+
assert diag["range"]["end"] == {"line": 0, "character": 1}
5653

5754

5855
def test_parse_full_line(workspace):
5956
doc = Document(DOC_URI, workspace)
6057
diag = plugin.parse_line(TEST_LINE, doc)
61-
assert diag['message'] == '"Request" has no attribute "id"'
62-
assert diag['range']['start'] == {'line': 278, 'character': 7}
63-
assert diag['range']['end'] == {'line': 278, 'character': 8}
58+
assert diag["message"] == '"Request" has no attribute "id"'
59+
assert diag["range"]["start"] == {"line": 278, "character": 7}
60+
assert diag["range"]["end"] == {"line": 278, "character": 8}
6461

6562

6663
def test_parse_line_without_col(workspace):
6764
doc = Document(DOC_URI, workspace)
6865
diag = plugin.parse_line(TEST_LINE_WITHOUT_COL, doc)
69-
assert diag['message'] == '"Request" has no attribute "id"'
70-
assert diag['range']['start'] == {'line': 278, 'character': 0}
71-
assert diag['range']['end'] == {'line': 278, 'character': 1}
66+
assert diag["message"] == '"Request" has no attribute "id"'
67+
assert diag["range"]["start"] == {"line": 278, "character": 0}
68+
assert diag["range"]["end"] == {"line": 278, "character": 1}
7269

7370

7471
def test_parse_line_without_line(workspace):
7572
doc = Document(DOC_URI, workspace)
7673
diag = plugin.parse_line(TEST_LINE_WITHOUT_LINE, doc)
77-
assert diag['message'] == '"Request" has no attribute "id"'
78-
assert diag['range']['start'] == {'line': 0, 'character': 0}
79-
assert diag['range']['end'] == {'line': 0, 'character': 6}
74+
assert diag["message"] == '"Request" has no attribute "id"'
75+
assert diag["range"]["start"] == {"line": 0, "character": 0}
76+
assert diag["range"]["end"] == {"line": 0, "character": 6}
8077

8178

82-
@pytest.mark.parametrize('word,bounds', [('', (7, 8)), ('my_var', (7, 13))])
79+
@pytest.mark.parametrize("word,bounds", [("", (7, 8)), ("my_var", (7, 13))])
8380
def test_parse_line_with_context(monkeypatch, word, bounds, workspace):
8481
doc = Document(DOC_URI, workspace)
85-
monkeypatch.setattr(Document, 'word_at_position', lambda *args: word)
82+
monkeypatch.setattr(Document, "word_at_position", lambda *args: word)
8683
diag = plugin.parse_line(TEST_LINE, doc)
87-
assert diag['message'] == '"Request" has no attribute "id"'
88-
assert diag['range']['start'] == {'line': 278, 'character': bounds[0]}
89-
assert diag['range']['end'] == {'line': 278, 'character': bounds[1]}
84+
assert diag["message"] == '"Request" has no attribute "id"'
85+
assert diag["range"]["start"] == {"line": 278, "character": bounds[0]}
86+
assert diag["range"]["end"] == {"line": 278, "character": bounds[1]}

0 commit comments

Comments
 (0)