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

Commit

Permalink
Merge remote-tracking branch 'PyCQA/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Nurdok committed Apr 2, 2016
2 parents 41b6cdb + c3cd2dc commit dbf8d5f
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 18 deletions.
3 changes: 2 additions & 1 deletion docs/error_codes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ Not all error codes are checked for by default. The default behavior is to
check only error codes that are part of the `PEP257
<http://www.python.org/dev/peps/pep-0257/>`_ official convention.

All of the above error codes are checked for by default except for D203.
All of the above error codes are checked for by default except for D203,
D212 and D213.
10 changes: 10 additions & 0 deletions docs/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ Release Notes
**pydocstyle** version numbers follow the
`Semantic Versioning <http://semver.org/>`_ specification.

Current Development Version
---------------------------

* Added the optional error codes D212 and D213, for checking whether
the summary of a multi-line docstring starts at the first line,
respectively at the second line (#174).

* The error code D300 is now also being reported if a docstring has
uppercase literals (``R`` or ``U``) as prefix (#176).

1.0.0 - January 30th, 2016
--------------------------

Expand Down
51 changes: 41 additions & 10 deletions src/pydocstyle.py
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,10 @@ def to_rst(cls):
'docstring text')
D211 = D2xx.create_error('D211', 'No blank lines allowed before class '
'docstring', 'found %s')
D212 = D2xx.create_error('D212', 'Multi-line docstring summary should start '
'at the first line')
D213 = D2xx.create_error('D213', 'Multi-line docstring summary should start '
'at the second line')

D3xx = ErrorRegistry.create_group('D3', 'Quotes Issues')
D300 = D3xx.create_error('D300', 'Use """triple double quotes"""',
Expand All @@ -707,7 +711,8 @@ def __getattr__(self, item):


conventions = AttrDict({
'pep257': set(ErrorRegistry.get_error_codes()) - set(['D203']),
'pep257': set(ErrorRegistry.get_error_codes()) - set(['D203', 'D212',
'D213'])
})


Expand Down Expand Up @@ -1541,6 +1546,30 @@ def check_surrounding_whitespaces(self, definition, docstring):
len(lines) == 1 and lines[0].endswith(' '):
return D210()

@check_for(Definition)
def check_multi_line_summary_start(self, definition, docstring):
"""D21{2,3}: Multi-line docstring summary style check.
A multi-line docstring summary should start either at the first,
or separately at the second line of a docstring.
"""
if docstring:
start_triple = [
'"""', "'''",
'u"""', "u'''",
'r"""', "r'''",
'ur"""', "ur'''"
]

lines = ast.literal_eval(docstring).split('\n')
if len(lines) > 1:
first = docstring.split("\n")[0].strip().lower()
if first in start_triple:
return D212()
else:
return D213()

@check_for(Definition)
def check_triple_double_quotes(self, definition, docstring):
r'''D300: Use """triple double quotes""".
Expand All @@ -1554,15 +1583,17 @@ def check_triple_double_quotes(self, definition, docstring):
""" quotes in its body.
'''
if (docstring and '"""' in ast.literal_eval(docstring) and
docstring.startswith(("'''", "r'''", "u'''", "ur'''"))):
# Allow ''' quotes if docstring contains """, because otherwise """
# quotes could not be expressed inside docstring. Not in PEP 257.
return
if docstring and not docstring.startswith(
('"""', 'r"""', 'u"""', 'ur"""')):
quotes = "'''" if "'''" in docstring[:4] else "'"
return D300(quotes)
if docstring:
opening = docstring[:5].lower()
if '"""' in ast.literal_eval(docstring) and opening.startswith(
("'''", "r'''", "u'''", "ur'''")):
# Allow ''' quotes if docstring contains """, because
# otherwise """ quotes could not be expressed inside
# docstring. Not in PEP 257.
return
if not opening.startswith(('"""', 'r"""', 'u"""', 'ur"""')):
quotes = "'''" if "'''" in opening else "'"
return D300(quotes)

@check_for(Definition)
def check_backslashes(self, definition, docstring):
Expand Down
136 changes: 136 additions & 0 deletions src/tests/test_cases/multi_line_summary_start.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
"""Module to check different multi-line docstring flavors."""

from .expected import Expectation

expectation = Expectation()
expect = expectation.expect

_D212 = 'D212: Multi-line docstring summary should start at the first line'
_D213 = 'D213: Multi-line docstring summary should start at the second line'

_D300 = 'D300: Use """triple double quotes""" (found \'\'\'-quotes)'
_D301 = 'D301: Use r""" if any backslashes in a docstring'


@expect(_D212)
def multi_line_starts_second_line():
"""
Summary.
Description.
"""


@expect(_D212)
@expect(_D300)
def multi_line_starts_second_line_single_quote():
'''
Summary.
Description.
'''


@expect(_D212)
def multi_line_starts_second_line_raw():
r"""
Summary.
Description with \backslash\.
"""


@expect(_D212)
@expect(_D301)
def multi_line_starts_second_line_upper_raw():
R"""
Summary.
Description with \backslash\.
"""


@expect(_D212)
@expect(_D300)
def multi_line_starts_second_line_raw_single_quote():
r'''
Summary.
Description with \backslash\.
'''


@expect(_D212)
@expect(_D300)
@expect(_D301)
def multi_line_starts_second_line_upper_raw_single_quote():
R'''
Summary.
Description with \backslash\.
'''


@expect(_D213)
def multi_line_starts_first_line():
"""Summary.
Description.
"""


@expect(_D213)
@expect(_D300)
def multi_line_starts_first_line_single_quote():
'''Summary.
Description.
'''


@expect(_D213)
def multi_line_starts_first_line_raw():
r"""Summary.
Description with \backslash\.
"""


@expect(_D213)
@expect(_D301)
def multi_line_starts_first_line_upper_raw():
R"""Summary.
Description with \backslash\.
"""


@expect(_D213)
@expect(_D300)
def multi_line_starts_first_line_raw_single_quote():
r'''Summary.
Description with \backslash\.
'''


@expect(_D213)
@expect(_D300)
@expect(_D301)
def multi_line_starts_first_line_upper_raw_single_quote():
R'''Summary.
Description with \backslash\.
'''

0 comments on commit dbf8d5f

Please sign in to comment.