Formats docstrings to follow PEP 257 conventions with support for various docstring styles and Black formatter compatibility
—
Main docstring formatting functionality providing the primary interface for processing Python files and docstrings according to PEP 257 conventions.
The main class responsible for docstring formatting operations, handling file processing, source code parsing, and docstring transformation.
class Formatter:
"""Format docstrings in Python source files."""
# Quote type constants
STR_QUOTE_TYPES = ('"""', "'''")
RAW_QUOTE_TYPES = ('r"""', 'R"""', "r'''", "R'''")
UCODE_QUOTE_TYPES = ('u"""', 'U"""', "u'''", "U'''")
QUOTE_TYPES = STR_QUOTE_TYPES + RAW_QUOTE_TYPES + UCODE_QUOTE_TYPES
def __init__(self, args, stderror, stdin, stdout):
"""
Initialize formatter with configuration and I/O streams.
Args:
args: Parsed configuration arguments from Configurater
stderror: Standard error stream for error output
stdin: Standard input stream for reading from stdin
stdout: Standard output stream for formatted output
"""
def do_format_files(self) -> int:
"""
Format all files specified in configuration.
Returns:
int: Exit code (FormatResult constant)
"""
def do_format_standard_in(self, parser) -> None:
"""
Format docstrings from standard input.
Args:
parser: ArgumentParser instance for error handling
"""def _do_format_file(self, filename):
"""
Format docstrings in a single file.
Args:
filename (str): Path to Python file to format
Returns:
Formatted source code or None if unchanged
"""
def _do_format_code(self, source):
"""
Format docstrings in source code string.
Args:
source (str): Python source code to format
Returns:
str: Formatted source code
"""def _format_code(self, source, summary_wrap_length, description_wrap_length,
make_summary_multi_line, force_wrap, tab_width, blank,
pre_summary_newline, pre_summary_space, close_quotes_on_newline,
style):
"""
Apply formatting rules to source code.
Args:
source (str): Python source code
summary_wrap_length (int): Maximum line length for summary
description_wrap_length (int): Maximum line length for description
make_summary_multi_line (bool): Convert single-line to multi-line docstrings
force_wrap (bool): Force wrapping even if it creates messy formatting
tab_width (int): Tab width for indentation calculations
blank (bool): Add blank line after description
pre_summary_newline (bool): Add newline before summary
pre_summary_space (bool): Add space after opening quotes
close_quotes_on_newline (bool): Place closing quotes on new line
style (str): Docstring style ('sphinx' or 'epytext')
Returns:
str: Formatted source code
"""def _do_format_docstring(self, docstring, summary_wrap_length, description_wrap_length,
make_summary_multi_line, force_wrap, tab_width, blank,
pre_summary_newline, pre_summary_space, close_quotes_on_newline,
style):
"""
Format individual docstring according to PEP 257.
Args:
docstring (str): Raw docstring content
summary_wrap_length (int): Summary line length limit
description_wrap_length (int): Description line length limit
make_summary_multi_line (bool): Multi-line summary conversion
force_wrap (bool): Force wrapping mode
tab_width (int): Tab character width
blank (bool): Add blank line after description
pre_summary_newline (bool): Newline before summary
pre_summary_space (bool): Space after opening quotes
close_quotes_on_newline (bool): Closing quote placement
style (str): Field list style ('sphinx' or 'epytext')
Returns:
str: Formatted docstring
"""
def _do_format_oneline_docstring(self, contents, summary_wrap_length, force_wrap,
tab_width, make_summary_multi_line,
close_quotes_on_newline):
"""
Format single-line docstrings.
Args:
contents (str): Docstring content
summary_wrap_length (int): Line length limit
force_wrap (bool): Force wrapping mode
tab_width (int): Tab width for calculations
make_summary_multi_line (bool): Convert to multi-line
close_quotes_on_newline (bool): Quote placement
Returns:
str: Formatted single-line docstring
"""
def _do_format_multiline_docstring(self, contents, summary_wrap_length,
description_wrap_length, force_wrap, tab_width,
blank, pre_summary_newline, pre_summary_space,
close_quotes_on_newline, style):
"""
Format multi-line docstrings.
Args:
contents (str): Docstring content
summary_wrap_length (int): Summary line length limit
description_wrap_length (int): Description line length limit
force_wrap (bool): Force wrapping mode
tab_width (int): Tab character width
blank (bool): Add blank line after description
pre_summary_newline (bool): Newline before summary
pre_summary_space (bool): Space after opening quotes
close_quotes_on_newline (bool): Closing quote placement
style (str): Field list style
Returns:
str: Formatted multi-line docstring
"""
def _do_strip_docstring(self, docstring):
"""
Strip and normalize docstring quotes and whitespace.
Args:
docstring (str): Raw docstring with quotes
Returns:
tuple: (stripped_content, indentation)
"""Exit code constants for formatter operations.
class FormatResult:
"""Exit codes for docformatter operations."""
ok = 0 # Successful completion
error = 1 # Error occurred during processing
interrupted = 2 # Operation interrupted by user (Ctrl+C)
check_failed = 3 # Check mode found formatting issuesimport sys
from docformatter import Formatter, Configurater, FormatResult
# Setup configuration
args = ['--in-place', 'example.py']
configurator = Configurater(args)
configurator.do_parse_arguments()
# Create formatter
formatter = Formatter(
configurator.args,
stderror=sys.stderr,
stdin=sys.stdin,
stdout=sys.stdout
)
# Format files
result = formatter.do_format_files()
if result == FormatResult.ok:
print("Formatting completed successfully")
elif result == FormatResult.error:
print("Error occurred during formatting")
elif result == FormatResult.check_failed:
print("Files need formatting")import sys
from docformatter import Formatter, Configurater
# Setup with Black compatibility and custom wrap lengths
args = [
'--black',
'--wrap-summaries', '88',
'--wrap-descriptions', '88',
'--in-place',
'src/'
]
configurator = Configurater(args)
configurator.do_parse_arguments()
formatter = Formatter(
configurator.args,
stderror=sys.stderr,
stdin=sys.stdin,
stdout=sys.stdout
)
# Format with custom settings
result = formatter.do_format_files()import sys
from docformatter import Formatter, Configurater, FormatResult
# Check formatting without making changes
args = ['--check', '--diff', '--recursive', '.']
configurator = Configurater(args)
configurator.do_parse_arguments()
formatter = Formatter(
configurator.args,
stderror=sys.stderr,
stdin=sys.stdin,
stdout=sys.stdout
)
result = formatter.do_format_files()
# Exit with appropriate code for CI/CD
sys.exit(result)import sys
from docformatter import Formatter, Configurater
# Process from stdin
args = ['-'] # '-' indicates stdin input
configurator = Configurater(args)
configurator.do_parse_arguments()
formatter = Formatter(
configurator.args,
stderror=sys.stderr,
stdin=sys.stdin,
stdout=sys.stdout
)
# Format from stdin and output to stdout
formatter.do_format_standard_in(configurator.parser)The Formatter applies the following PEP 257 rules:
The Formatter handles various error conditions:
Install with Tessl CLI
npx tessl i tessl/pypi-docformatter