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

Commit 2dfbb38

Browse files
bsamsethCielquansambhav
authored
Bugfix: Allow comments before module docstring noqa codes (#446)
* Allow comments before module docstring noqa codes * Add a note to the release notes * Break after first `noqa` is encountered The behavior is now the same as on master. * added integration tests for comment files * fixed docstring in test_comment_plus_docstring_file * added integration tests with noqa Co-authored-by: Cielquan <[email protected]> Co-authored-by: Christian Riedel <[email protected]> Co-authored-by: Sambhav Kothari <[email protected]>
1 parent dd5ab9e commit 2dfbb38

File tree

4 files changed

+84
-6
lines changed

4 files changed

+84
-6
lines changed

docs/release_notes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Bug Fixes
1818
* Fix indentation error while parsing class methods (#441).
1919
* Fix a bug in parsing Google-style argument description.
2020
The bug caused some argument names to go unreported in D417 (#448).
21+
* Fixed an issue where skipping errors on module level docstring via #noqa
22+
failed when there where more prior comments (#446).
2123

2224

2325
5.0.2 - January 8th, 2020

src/pydocstyle/parser.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -584,12 +584,20 @@ def parse_definition(self, class_):
584584
def parse_skip_comment(self):
585585
"""Parse a definition comment for noqa skips."""
586586
skipped_error_codes = ''
587-
if self.current.kind == tk.COMMENT:
588-
if 'noqa: ' in self.current.value:
589-
skipped_error_codes = ''.join(
590-
self.current.value.split('noqa: ')[1:])
591-
elif self.current.value.startswith('# noqa'):
592-
skipped_error_codes = 'all'
587+
while self.current.kind in (tk.COMMENT, tk.NEWLINE, tk.NL):
588+
if self.current.kind == tk.COMMENT:
589+
if 'noqa: ' in self.current.value:
590+
skipped_error_codes = ''.join(
591+
self.current.value.split('noqa: ')[1:])
592+
elif self.current.value.startswith('# noqa'):
593+
skipped_error_codes = 'all'
594+
self.stream.move()
595+
self.log.debug("parsing comments before docstring, token is %r (%s)",
596+
self.current.kind, self.current.value)
597+
598+
if skipped_error_codes:
599+
break
600+
593601
return skipped_error_codes
594602

595603
def check_current(self, kind=None, value=None):

src/tests/test_cases/noqa.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# -*- coding: utf-8 -*-
12
# noqa: D400,D415
23
"""Test case for "# noqa" comments"""
34
from .expected import Expectation

src/tests/test_integration.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,3 +1123,70 @@ def bar(a):
11231123
out, err, code = env.invoke(args="-v")
11241124
assert code == 0
11251125
assert "IndentationError: unexpected indent" not in err
1126+
1127+
1128+
def test_only_comment_file(env):
1129+
"""Test that file with only comments does only cause D100."""
1130+
with env.open('comments.py', 'wt') as comments:
1131+
comments.write(
1132+
'#!/usr/bin/env python3\n'
1133+
'# -*- coding: utf-8 -*-\n'
1134+
'# Useless comment\n'
1135+
'# Just another useless comment\n'
1136+
)
1137+
1138+
out, _, code = env.invoke()
1139+
assert 'D100' in out
1140+
out = out.replace('D100', '')
1141+
for err in {'D1', 'D2', 'D3', 'D4'}:
1142+
assert err not in out
1143+
assert code == 1
1144+
1145+
1146+
def test_comment_plus_docstring_file(env):
1147+
"""Test that file with comments and docstring does not cause errors."""
1148+
with env.open('comments_plus.py', 'wt') as comments_plus:
1149+
comments_plus.write(
1150+
'#!/usr/bin/env python3\n'
1151+
'# -*- coding: utf-8 -*-\n'
1152+
'# Useless comment\n'
1153+
'# Just another useless comment\n'
1154+
'"""Module docstring."""\n'
1155+
)
1156+
1157+
out, _, code = env.invoke()
1158+
assert '' == out
1159+
assert code == 0
1160+
1161+
1162+
def test_only_comment_with_noqa_file(env):
1163+
"""Test that file with noqa and only comments does not cause errors."""
1164+
with env.open('comments.py', 'wt') as comments:
1165+
comments.write(
1166+
'#!/usr/bin/env python3\n'
1167+
'# -*- coding: utf-8 -*-\n'
1168+
'# Useless comment\n'
1169+
'# Just another useless comment\n'
1170+
'# noqa: D100\n'
1171+
)
1172+
1173+
out, _, code = env.invoke()
1174+
assert 'D100' not in out
1175+
assert code == 0
1176+
1177+
1178+
def test_comment_with_noqa_plus_docstring_file(env):
1179+
"""Test that file with comments, noqa, docstring does not cause errors."""
1180+
with env.open('comments_plus.py', 'wt') as comments_plus:
1181+
comments_plus.write(
1182+
'#!/usr/bin/env python3\n'
1183+
'# -*- coding: utf-8 -*-\n'
1184+
'# Useless comment\n'
1185+
'# Just another useless comment\n'
1186+
'# noqa: D400\n'
1187+
'"""Module docstring without period"""\n'
1188+
)
1189+
1190+
out, _, code = env.invoke()
1191+
assert '' == out
1192+
assert code == 0

0 commit comments

Comments
 (0)