diff --git a/README.md b/README.md index 2ba06088..53e10ebc 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ multi-line docstring **PEP 257: _The closing quotes are on the same line as the opening quotes_** -For consistency this rule also gets applied to multi-line docstrings +For consistency this rule also gets applied to multi-line docstrings. ```python # Bad @@ -112,6 +112,9 @@ of a summary line just like a one-line docstring_** Since the first line should be a phrase or summary the first character gets capitalized. +When the second line is one recurring character we consider the summary line to be a +title as used in many Sphinx documentation schemes and do not add a period. + ```python # Bad """My docstring""" @@ -127,6 +130,12 @@ My docstring """Summary. +My docstring +""" + +"""My title +=========== + My docstring """ ``` @@ -134,19 +143,28 @@ My docstring **PEP 257: _Multi-line docstrings consist of a summary line just like a one-line docstring, followed by a blank line, followed by a more elaborate description._** +When the second line is one recurring character we consider the summary line to be a +title as used in many Sphinx documentation schemes and do not add a white line. + ```python # Bad """Summary. Body.""" """Summary. - Body. - """ +Body. +""" # Good """Summary. - Body. - """ +Body. +""" + +"""My title +=========== + +My docstring +""" ``` ## Development diff --git a/pydocstringformatter/formatting/formatter.py b/pydocstringformatter/formatting/formatter.py index 966f67f8..0be72724 100644 --- a/pydocstringformatter/formatting/formatter.py +++ b/pydocstringformatter/formatting/formatter.py @@ -70,15 +70,16 @@ def _treat_string(self, tokeninfo: tokenize.TokenInfo, _: int) -> str: return tokeninfo.string[:-3] + "." + tokeninfo.string[-3:] # Handle multi-line docstrings else: - first_linebreak = tokeninfo.string.index("\n") - # If first linebreak is followed by another we're dealing with a summary - if tokeninfo.string[tokeninfo.string.index("\n") + 1] == "\n": - if tokeninfo.string[first_linebreak - 1] != ".": - return ( - tokeninfo.string[:first_linebreak] - + "." - + tokeninfo.string[first_linebreak:] - ) + lines = tokeninfo.string.splitlines() + # If second line is one recurring character we're dealing with a rst title + if (stripped := lines[1].lstrip()) and stripped.count(stripped[0]) == len( + stripped + ): + return tokeninfo.string + # If second line is empty we're dealing with a summary + if lines[1] == "": + if lines[0][-1] != ".": + return lines[0] + ".\n" + "\n".join(lines[1:]) # TODO(#26): Handle multi-line docstrings that do not have a summary # This is obviously dependent on whether 'pydocstringformatter' will # start enforcing summaries :) diff --git a/tests/data/format/final_period/function_title_docstrings.py b/tests/data/format/final_period/function_title_docstrings.py new file mode 100644 index 00000000..61b90b04 --- /dev/null +++ b/tests/data/format/final_period/function_title_docstrings.py @@ -0,0 +1,42 @@ +def func(): + def inner_func(): + """Summary + ========== + + docstring + """ + + def inner_func(): + """Summary + ---------- + + docstring + """ + + def inner_func(): + """Summary + ^^^^^^^^^^ + + docstring + """ + + def inner_func(): + """Summary + ********** + + docstring + """ + + def inner_func(): + """Summary + ^^^^^^^^^^ + + docstring + """ + + def inner_func(): + """Summary + aaaaaaaaaa + + docstring + """ diff --git a/tests/data/format/final_period/function_title_docstrings.py.out b/tests/data/format/final_period/function_title_docstrings.py.out new file mode 100644 index 00000000..61b90b04 --- /dev/null +++ b/tests/data/format/final_period/function_title_docstrings.py.out @@ -0,0 +1,42 @@ +def func(): + def inner_func(): + """Summary + ========== + + docstring + """ + + def inner_func(): + """Summary + ---------- + + docstring + """ + + def inner_func(): + """Summary + ^^^^^^^^^^ + + docstring + """ + + def inner_func(): + """Summary + ********** + + docstring + """ + + def inner_func(): + """Summary + ^^^^^^^^^^ + + docstring + """ + + def inner_func(): + """Summary + aaaaaaaaaa + + docstring + """