format-docstring 0.1.9__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {format_docstring-0.1.9 → format_docstring-0.2.0}/.pre-commit-config.yaml +21 -4
- {format_docstring-0.1.9 → format_docstring-0.2.0}/AGENTS.md +37 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/CHANGELOG.md +11 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/PKG-INFO +135 -10
- {format_docstring-0.1.9 → format_docstring-0.2.0}/README.md +134 -9
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring/base_fixer.py +12 -2
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring/docstring_rewriter.py +204 -10
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring/line_wrap_google.py +5 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring/line_wrap_numpy.py +271 -3
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring/line_wrap_utils.py +14 -8
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring.egg-info/PKG-INFO +135 -10
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring.egg-info/SOURCES.txt +2 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/pyproject.toml +1 -1
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/fix_rst_backticks.txt +1 -1
- format_docstring-0.2.0/tests/test_data/end_to_end/numpy/parameter_signature_sync.txt +197 -0
- format_docstring-0.2.0/tests/test_data/end_to_end/numpy/returns_signature_sync.txt +169 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tox.ini +15 -25
- {format_docstring-0.1.9 → format_docstring-0.2.0}/.github/workflows/python-package.yml +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/.github/workflows/python-publish.yml +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/.gitignore +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/.pre-commit-hooks.yaml +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/LICENSE +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring/__init__.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring/config.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring/main_jupyter.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring/main_py.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring.egg-info/dependency_links.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring.egg-info/entry_points.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring.egg-info/requires.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/format_docstring.egg-info/top_level.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/muff.toml +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/requirements.dev +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/setup.cfg +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/__init__.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/helpers.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_base_fixer.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_config.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/README.md +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/colon_spacing_fix.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/contents_that_are_not_wrapped.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/default_value_standardization.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/empty_lines_are_respected.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/examples_section.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/existing_linebreaks_should_not_be_respected.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/four_level_nested_classes.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/indent_four_levels_16_spaces_width_10.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/indent_misaligned_all.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/indent_two_levels_8_spaces.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/line_length_2.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/mismatched_underlines.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/mismatched_underlines_one_dash.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/mismatched_underlines_two_dashes.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/module_level_docstring.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/new_lines_before_and_after.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/no_format_docstring_comment.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/param_signature_without_type.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/parameters_returns_raises_wrapping.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/returns_signature_and_description.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/section_headings_with_colons.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/section_title_fixed.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/sections_notes_examples.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/signature_line_is_not_wrapped.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/single_line_docstring.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/texts_are_rewrapped.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/end_to_end/numpy/very_long_unbreakable_word.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/integration_test/numpy/after.ipynb +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/integration_test/numpy/after.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/integration_test/numpy/after_50.ipynb +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/integration_test/numpy/after_50.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/integration_test/numpy/before.ipynb +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/integration_test/numpy/before.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/jupyter/before.ipynb +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/jupyter/verbose_before.ipynb +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/README.md +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/colon_spacing_fix.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/contents_that_are_not_wrapped.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/default_value_standardization.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/empty_lines_are_respected.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/examples_section.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/existing_linebreaks_should_not_be_respected.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/fix_rst_backticks.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/indent_four_levels_16_spaces_width_10.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/indent_two_levels_8_spaces.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/line_length_2.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/mismatched_underlines.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/mismatched_underlines_one_dash.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/mismatched_underlines_two_dashes.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/module_level_docstring.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/param_signature_without_type.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/parameters_returns_raises_wrapping.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/returns_signature_and_description.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/section_headings_with_colons.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/section_title_fixed.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/sections_notes_examples.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/signature_line_is_not_wrapped.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/texts_are_rewrapped.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/line_wrap/numpy/very_long_unbreakable_word.txt +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_data/playground.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_docstring_rewriter.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_line_wrap_google.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_line_wrap_numpy.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_line_wrap_utils.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_main_jupyter.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_main_py.py +0 -0
- {format_docstring-0.1.9 → format_docstring-0.2.0}/tests/test_playground.py +0 -0
|
@@ -5,12 +5,19 @@ repos:
|
|
|
5
5
|
hooks:
|
|
6
6
|
- id: trailing-whitespace
|
|
7
7
|
- id: end-of-file-fixer
|
|
8
|
+
exclude: \.json$|\.ipynb$
|
|
8
9
|
- id: debug-statements
|
|
9
10
|
- id: double-quote-string-fixer
|
|
10
11
|
- id: requirements-txt-fixer
|
|
11
|
-
- id: pretty-format-json
|
|
12
|
-
args: [--no-ensure-ascii, --indent=4, --no-sort-keys]
|
|
13
12
|
exclude: \.ipynb$
|
|
13
|
+
- id: check-added-large-files
|
|
14
|
+
args: [--maxkb=1000]
|
|
15
|
+
- id: check-toml
|
|
16
|
+
- id: check-yaml
|
|
17
|
+
- id: name-tests-test
|
|
18
|
+
args: [--pytest-test-first]
|
|
19
|
+
exclude: ^tests/test_data/|^tests/helpers\.py$
|
|
20
|
+
- id: check-merge-conflict
|
|
14
21
|
- repo: https://github.com/asottile/pyupgrade
|
|
15
22
|
rev: v3.20.0
|
|
16
23
|
hooks:
|
|
@@ -31,11 +38,21 @@ repos:
|
|
|
31
38
|
hooks:
|
|
32
39
|
- id: yamlfix
|
|
33
40
|
- repo: https://github.com/hukkin/mdformat
|
|
34
|
-
rev: 0.
|
|
41
|
+
rev: 1.0.0
|
|
35
42
|
hooks:
|
|
36
43
|
- id: mdformat
|
|
37
44
|
args: [--wrap, '79', --number]
|
|
38
|
-
additional_dependencies: [mdformat-
|
|
45
|
+
additional_dependencies: [mdformat-gfm]
|
|
46
|
+
- repo: https://github.com/jsh9/format-json
|
|
47
|
+
rev: 0.1.2
|
|
48
|
+
hooks:
|
|
49
|
+
- id: format-json
|
|
50
|
+
args:
|
|
51
|
+
- --autofix
|
|
52
|
+
- --no-ensure-ascii
|
|
53
|
+
- --indent=4
|
|
54
|
+
- --no-sort-keys
|
|
55
|
+
- --no-eof-newline
|
|
39
56
|
- repo: https://github.com/jsh9/markdown-toc-creator
|
|
40
57
|
rev: 0.0.11
|
|
41
58
|
hooks:
|
|
@@ -38,8 +38,17 @@ oriented before making changes.
|
|
|
38
38
|
- `docstring_rewriter.fix_src` parses with `ast.parse`, collects docstring
|
|
39
39
|
literals, and rewrites source slices using absolute offsets from
|
|
40
40
|
`calc_line_starts`; this avoids `ast.unparse` and keeps comments/spacing.
|
|
41
|
+
- For functions, `_collect_param_metadata` records signature annotations and
|
|
42
|
+
default values so NumPy `Parameters` signatures in docstrings are
|
|
43
|
+
resynchronised with the real function definition. Defaulted parameters omit
|
|
44
|
+
redundant `, optional`, and forward references keep their original quoting.
|
|
45
|
+
- Return annotations are likewise projected into `Returns`/`Yields` sections,
|
|
46
|
+
mirroring tuple element splits when the docstring already enumerates them.
|
|
41
47
|
- Wrapping honors NumPy section heuristics, rST constructs, code fences,
|
|
42
48
|
`Examples` prompts, and literal blocks introduced by `::`.
|
|
49
|
+
- `_normalize_signature_segment` flattens multiline annotations via
|
|
50
|
+
`ast.unparse` but uses token-level replay to preserve the author's quoting
|
|
51
|
+
style for forward references and string defaults.
|
|
43
52
|
- CLI exposes `--docstring-style`, but the Python entry-point currently raises
|
|
44
53
|
if a non-NumPy style is requested; Jupyter flow passes style through
|
|
45
54
|
unchanged.
|
|
@@ -91,3 +100,31 @@ oriented before making changes.
|
|
|
91
100
|
- Keep docstring style tests conservative: avoid mutating non-docstring
|
|
92
101
|
content, and add regression cases whenever handling around literal sections
|
|
93
102
|
or tables changes.
|
|
103
|
+
|
|
104
|
+
## What is a "signature line"?
|
|
105
|
+
|
|
106
|
+
They are the lines in the docstring where input and return args are defined,
|
|
107
|
+
for example, in this docstring:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
"""
|
|
111
|
+
Do something
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
arg1 : str
|
|
116
|
+
Arg 1
|
|
117
|
+
arg2 : int = 2
|
|
118
|
+
Arg 2
|
|
119
|
+
|
|
120
|
+
Returns
|
|
121
|
+
-------
|
|
122
|
+
dict[str, str]
|
|
123
|
+
The mapping
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Signature lines are:
|
|
127
|
+
|
|
128
|
+
- arg1 : str
|
|
129
|
+
- arg2 : int = 2
|
|
130
|
+
- dict[str, str]
|
|
@@ -6,6 +6,15 @@ The format is based on
|
|
|
6
6
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
7
7
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
8
8
|
|
|
9
|
+
## [0.2.0] - 2025-10-20
|
|
10
|
+
|
|
11
|
+
- Added
|
|
12
|
+
- AST-driven synchronization of NumPy `Parameters` and `Returns` signature
|
|
13
|
+
lines with the function signature, including tuple element expansion for
|
|
14
|
+
multi-line return blocks
|
|
15
|
+
- Full diff
|
|
16
|
+
- https://github.com/jsh9/format-docstring/compare/0.1.9...0.2.0
|
|
17
|
+
|
|
9
18
|
## [0.1.9] - 2025-10-16
|
|
10
19
|
|
|
11
20
|
- Added
|
|
@@ -17,6 +26,8 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
17
26
|
- Changed
|
|
18
27
|
- Added "self format" pre-commit hook to format docstrings within this repo
|
|
19
28
|
with its own formatting logic
|
|
29
|
+
- Full diff
|
|
30
|
+
- https://github.com/jsh9/format-docstring/compare/0.1.8...0.1.9
|
|
20
31
|
|
|
21
32
|
## [0.1.8] - 2025-10-14
|
|
22
33
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: format-docstring
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: A Python formatter to wrap/adjust docstring lines
|
|
5
5
|
Author-email: jsh9 <25124332+jsh9@users.noreply.github.com>
|
|
6
6
|
Maintainer-email: jsh9 <25124332+jsh9@users.noreply.github.com>
|
|
@@ -34,6 +34,8 @@ Dynamic: license-file
|
|
|
34
34
|
|
|
35
35
|
A Python formatter to automatically format numpy-style docstrings.
|
|
36
36
|
|
|
37
|
+
______________________________________________________________________
|
|
38
|
+
|
|
37
39
|
**Table of Contents:**
|
|
38
40
|
|
|
39
41
|
<!--TOC-->
|
|
@@ -45,6 +47,7 @@ A Python formatter to automatically format numpy-style docstrings.
|
|
|
45
47
|
- [2.3. Minor typos can be automatically fixed](#23-minor-typos-can-be-automatically-fixed)
|
|
46
48
|
- [2.4. Default value declarations are standardized](#24-default-value-declarations-are-standardized)
|
|
47
49
|
- [2.5. Single backticks are converted to double backticks (rST syntax)](#25-single-backticks-are-converted-to-double-backticks-rst-syntax)
|
|
50
|
+
- [2.6. Docstring parameters and returns stay in sync with signatures](#26-docstring-parameters-and-returns-stay-in-sync-with-signatures)
|
|
48
51
|
- [3. Installation](#3-installation)
|
|
49
52
|
- [4. Usage](#4-usage)
|
|
50
53
|
- [4.1. Command Line Interface](#41-command-line-interface)
|
|
@@ -54,24 +57,28 @@ A Python formatter to automatically format numpy-style docstrings.
|
|
|
54
57
|
- [5.1. Command-Line Options](#51-command-line-options)
|
|
55
58
|
- [5.2. Usage Examples](#52-usage-examples)
|
|
56
59
|
- [5.3. `pyproject.toml` Configuration](#53-pyprojecttoml-configuration)
|
|
60
|
+
- [6. Caveat](#6-caveat)
|
|
57
61
|
|
|
58
62
|
<!--TOC-->
|
|
59
63
|
|
|
64
|
+
______________________________________________________________________
|
|
65
|
+
|
|
60
66
|
## 1. Overview
|
|
61
67
|
|
|
62
68
|
`format-docstring` is a tool that automatically formats and wraps docstring
|
|
63
69
|
content in Python files and Jupyter notebooks.
|
|
64
70
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
Baseline reflow corresponds to the common docstring cleanups offered by
|
|
72
|
+
general-purpose formatters: splitting one-line docstrings into the canonical
|
|
73
|
+
multi-line layout (triple quotes, blank line, summary), normalizing
|
|
74
|
+
indentation, and wrapping text at a fixed column width without applying extra
|
|
75
|
+
heuristics.
|
|
69
76
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
| Feature | `format-docstring` | [docformatter] | [pydocstringformatter] | [Ruff] | [Black] |
|
|
78
|
+
| ----------------------------------------- | ------------------ | -------------- | ---------------------- | ------ | ------- |
|
|
79
|
+
| Docstring wrapping | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
80
|
+
| Compatible with line length linter (E501) | ✅ | ❌ | ❌ | N/A | N/A |
|
|
81
|
+
| Fixes common docstring typos | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
75
82
|
|
|
76
83
|
## 2. Before vs After Examples
|
|
77
84
|
|
|
@@ -187,6 +194,25 @@ def mu_function():
|
|
|
187
194
|
pass
|
|
188
195
|
```
|
|
189
196
|
|
|
197
|
+
or, Google-style section headers can be fixed:
|
|
198
|
+
|
|
199
|
+
```diff
|
|
200
|
+
def my_function():
|
|
201
|
+
"""
|
|
202
|
+
My function
|
|
203
|
+
|
|
204
|
+
- Args:
|
|
205
|
+
- ----
|
|
206
|
+
+ Parameters
|
|
207
|
+
+ ----------
|
|
208
|
+
arg1 : str
|
|
209
|
+
Arg 1
|
|
210
|
+
|
|
211
|
+
...
|
|
212
|
+
"""
|
|
213
|
+
pass
|
|
214
|
+
```
|
|
215
|
+
|
|
190
216
|
### 2.4. Default value declarations are standardized
|
|
191
217
|
|
|
192
218
|
```diff
|
|
@@ -230,9 +256,94 @@ def process_data(data):
|
|
|
230
256
|
- Processed data with key `result`.
|
|
231
257
|
+ Processed data with key ``result``.
|
|
232
258
|
"""
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### 2.6. Docstring parameters and returns stay in sync with signatures
|
|
262
|
+
|
|
263
|
+
```diff
|
|
264
|
+
from typing import List, Optional
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def create_user(
|
|
268
|
+
user: Optional[str] = None,
|
|
269
|
+
roles: List["Role"] | None = None,
|
|
270
|
+
retries: int = 0,
|
|
271
|
+
serializer: "Serializer" | None = None,
|
|
272
|
+
something_else: tuple[int, ...] = (
|
|
273
|
+
"1",
|
|
274
|
+
'2',
|
|
275
|
+
3,
|
|
276
|
+
4,
|
|
277
|
+
5,
|
|
278
|
+
6,
|
|
279
|
+
7,
|
|
280
|
+
8,
|
|
281
|
+
9,
|
|
282
|
+
10,
|
|
283
|
+
11,
|
|
284
|
+
12,
|
|
285
|
+
),
|
|
286
|
+
) -> None:
|
|
287
|
+
"""
|
|
288
|
+
Parameters
|
|
289
|
+
----------
|
|
290
|
+
- user : str
|
|
291
|
+
+ user : Optional[str], default=None
|
|
292
|
+
Login name.
|
|
293
|
+
- roles : list
|
|
294
|
+
+ roles : List["Role"] | None, default=None
|
|
295
|
+
Assigned roles.
|
|
296
|
+
- retries : int
|
|
297
|
+
+ retries : int, default=0
|
|
298
|
+
Number of retry attempts.
|
|
299
|
+
- serializer : Serializer, optional
|
|
300
|
+
+ serializer : "Serializer" | None, default=None
|
|
301
|
+
Custom serializer instance.
|
|
302
|
+
- something_else : tuple[int, ...]
|
|
303
|
+
+ something_else : tuple[int, ...], default=("1", '2', 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
|
|
304
|
+
"""
|
|
233
305
|
pass
|
|
234
306
|
```
|
|
235
307
|
|
|
308
|
+
And return type hint:
|
|
309
|
+
|
|
310
|
+
```diff
|
|
311
|
+
def build_mapping() -> dict[str, str]:
|
|
312
|
+
"""
|
|
313
|
+
Returns
|
|
314
|
+
-------
|
|
315
|
+
- str
|
|
316
|
+
+ dict[str, str]
|
|
317
|
+
Mapping of values.
|
|
318
|
+
"""
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
For tuple return annotations, tuple elements are split across multiple
|
|
322
|
+
signature lines only when the docstring already adopted that layout:
|
|
323
|
+
|
|
324
|
+
```diff
|
|
325
|
+
def compute_values() -> tuple[int, str, list[str]]:
|
|
326
|
+
"""
|
|
327
|
+
Returns
|
|
328
|
+
-------
|
|
329
|
+
- float
|
|
330
|
+
+ int
|
|
331
|
+
First element.
|
|
332
|
+
- str
|
|
333
|
+
+ str
|
|
334
|
+
Second element.
|
|
335
|
+
- List[str]
|
|
336
|
+
+ list[str]
|
|
337
|
+
Third element.
|
|
338
|
+
"""
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Annotations and defaults are extracted from the actual function signature, so
|
|
342
|
+
docstring signature lines reflect the ground truth. Defaulted parameters omit
|
|
343
|
+
redundant `, optional`, forward references keep their original quoting, and
|
|
344
|
+
return signatures track tuple splitting conventions already present in the
|
|
345
|
+
docstring.
|
|
346
|
+
|
|
236
347
|
## 3. Installation
|
|
237
348
|
|
|
238
349
|
```bash
|
|
@@ -367,3 +478,17 @@ verbose = "default" # or "diff" to print unified diffs
|
|
|
367
478
|
|
|
368
479
|
The tool searches for `pyproject.toml` starting from the target file/directory
|
|
369
480
|
and walking up the parent directories until one is found.
|
|
481
|
+
|
|
482
|
+
## 6. Caveat
|
|
483
|
+
|
|
484
|
+
This tool assumes the docstrings are written in **mostly** the correct format,
|
|
485
|
+
because it needs those formatting cues (such as section headers and `------`)
|
|
486
|
+
to parse docstrings.
|
|
487
|
+
|
|
488
|
+
If the docstrings are far from perfectly formatted, it's recommended that you
|
|
489
|
+
use AI coding assistants to rewrite the docstrings first.
|
|
490
|
+
|
|
491
|
+
[black]: https://github.com/psf/black
|
|
492
|
+
[docformatter]: https://github.com/PyCQA/docformatter
|
|
493
|
+
[pydocstringformatter]: https://github.com/DanielNoord/pydocstringformatter
|
|
494
|
+
[ruff]: https://github.com/astral-sh/ruff
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
A Python formatter to automatically format numpy-style docstrings.
|
|
4
4
|
|
|
5
|
+
______________________________________________________________________
|
|
6
|
+
|
|
5
7
|
**Table of Contents:**
|
|
6
8
|
|
|
7
9
|
<!--TOC-->
|
|
@@ -13,6 +15,7 @@ A Python formatter to automatically format numpy-style docstrings.
|
|
|
13
15
|
- [2.3. Minor typos can be automatically fixed](#23-minor-typos-can-be-automatically-fixed)
|
|
14
16
|
- [2.4. Default value declarations are standardized](#24-default-value-declarations-are-standardized)
|
|
15
17
|
- [2.5. Single backticks are converted to double backticks (rST syntax)](#25-single-backticks-are-converted-to-double-backticks-rst-syntax)
|
|
18
|
+
- [2.6. Docstring parameters and returns stay in sync with signatures](#26-docstring-parameters-and-returns-stay-in-sync-with-signatures)
|
|
16
19
|
- [3. Installation](#3-installation)
|
|
17
20
|
- [4. Usage](#4-usage)
|
|
18
21
|
- [4.1. Command Line Interface](#41-command-line-interface)
|
|
@@ -22,24 +25,28 @@ A Python formatter to automatically format numpy-style docstrings.
|
|
|
22
25
|
- [5.1. Command-Line Options](#51-command-line-options)
|
|
23
26
|
- [5.2. Usage Examples](#52-usage-examples)
|
|
24
27
|
- [5.3. `pyproject.toml` Configuration](#53-pyprojecttoml-configuration)
|
|
28
|
+
- [6. Caveat](#6-caveat)
|
|
25
29
|
|
|
26
30
|
<!--TOC-->
|
|
27
31
|
|
|
32
|
+
______________________________________________________________________
|
|
33
|
+
|
|
28
34
|
## 1. Overview
|
|
29
35
|
|
|
30
36
|
`format-docstring` is a tool that automatically formats and wraps docstring
|
|
31
37
|
content in Python files and Jupyter notebooks.
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
Baseline reflow corresponds to the common docstring cleanups offered by
|
|
40
|
+
general-purpose formatters: splitting one-line docstrings into the canonical
|
|
41
|
+
multi-line layout (triple quotes, blank line, summary), normalizing
|
|
42
|
+
indentation, and wrapping text at a fixed column width without applying extra
|
|
43
|
+
heuristics.
|
|
37
44
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
| Feature | `format-docstring` | [docformatter] | [pydocstringformatter] | [Ruff] | [Black] |
|
|
46
|
+
| ----------------------------------------- | ------------------ | -------------- | ---------------------- | ------ | ------- |
|
|
47
|
+
| Docstring wrapping | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
48
|
+
| Compatible with line length linter (E501) | ✅ | ❌ | ❌ | N/A | N/A |
|
|
49
|
+
| Fixes common docstring typos | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
43
50
|
|
|
44
51
|
## 2. Before vs After Examples
|
|
45
52
|
|
|
@@ -155,6 +162,25 @@ def mu_function():
|
|
|
155
162
|
pass
|
|
156
163
|
```
|
|
157
164
|
|
|
165
|
+
or, Google-style section headers can be fixed:
|
|
166
|
+
|
|
167
|
+
```diff
|
|
168
|
+
def my_function():
|
|
169
|
+
"""
|
|
170
|
+
My function
|
|
171
|
+
|
|
172
|
+
- Args:
|
|
173
|
+
- ----
|
|
174
|
+
+ Parameters
|
|
175
|
+
+ ----------
|
|
176
|
+
arg1 : str
|
|
177
|
+
Arg 1
|
|
178
|
+
|
|
179
|
+
...
|
|
180
|
+
"""
|
|
181
|
+
pass
|
|
182
|
+
```
|
|
183
|
+
|
|
158
184
|
### 2.4. Default value declarations are standardized
|
|
159
185
|
|
|
160
186
|
```diff
|
|
@@ -198,9 +224,94 @@ def process_data(data):
|
|
|
198
224
|
- Processed data with key `result`.
|
|
199
225
|
+ Processed data with key ``result``.
|
|
200
226
|
"""
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### 2.6. Docstring parameters and returns stay in sync with signatures
|
|
230
|
+
|
|
231
|
+
```diff
|
|
232
|
+
from typing import List, Optional
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def create_user(
|
|
236
|
+
user: Optional[str] = None,
|
|
237
|
+
roles: List["Role"] | None = None,
|
|
238
|
+
retries: int = 0,
|
|
239
|
+
serializer: "Serializer" | None = None,
|
|
240
|
+
something_else: tuple[int, ...] = (
|
|
241
|
+
"1",
|
|
242
|
+
'2',
|
|
243
|
+
3,
|
|
244
|
+
4,
|
|
245
|
+
5,
|
|
246
|
+
6,
|
|
247
|
+
7,
|
|
248
|
+
8,
|
|
249
|
+
9,
|
|
250
|
+
10,
|
|
251
|
+
11,
|
|
252
|
+
12,
|
|
253
|
+
),
|
|
254
|
+
) -> None:
|
|
255
|
+
"""
|
|
256
|
+
Parameters
|
|
257
|
+
----------
|
|
258
|
+
- user : str
|
|
259
|
+
+ user : Optional[str], default=None
|
|
260
|
+
Login name.
|
|
261
|
+
- roles : list
|
|
262
|
+
+ roles : List["Role"] | None, default=None
|
|
263
|
+
Assigned roles.
|
|
264
|
+
- retries : int
|
|
265
|
+
+ retries : int, default=0
|
|
266
|
+
Number of retry attempts.
|
|
267
|
+
- serializer : Serializer, optional
|
|
268
|
+
+ serializer : "Serializer" | None, default=None
|
|
269
|
+
Custom serializer instance.
|
|
270
|
+
- something_else : tuple[int, ...]
|
|
271
|
+
+ something_else : tuple[int, ...], default=("1", '2', 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
|
|
272
|
+
"""
|
|
201
273
|
pass
|
|
202
274
|
```
|
|
203
275
|
|
|
276
|
+
And return type hint:
|
|
277
|
+
|
|
278
|
+
```diff
|
|
279
|
+
def build_mapping() -> dict[str, str]:
|
|
280
|
+
"""
|
|
281
|
+
Returns
|
|
282
|
+
-------
|
|
283
|
+
- str
|
|
284
|
+
+ dict[str, str]
|
|
285
|
+
Mapping of values.
|
|
286
|
+
"""
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
For tuple return annotations, tuple elements are split across multiple
|
|
290
|
+
signature lines only when the docstring already adopted that layout:
|
|
291
|
+
|
|
292
|
+
```diff
|
|
293
|
+
def compute_values() -> tuple[int, str, list[str]]:
|
|
294
|
+
"""
|
|
295
|
+
Returns
|
|
296
|
+
-------
|
|
297
|
+
- float
|
|
298
|
+
+ int
|
|
299
|
+
First element.
|
|
300
|
+
- str
|
|
301
|
+
+ str
|
|
302
|
+
Second element.
|
|
303
|
+
- List[str]
|
|
304
|
+
+ list[str]
|
|
305
|
+
Third element.
|
|
306
|
+
"""
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Annotations and defaults are extracted from the actual function signature, so
|
|
310
|
+
docstring signature lines reflect the ground truth. Defaulted parameters omit
|
|
311
|
+
redundant `, optional`, forward references keep their original quoting, and
|
|
312
|
+
return signatures track tuple splitting conventions already present in the
|
|
313
|
+
docstring.
|
|
314
|
+
|
|
204
315
|
## 3. Installation
|
|
205
316
|
|
|
206
317
|
```bash
|
|
@@ -335,3 +446,17 @@ verbose = "default" # or "diff" to print unified diffs
|
|
|
335
446
|
|
|
336
447
|
The tool searches for `pyproject.toml` starting from the target file/directory
|
|
337
448
|
and walking up the parent directories until one is found.
|
|
449
|
+
|
|
450
|
+
## 6. Caveat
|
|
451
|
+
|
|
452
|
+
This tool assumes the docstrings are written in **mostly** the correct format,
|
|
453
|
+
because it needs those formatting cues (such as section headers and `------`)
|
|
454
|
+
to parse docstrings.
|
|
455
|
+
|
|
456
|
+
If the docstrings are far from perfectly formatted, it's recommended that you
|
|
457
|
+
use AI coding assistants to rewrite the docstrings first.
|
|
458
|
+
|
|
459
|
+
[black]: https://github.com/psf/black
|
|
460
|
+
[docformatter]: https://github.com/PyCQA/docformatter
|
|
461
|
+
[pydocstringformatter]: https://github.com/DanielNoord/pydocstringformatter
|
|
462
|
+
[ruff]: https://github.com/astral-sh/ruff
|
|
@@ -8,7 +8,18 @@ from typing import Any
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class BaseFixer:
|
|
11
|
-
"""
|
|
11
|
+
r"""
|
|
12
|
+
Base class for fixing code formatting issues.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
path : str
|
|
17
|
+
Target file or directory to process.
|
|
18
|
+
exclude_pattern : str, default='\.git|\.tox|\.pytest_cache'
|
|
19
|
+
Regular expression describing paths to skip.
|
|
20
|
+
verbose : str, default='default'
|
|
21
|
+
Verbosity mode; ``'diff'`` prints unified diffs for rewritten files.
|
|
22
|
+
"""
|
|
12
23
|
|
|
13
24
|
def __init__(
|
|
14
25
|
self,
|
|
@@ -16,7 +27,6 @@ class BaseFixer:
|
|
|
16
27
|
exclude_pattern: str = r'\.git|\.tox|\.pytest_cache',
|
|
17
28
|
verbose: str = 'default',
|
|
18
29
|
) -> None:
|
|
19
|
-
"""Initialize the fixer with a path and optional exclude pattern."""
|
|
20
30
|
self.path = path
|
|
21
31
|
self.exclude_pattern = exclude_pattern
|
|
22
32
|
self.verbose = verbose
|