Skip to content

Commit 1b3f03d

Browse files
authored
fix: issue 321 (#323)
* fix: adding additional blank line before inner function * fix: removing blank line between two preceding comment blocks * fix: mangling long description when splitting multi-sentence summary * fix: not detecting string constants * feat: add function to find inline reST markup * test: add tests for function to find inline reST markup * fix: fix tests that failed after updating regex's As docformatter becomes more strict in identifying patterns and handling the various patterns that are identified, some of the older tests are failing. These tests fail because the patterns in the test strings are not strictly reST, Sphinx, etc. * doc: add section discussing text patterns to usage docs * doc: add assistance section to the README * fix: use sys module to get default file encoding * fix: explicitly ignore utf_16 and utf_32 encoding
1 parent cfc666f commit 1b3f03d

File tree

21 files changed

+405
-198
lines changed

21 files changed

+405
-198
lines changed

README.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,17 @@ Do you use *docformatter*? What style docstrings do you use? Add some badges t
199199
.. image:: https://img.shields.io/badge/%20style-google-3666d6.svg
200200
:target: https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings
201201
202+
Assistance
203+
==========
204+
``docformatter`` has an IRC channel on `Libera.Chat`_ in the `#docformatter`_ room.
205+
.. _`Libera.Chat`: https://libera.chat
206+
.. _`#docformatter`: https://web.libera.chat/#docformatter
207+
208+
There is no ``docformatter`` channel on the Python Code Quality Discord server, but
209+
you can ask for help in the `# general`_ channel.
210+
211+
.. _`# general`: https://discord.com/channels/825463413634891776/934197425357336596
212+
202213
Issues
203214
======
204215

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
#
44
# For the full list of built-in configuration values, see the documentation:
55
# https://www.sphinx-doc.org/en/master/usage/configuration.html
6-
76
# -- Project information -----------------------------------------------------
87
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
98
"""Configuration file for the Sphinx documentation builder."""
109

10+
1111
project = "docformatter"
1212
copyright = "2022-2023, Steven Myint"
1313
author = "Steven Myint"

docs/source/usage.rst

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,52 @@ Use with GitHub Actions
151151
action.
152152

153153
.. _`python-lint-plus`: https://github.com/marketplace/actions/python-code-style-quality-and-lint
154+
155+
Dostring Text Patterns
156+
======================
157+
158+
``docformatter`` began as a simple tool to format docstrings to follow PEP257. It
159+
was originally a single Python script of 118 lines containing seven functions.
160+
That's no longer the case as an inspection of the codebase will show. Over time,
161+
``docformatter`` has grown to include a number of features that have been requested
162+
by its most fantastic user base.
163+
164+
In the early days, ``docformatter`` only formatted simple docstrings. "Complex" text
165+
patterns like lists, parameter descriptions, and reStructuredText (reST) sections
166+
caused ``docformatter`` to simply skip formatting the docstring. As feature requests
167+
have been and will be incorporated, ``docformatter`` has gained the ability to
168+
recognize and format more complex text patterns.
169+
170+
As a result, it is necessary for the user to properly format their docstrings to
171+
follow the patterns documented in the various specifications. These specifications
172+
would include:
173+
174+
- PEP 257 - Docstring Conventions
175+
https://www.python.org/dev/peps/pep-0257/
176+
- reStructuredText (reST) Markup Specification
177+
https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html
178+
- Sphinx Documentation Style
179+
https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html
180+
- Epydoc Documentation Style
181+
http://epydoc.sourceforge.net/manual-fields.html
182+
183+
Any docstring that does not follow these specifications may not be formatted properly
184+
as these patterns may be recognized by ``docformatter`` as simple text that needs to
185+
formatted. For example, if a user writes a docstring that contains a list but does not
186+
format the list according to reST specifications, ``docformatter`` may not recognize
187+
the list and may format the list items as simple text. This could result in a
188+
list that is not properly indented or wrapped.
189+
190+
The user is encouraged to read and follow these specifications when writing
191+
docstrings to ensure that ``docformatter`` can properly format them. Issues reported
192+
to the ``docformatter`` project that are the result of docstrings not following these
193+
specifications will be closed as ``S:wontfix`` with a request for the user to update
194+
their docstrings to follow the specifications.
195+
196+
Additionally, as ``docformatter`` continues to add support for more text patterns (e.g.,
197+
Numpy or Google style docstrings), new releases may result in significant docstring
198+
formatting changes in your code base. While we hate to see this happen to our users,
199+
it is the result of our desire to make ``docformatter`` the best tool it can be for
200+
formatting docstrings and the best way to achieve that is to strigently comply with
201+
the various specifications. We appreciate your understanding and patience as we
202+
continue to improve ``docformatter``.

src/docformatter/classify.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929

3030
# Standard Library Imports
31+
import re
3132
import sys
3233
import tokenize
3334
from tokenize import TokenInfo
@@ -289,9 +290,9 @@ def is_definition_line(token: tokenize.TokenInfo) -> bool:
289290
True if the token is a definition line, False otherwise.
290291
"""
291292
if token.type == tokenize.NAME and (
292-
token.line.strip().startswith("def ")
293-
or token.line.strip().startswith("async ")
294-
or token.line.strip().startswith("class ")
293+
token.line.startswith("def ")
294+
or token.line.startswith("async ")
295+
or token.line.startswith("class ")
295296
):
296297
return True
297298

@@ -407,14 +408,7 @@ def is_nested_definition_line(token: tokenize.TokenInfo) -> bool:
407408
bool
408409
True if the token is a nested definition line, False otherwise.
409410
"""
410-
if token.type == tokenize.NAME and (
411-
token.line.startswith(" def ")
412-
or token.line.startswith(" async ")
413-
or token.line.startswith(" class ")
414-
):
415-
return True
416-
417-
return False
411+
return re.match(r"^ {4,}(async|class|def) ", token.line) is not None
418412

419413

420414
def is_newline_continuation(

src/docformatter/constants.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,12 @@
7676
OPTION_REGEX = r"^ {0,}-{1,2}[\S ]+ \w+"
7777
"""Regular expression to use for finding option lists."""
7878

79-
REST_REGEX = r"((\.{2}|`{2}) ?[\w.~-]+(:{2}|`{2})?[\w ]*?|`[\w.~]+`)"
79+
REST_DIRECTIVE_REGEX = r"^( {0,}\.\. .+?:{1,2}.*\n(?:[ \t]{1,}.*\n|\n)*)"
8080
"""Regular expression to use for finding reST directives."""
8181

82+
REST_INLINE_REGEX = r"(?<!^\.{2} )(:)*([*]{1,2}|_?[`]{1,2}|[|\[])[\w <>:.-]+([*]{1,2}|[`]{1,2}_?|[|]|[\]]_?)" # noqa: E501
83+
"""Regular expression to use for finding inline reST markup."""
84+
8285
REST_SECTION_REGEX = (
8386
r"(^ *[#\*=\-^\'\"\+_\~`\.\:]+\n)?[\w ]+\n *[#\*=\-^\'\"\+_\~`\.\:]+"
8487
)
@@ -153,7 +156,8 @@
153156
)
154157
"""The URL patterns to look for when finding links.
155158
156-
Based on the table at <https://en.wikipedia.org/wiki/List_of_URI_schemes>
159+
Based on the table at
160+
<https://en.wikipedia.org/wiki/List_of_URI_schemes>
157161
"""
158162

159163
# This is the regex used to find URL links:

src/docformatter/encode.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class Encoder:
4747
CRLF = "\r\n"
4848

4949
# Default encoding to use if the file encoding cannot be detected
50-
DEFAULT_ENCODING = "latin-1"
50+
DEFAULT_ENCODING = sys.getdefaultencoding()
5151

5252
def __init__(self):
5353
"""Initialize an Encoder instance."""
@@ -64,9 +64,15 @@ def do_detect_encoding(self, filename) -> None:
6464
"""
6565
try:
6666
detection_result = from_path(filename).best()
67-
self.encoding = (
68-
detection_result.encoding if detection_result else self.DEFAULT_ENCODING
69-
)
67+
if detection_result and detection_result.encoding in ["utf_16", "utf_32"]:
68+
# Treat undetectable/binary encodings as failure
69+
self.encoding = self.DEFAULT_ENCODING
70+
else:
71+
self.encoding = (
72+
detection_result.encoding
73+
if detection_result
74+
else self.DEFAULT_ENCODING
75+
)
7076

7177
# Check for correctness of encoding.
7278
with self.do_open_with_encoding(filename) as check_file:

0 commit comments

Comments
 (0)