8000 Support pydocstyle configuration (#302) · python-lsp/python-lsp-server@9254d5f · GitHub
[go: up one dir, main page]

Skip to content

Commit 9254d5f

Browse files
authored
Support pydocstyle configuration (#302)
1 parent e219594 commit 9254d5f

File tree

3 files changed

+109
-10
lines changed

3 files changed

+109
-10
lines changed

pyls/plugins/pydocstyle_lint.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Copyright 2017 Palantir Technologies, Inc.
10000
22
import contextlib
33
import logging
4+
import os
5+
import re
46
import sys
57

68
import pydocstyle
@@ -12,6 +14,9 @@
1214
pydocstyle_logger = logging.getLogger(pydocstyle.utils.__name__)
1315
pydocstyle_logger.setLevel(logging.INFO)
1416

17+
DEFAULT_MATCH_RE = pydocstyle.config.ConfigurationParser.DEFAULT_MATCH_RE
18+
DEFAULT_MATCH_DIR_RE = pydocstyle.config.ConfigurationParser.DEFAULT_MATCH_DIR_RE
19+
1520

1621
@hookimpl
1722
def pyls_settings():
@@ -20,10 +25,39 @@ def pyls_settings():
2025

2126

2227
@hookimpl
23-
def pyls_lint(document):
24-
conf = pydocstyle.config.ConfigurationParser()
28+
def pyls_lint(config, document):
29+
settings = config.plugin_settings('pydocstyle')
30+
log.debug("Got pydocstyle settings: %s", settings)
31+
32+
# Explicitly passing a path to pydocstyle means it doesn't respect the --match flag, so do it ourselves
33+
filename_match_re = re.compile(settings.get('match', DEFAULT_MATCH_RE) + '$')
34+
if not filename_match_re.match(os.path.basename(document.path)):
35+
return []
36+
37+
# Likewise with --match-dir
38+
dir_match_re = re.compile(settings.get('matchDir', DEFAULT_MATCH_DIR_RE) + '$')
39+
if not dir_match_re.match(os.path.basename(os.path.dirname(document.path))):
40+
return []
41+
42+
args = [document.path]
2543

26-
with _patch_sys_argv([document.path]):
44+
if settings.get('convention'):
45+
args.append('--convention=' + settings['convention'])
46+
47+
if settings.get('addSelect'):
48+
args.append('--add-select=' + ','.join(settings['addSelect']))
49+
if settings.get('addIgnore'):
50+
args.append('--add-ignore=' + ','.join(settings['addIgnore']))
51+
52+
elif settings.get('select'):
53+
args.append('--select=' + ','.join(settings['select']))
54+
elif settings.get('ignore'):
55+
args.append('--ignore=' + ','.join(settings['ignore']))
56+
57+
log.info("Using pydocstyle args: %s", args)
58+
59+
conf = pydocstyle.config.ConfigurationParser()
60+
with _patch_sys_argv(args):
2761
# TODO(gatesn): We can add more pydocstyle args here from our pyls config
2862
conf.parse()
2963

test/plugins/test_pydocstyle_lint.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
# Copyright 2017 Palantir Technologies, Inc.
2+
import os
23
from pyls import lsp, uris
34
from pyls.workspace import Document
45
from pyls.plugins import pydocstyle_lint
56

6-
DOC_URI = uris.from_fs_path(__file__)
7+
DOC_URI = uris.from_fs_path(os.path.join(os.path.dirname(__file__), "pydocstyle.py"))
8+
TEST_DOC_URI = uris.from_fs_path(__file__)
9+
710
DOC = """import sys
811
912
def hello():
@@ -13,9 +16,9 @@ def hello():
1316
"""
1417

1518

16-
def test_pydocstyle():
19+
def test_pydocstyle(config):
1720
doc = Document(DOC_URI, DOC)
18-
diags = pydocstyle_lint.pyls_lint(doc)
21+
diags = pydocstyle_lint.pyls_lint(config, doc)
1922

2023
assert all([d['source'] == 'pydocstyle' for d in diags])
2124

@@ -32,15 +35,22 @@ def test_pydocstyle():
3235
}
3336

3437

35-
def test_pydocstyle_empty_source():
38+
def test_pydocstyle_test_document(config):
39+
# The default --match argument excludes test_* documents.
40+
doc = Document(TEST_DOC_URI, "")
41+
diags = pydocstyle_lint.pyls_lint(config, doc)
42+
assert not diags
43+
44+
45+
def test_pydocstyle_empty_source(config):
3646
doc = Document(DOC_URI, "")
37-
diags = pydocstyle_lint.pyls_lint(doc)
47+
diags = pydocstyle_lint.pyls_lint(config, doc)
3848
assert diags[0]['message'] == 'D100: Missing docstring in public module'
3949
assert len(diags) == 1
4050

4151

42-
def test_pydocstyle_invalid_source():
52+
def test_pydocstyle_invalid_source(config):
4353
doc = Document(DOC_URI, "bad syntax")
44-
diags = pydocstyle_lint.pyls_lint(doc)
54+
diags = pydocstyle_lint.pyls_lint(config, doc)
4555
# We're unable to parse the file, so can't get any pydocstyle diagnostics
4656
assert not diags

vscode-client/package.json

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,61 @@
131131
"default": false,
132132
"description": "Enable or disable the plugin."
133133
},
134+
"pyls.plugins.pydocstyle.convention": {
135+
"type": "string",
136+
"default": null,
137+
"enum": [
138+
"pep257",
139+
"numpy"
140+
],
141+
"description": "Choose the basic list of checked errors by specifying an existing convention."
142+
},
143+
"pyls.plugins.pydocstyle.addIgnore": {
144+
"type": "array",
145+
"default": null,
146+
"items": {
147+
"type": "string"
148+
},
149+
"uniqueItems": true,
150+
"description": "Ignore errors and warnings in addition to the specified convention."
151+
},
152+
"pyls.plugins.pydocstyle.addSelect": {
153+
"type": "array",
154+
"default": null,
155+
"items": {
156+
"type": "string"
157+
},
158+
"uniqueItems": true,
159+
"description": "Select errors and warnings in addition to the specified convention."
160+
},
161+
"pyls.plugins.pydocstyle.ignore": {
162+
"type": "array",
163+
"default": null,
164+
"items": {
165+
"type": "string"
166+
},
167+
"uniqueItems": true,
168+
"description": "Ignore errors and warnings"
169+
},
170+
"pyls.plugins.pydocstyle.select": {
171+
"type": "array",
172+
"default": null,
173+
"items": {
174+
"type": "string"
175+
},
176+
"uniqueItems": true,
177+
"description": "Select errors and warnings"
178+
},
179+
"pyls.plugins.pydocstyle.match": {
180+
"type": "string",
181+
"default": "(?!test_).*\\.py",
182+
"description": "Check only files that exactly match the given regular expression; default is to match files that don't start with 'test_' but end with '.py'."
183+
},
184+
"pyls.plugins.pydocstyle.matchDir": {
185+
"type": "string",
186+
"default": "[^\\.].*",
187+
"description": "Search only dirs that exactly match the given regular expression; default is to match dirs which do not begin with a dot."
188+
},
134189
"pyls.plugins.pyflakes.enabled": {
135190
"type": "boolean",
136191
"default": true,

0 commit comments

Comments
 (0)
0