This guide briefs coding agents working on format-docstring. Use it to get
oriented before making changes.
- Formats NumPy-style docstrings (with experimental Google support) in
.pyfiles and Jupyter notebooks while preserving surrounding code. - Distributed as a CLI (
format-docstring,format-docstring-jupyter) with minimum Python 3.10, packaged viasetuptools. - Core dependencies:
click,docstring_parser_fork,jupyter-notebook-parser, andtomli/tomllibfor configuration loading. - Version is sourced dynamically in
format_docstring/__init__.py.
format_docstring/main_py.py– Click CLI for Python files; validates input and delegates toPythonFileFixer.format_docstring/main_jupyter.py– CLI for.ipynbfiles built onJupyterNotebookParser/JupyterNotebookRewriter.format_docstring/base_fixer.py– Shared directory traversal, exclusion regex handling, andfix_one_directory_or_one_fileorchestration.format_docstring/docstring_rewriter.py– AST-based docstring extraction and replacement that leaves non-docstring text untouched.format_docstring/line_wrap_numpy.py/line_wrap_google.py– Style-specific wrapping helpers; NumPy path is the production code path, Google is partial.format_docstring/line_wrap_utils.py– Shared utilities for wrapping (indent management, bullet handling, preserving literal blocks, etc.).format_docstring/config.py–pyproject.tomldiscovery, parsing, and Click default injection.tests/– Pytest suite with fixture-driven cases intests/test_data/; seetests/helpers.pyfor fixture loading helpers.
docstring_rewriter.fix_srcparses withast.parse, collects docstring literals, and rewrites source slices using absolute offsets fromcalc_line_starts; this avoidsast.unparseand keeps comments/spacing.- For functions,
_collect_param_metadatarecords signature annotations and default values so NumPyParameterssignatures in docstrings are resynchronised with the real function definition. Defaulted parameters omit redundant, optional, and forward references keep their original quoting. - Return annotations are likewise projected into
Returns/Yieldssections, mirroring tuple element splits when the docstring already enumerates them. Raisessection entries are treated like signature lines in the NumPy wrapper so exception names stay untouched while descriptions wrap.- Wrapping honors NumPy section heuristics, rST constructs, code fences,
Examplesprompts, and literal blocks introduced by::. _normalize_signature_segmentflattens multiline annotations viaast.unparsebut uses token-level replay to preserve the author's quoting style for forward references and string defaults.- CLI exposes
--docstring-style, but the Python entry-point currently raises if a non-NumPy style is requested; Jupyter flow passes style through unchanged. BaseFixersubclasses return1when any file changed so callers can surface non-zero exit codes.- Notebook fixer round-trips JSON via
json.dump(..., indent=1)and rewrites cells only when content changes, preserving magics withreconstruct_source.
- User-facing configuration lives under
[tool.format_docstring]insidepyproject.tomland supportsline_length,docstring_style,exclude,fix_rst_backticks, andverbose(defaultordiffto print unified diffs on rewrites). config.inject_config_from_fileauto-discovers the nearestpyproject.toml(walking up from targets) and merges values into Click’sdefault_map.- Default exclude pattern is
\.git|\.tox|\.pytest_cache; tests tweak it as needed.
- Install:
pip install -e .for the project,pip install -r requirements.devfor tooling. - Tests:
pytest --tb=long, or target modules such aspytest tests/test_docstring_rewriter.py. - Lint/format:
muff check --fix --config=muff.toml format_docstring tests,muff format --diff --config=muff.toml format_docstring tests. - Type checking:
mypy format_docstring/. - Tox:
toxfor the full matrix (py310–py313, mypy, lint), or focused runs liketox -e py311,tox -e mypy,tox -e muff-format. - CLI smoke tests:
format-docstring --help,format-docstring-jupyter --help. - Pre-commit:
pre-commit run -a.
- Fixture files under
tests/test_data/line_wrapandtests/test_data/end_to_enduseLINE_LENGTH: <int>headers followed byBEFORE/AFTERsections split by**********. - Regression fixture
tests/test_data/end_to_end/numpy/signature_dont_sync_raises.txtguards against mutating exception names inRaisesblocks. tests/test_playground.pyfocuses on regression snippets;tests/test_config.pyexercises config discovery and CLI overrides.- When modifying wrapping rules, update both the helper (
line_wrap_utils.py) and the corresponding expectation files intests/test_data/.
- Formatting rules mirror
muff.toml(line length 79, single quotes, NumPy docstring convention). Respect these when adding code. - Keep docstring style tests conservative: avoid mutating non-docstring content, and add regression cases whenever handling around literal sections or tables changes.
They are the lines in the docstring where input and return args are defined, for example, in this docstring:
"""
Do something
Parameters
----------
arg1 : str
Arg 1
arg2 : int = 2
Arg 2
Returns
-------
dict[str, str]
The mappingSignature lines are:
- arg1 : str
- arg2 : int = 2
- dict[str, str]