Skip to content
This repository was archived by the owner on Nov 3, 2023. It is now read-only.

Commit 779e247

Browse files
plinsssambhav
andauthored
Add disable_skip_errors flag to ConventionChecker API (#485)
* Add disable_skip_errors flag to ConventionChecker API Added to ConventionChecker.check_source() and ConventionChecker.check(). This allows other systems that integrate pydocstyle, such as flake8-docstyle, to request errors that are otherwise skipped due to # noqa comments. Added test for skip_errors feature in general and with this flag. Fixes #484 * Update release notes * rename argument to ignore inline noqa comments * Add docstring description of new argument * Move release note Co-authored-by: Sambhav Kothari <[email protected]>
1 parent fd3aef5 commit 779e247

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

docs/release_notes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ Release Notes
88
Current Development Version
99
---------------------------
1010

11+
New Features
12+
13+
* Add flag to disable `# noqa` comment processing in API (#485).
1114

1215
5.1.1 - August 29th, 2020
1316
---------------------------

src/pydocstyle/checker.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class ConventionChecker:
104104
".+" # Followed by 1 or more characters - which is the docstring for the parameter
105105
)
106106

107-
def check_source(self, source, filename, ignore_decorators=None):
107+
def check_source(self, source, filename, ignore_decorators=None, ignore_inline_noqa=False):
108108
module = parse(StringIO(source), filename)
109109
for definition in module:
110110
for this_check in self.checks:
@@ -114,15 +114,15 @@ def check_source(self, source, filename, ignore_decorators=None):
114114
decorator_skip = ignore_decorators is not None and any(
115115
len(ignore_decorators.findall(dec.name)) > 0
116116
for dec in definition.decorators)
117-
if not skipping_all and not decorator_skip:
117+
if (ignore_inline_noqa or not skipping_all) and not decorator_skip:
118118
error = this_check(self, definition,
119119
definition.docstring)
120120
else:
121121
error = None
122122
errors = error if hasattr(error, '__iter__') else [error]
123123
for error in errors:
124-
if error is not None and error.code not in \
125-
definition.skipped_error_codes:
124+
if error is not None and (ignore_inline_noqa or error.code not in \
125+
definition.skipped_error_codes):
126126
partition = this_check.__doc__.partition('.\n')
127127
message, _, explanation = partition
128128
error.set_context(explanation=explanation,
@@ -932,7 +932,7 @@ def check_docstring_sections(self, definition, docstring):
932932
parse = Parser()
933933

934934

935-
def check(filenames, select=None, ignore=None, ignore_decorators=None):
935+
def check(filenames, select=None, ignore=None, ignore_decorators=None, ignore_inline_noqa=False):
936936
"""Generate docstring errors that exist in `filenames` iterable.
937937
938938
By default, the PEP-257 convention is checked. To specifically define the
@@ -949,6 +949,8 @@ def check(filenames, select=None, ignore=None, ignore_decorators=None):
949949
convenience, you may use `pydocstyle.violations.conventions.pep257` as
950950
a base set to add or remove errors from.
951951
952+
`ignore_inline_noqa` controls if `# noqa` comments are respected or not.
953+
952954
Examples
953955
---------
954956
>>> check(['pydocstyle.py'])
@@ -978,7 +980,8 @@ def check(filenames, select=None, ignore=None, ignore_decorators=None):
978980
with tk.open(filename) as file:
979981
source = file.read()
980982
for error in ConventionChecker().check_source(source, filename,
981-
ignore_decorators):
983+
ignore_decorators,
984+
ignore_inline_noqa):
982985
code = getattr(error, 'code', None)
983986
if code in checked_codes:
984987
yield error

src/tests/test_integration.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,36 @@ def function_with_bad_docstring(foo):
190190
assert error_codes == expected_error_codes - ignored
191191

192192

193+
def test_skip_errors():
194+
"""Test that `ignore`d errors are not reported in the API."""
195+
function_to_check = textwrap.dedent('''
196+
def function_with_bad_docstring(foo): # noqa: D400, D401, D403, D415
197+
""" does spacinwithout a period in the end
198+
no blank line after one-liner is bad. Also this - """
199+
return foo
200+
''')
201+
expected_error_codes = {'D100', 'D205', 'D209', 'D210', 'D213'}
202+
mock_open = mock.mock_open(read_data=function_to_check)
203+
from pydocstyle import checker
204+
with mock.patch.object(
205+
checker.tk, 'open', mock_open, create=True):
206+
# Passing a blank ignore here explicitly otherwise
207+
# checkers takes the pep257 ignores by default.
208+
errors = tuple(checker.check(['filepath'], ignore={}))
209+
error_codes = {error.code for error in errors}
210+
assert error_codes == expected_error_codes
211+
212+
skipped_error_codes = {'D400', 'D401', 'D403', 'D415'}
213+
# We need to recreate the mock, otherwise the read file is empty
214+
mock_open = mock.mock_open(read_data=function_to_check)
215+
with mock.patch.object(
216+
checker.tk, 'open', mock_open, create=True):
217+
errors = tuple(checker.check(['filepath'], ignore={},
218+
ignore_inline_noqa=True))
219+
error_codes = {error.code for error in errors}
220+
assert error_codes == expected_error_codes | skipped_error_codes
221+
222+
193223
def test_run_as_named_module():
194224
"""Test that pydocstyle can be run as a "named module".
195225

0 commit comments

Comments
 (0)