docstring-tailor 0.2.1.dev6__tar.gz → 0.3.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.
- docstring_tailor-0.3.0/PKG-INFO +636 -0
- docstring_tailor-0.3.0/README.md +603 -0
- {docstring_tailor-0.2.1.dev6 → docstring_tailor-0.3.0}/makefile +2 -2
- {docstring_tailor-0.2.1.dev6 → docstring_tailor-0.3.0}/pyproject.toml +2 -2
- docstring_tailor-0.3.0/src/docstring_tailor/__init__.py +1 -0
- {docstring_tailor-0.2.1.dev6 → docstring_tailor-0.3.0}/src/docstring_tailor/cli_config.py +1 -4
- docstring_tailor-0.3.0/src/docstring_tailor/constants.py +114 -0
- docstring_tailor-0.3.0/src/docstring_tailor/docstring_visitor.py +255 -0
- docstring_tailor-0.3.0/src/docstring_tailor/ir_model.py +132 -0
- docstring_tailor-0.3.0/src/docstring_tailor/main.py +295 -0
- docstring_tailor-0.3.0/src/docstring_tailor/parser/indentation_based/google_docstring_parser.py +121 -0
- docstring_tailor-0.3.0/src/docstring_tailor/parser/indentation_based/indentation_based_parser.py +387 -0
- docstring_tailor-0.3.0/src/docstring_tailor/parser/indentation_based/numpy_docstring_parser.py +162 -0
- docstring_tailor-0.3.0/src/docstring_tailor/parser/indentation_based/structured_list_parser.py +213 -0
- docstring_tailor-0.3.0/src/docstring_tailor/parser/parser_factory.py +41 -0
- docstring_tailor-0.3.0/src/docstring_tailor/renderer/base_renderer.py +623 -0
- docstring_tailor-0.3.0/src/docstring_tailor/renderer/google_renderer.py +77 -0
- docstring_tailor-0.3.0/src/docstring_tailor/renderer/numpy_renderer.py +99 -0
- docstring_tailor-0.3.0/src/docstring_tailor/renderer/renderer_factory.py +35 -0
- docstring_tailor-0.3.0/src/docstring_tailor/utils/__init__.py +1 -0
- {docstring_tailor-0.2.1.dev6 → docstring_tailor-0.3.0}/src/docstring_tailor/utils/utils_cli.py +4 -3
- {docstring_tailor-0.2.1.dev6 → docstring_tailor-0.3.0}/src/docstring_tailor/utils/utils_file_system.py +17 -14
- docstring_tailor-0.3.0/src/docstring_tailor/utils/utils_formatting.py +76 -0
- docstring_tailor-0.3.0/src/docstring_tailor/utils/utils_keyword_translation.py +128 -0
- docstring_tailor-0.3.0/src/docstring_tailor/utils/utils_list_detection.py +197 -0
- docstring_tailor-0.3.0/src/docstring_tailor/utils/utils_parsing.py +121 -0
- docstring_tailor-0.3.0/src/docstring_tailor/utils/utils_printing.py +76 -0
- docstring_tailor-0.3.0/temp.md +0 -0
- {docstring_tailor-0.2.1.dev6 → docstring_tailor-0.3.0}/tests/cases/config_model.py +54 -1
- docstring_tailor-0.3.0/tests/cases/formatting_cases.py +226 -0
- docstring_tailor-0.3.0/tests/fixtures/class_docstring/class_docstring_100.py +93 -0
- docstring_tailor-0.3.0/tests/fixtures/class_docstring/class_docstring_60.py +113 -0
- docstring_tailor-0.3.0/tests/fixtures/class_docstring/class_docstring_80.py +100 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/code_block_multiple/code_block_multiple_80.py +17 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/code_block_multiple/code_block_multiple_blank_lines.py +29 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/code_block_singular/code_block_singular_80.py +6 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/code_block_singular/code_block_singular_blank_lines.py +12 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/code_repl_multiple/code_repl_multiple_80.py +28 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/code_repl_multiple/code_repl_multiple_blank_lines.py +40 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/code_repl_singular/code_repl_singular_80.py +24 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/code_repl_singular/code_repl_singular_blank_lines.py +36 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/empty/empty_80.py +1 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/named_paragraph_code_block/named_paragraph_code_block_80.py +7 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/named_paragraph_code_block/named_paragraph_code_block_blank_lines.py +13 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/named_paragraph_code_repl/named_paragraph_code_repl_80.py +25 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/named_paragraph_code_repl/named_paragraph_code_repl_blank_lines.py +36 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/named_paragraph_paragraph/named_paragraph_paragraph_100.py +7 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/named_paragraph_paragraph/named_paragraph_paragraph_60.py +9 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/named_paragraph_paragraph/named_paragraph_paragraph_80.py +7 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/named_paragraph_paragraph/named_paragraph_paragraph_wrong_input.py +21 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/paragraph_and_simple_list/paragraph_and_simple_list_100.py +23 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/paragraph_and_simple_list/paragraph_and_simple_list_60.py +31 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/paragraph_and_simple_list/paragraph_and_simple_list_80.py +25 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/paragraph_and_simple_list/paragraph_and_simple_list_wrong_input.py +41 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/paragraph_multi_line/paragraph_multi_line_100.py +4 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/paragraph_multi_line/paragraph_multi_line_60.py +5 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/paragraph_multi_line/paragraph_multi_line_80.py +5 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/paragraph_multi_line/paragraph_multi_line_wrong_input.py +13 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/paragraph_one_line/paragraph_one_line_100.py +1 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/paragraph_one_line/paragraph_one_line_60.py +1 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/paragraph_one_line/paragraph_one_line_80.py +1 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/paragraph_one_line/paragraph_one_line_wrong_input.py +16 -0
- docstring_tailor-0.2.1.dev6/tests/fixtures/module_docstring_ordered_list/module_docstring_ordered_list_100.py → docstring_tailor-0.3.0/tests/fixtures/docstring_elements/simple_list/simple_list_100.py +12 -5
- docstring_tailor-0.2.1.dev6/tests/fixtures/module_docstring_ordered_list/module_docstring_ordered_list_60.py → docstring_tailor-0.3.0/tests/fixtures/docstring_elements/simple_list/simple_list_60.py +15 -6
- docstring_tailor-0.2.1.dev6/tests/fixtures/module_docstring_ordered_list/module_docstring_ordered_list_80.py → docstring_tailor-0.3.0/tests/fixtures/docstring_elements/simple_list/simple_list_80.py +12 -5
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/simple_list/simple_list_wrong_input.py +35 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/structured_list/structured_list_100.py +22 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/structured_list/structured_list_60.py +31 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/structured_list/structured_list_80.py +27 -0
- docstring_tailor-0.3.0/tests/fixtures/docstring_elements/structured_list/structured_list_wrong_input.py +48 -0
- docstring_tailor-0.2.1.dev6/tests/fixtures/function_docstring_complex/function_docstring_complex_100.py → docstring_tailor-0.3.0/tests/fixtures/function_docstring/function_docstring_100.py +48 -23
- docstring_tailor-0.2.1.dev6/tests/fixtures/function_docstring_complex/function_docstring_complex_60.py → docstring_tailor-0.3.0/tests/fixtures/function_docstring/function_docstring_60.py +54 -29
- docstring_tailor-0.2.1.dev6/tests/fixtures/function_docstring_complex/function_docstring_complex_80.py → docstring_tailor-0.3.0/tests/fixtures/function_docstring/function_docstring_80.py +48 -25
- docstring_tailor-0.3.0/tests/fixtures/module_docstring/module_docstring_100.py +52 -0
- docstring_tailor-0.3.0/tests/fixtures/module_docstring/module_docstring_60.py +61 -0
- docstring_tailor-0.3.0/tests/fixtures/module_docstring/module_docstring_80.py +57 -0
- docstring_tailor-0.2.1.dev6/tests/test_formatting.py → docstring_tailor-0.3.0/tests/test_docstring_tailor.py +1 -1
- {docstring_tailor-0.2.1.dev6/src/docstring_tailor → docstring_tailor-0.3.0/tests}/utils/utils_testing.py +5 -4
- {docstring_tailor-0.2.1.dev6 → docstring_tailor-0.3.0}/uv.lock +1 -1
- docstring_tailor-0.2.1.dev6/PKG-INFO +0 -426
- docstring_tailor-0.2.1.dev6/README.md +0 -393
- docstring_tailor-0.2.1.dev6/src/docstring_tailor/constants.py +0 -64
- docstring_tailor-0.2.1.dev6/src/docstring_tailor/docstring_visitor.py +0 -272
- docstring_tailor-0.2.1.dev6/src/docstring_tailor/main.py +0 -148
- docstring_tailor-0.2.1.dev6/src/docstring_tailor/multi_line_docstring_formatter.py +0 -477
- docstring_tailor-0.2.1.dev6/src/docstring_tailor/utils/__init__.py +0 -1
- docstring_tailor-0.2.1.dev6/src/docstring_tailor/utils/utils_formatting.py +0 -86
- docstring_tailor-0.2.1.dev6/src/docstring_tailor/utils/utils_list_detection.py +0 -88
- docstring_tailor-0.2.1.dev6/tests/cases/__init__.py +0 -1
- docstring_tailor-0.2.1.dev6/tests/cases/formatting_cases.py +0 -90
- docstring_tailor-0.2.1.dev6/tests/fixtures/all_docstrings/all_docstrings_100.py +0 -71
- docstring_tailor-0.2.1.dev6/tests/fixtures/all_docstrings/all_docstrings_60.py +0 -107
- docstring_tailor-0.2.1.dev6/tests/fixtures/all_docstrings/all_docstrings_80.py +0 -85
- docstring_tailor-0.2.1.dev6/tests/fixtures/all_docstrings/all_docstrings_too_long.py +0 -32
- docstring_tailor-0.2.1.dev6/tests/fixtures/all_docstrings/all_docstrings_too_short.py +0 -167
- docstring_tailor-0.2.1.dev6/tests/fixtures/module_docstring_blank_lines/module_docstring_blank_lines.py +0 -8
- docstring_tailor-0.2.1.dev6/tests/fixtures/module_docstring_blank_lines/module_docstring_blank_lines_100.py +0 -6
- docstring_tailor-0.2.1.dev6/tests/fixtures/module_docstring_example_backticks/module_docstring_example_backticks.py +0 -13
- docstring_tailor-0.2.1.dev6/tests/fixtures/module_docstring_example_backticks/module_docstring_example_backticks_60.py +0 -14
- docstring_tailor-0.2.1.dev6/tests/fixtures/module_docstring_example_tildes/module_docstring_example_tildes.py +0 -13
- docstring_tailor-0.2.1.dev6/tests/fixtures/module_docstring_example_tildes/module_docstring_example_tildes_60.py +0 -14
- docstring_tailor-0.2.1.dev6/tests/fixtures/module_docstring_ordered_list/module_docstring_ordered_list_too_long.py +0 -7
- {docstring_tailor-0.2.1.dev6 → docstring_tailor-0.3.0}/.gitignore +0 -0
- {docstring_tailor-0.2.1.dev6 → docstring_tailor-0.3.0}/LICENSE +0 -0
- {docstring_tailor-0.2.1.dev6/src/docstring_tailor → docstring_tailor-0.3.0/tests/cases}/__init__.py +0 -0
- /docstring_tailor-0.2.1.dev6/tests/fixtures/module_docstring_empty/module_docstring_empty_blank_lines.py → /docstring_tailor-0.3.0/tests/fixtures/docstring_elements/empty/empty_blank_lines.py +0 -0
- /docstring_tailor-0.2.1.dev6/tests/fixtures/module_docstring_empty/module_docstring_empty.py → /docstring_tailor-0.3.0/tests/fixtures/docstring_elements/empty/empty_no_space.py +0 -0
- {docstring_tailor-0.2.1.dev6 → docstring_tailor-0.3.0}/tests/fixtures/readme_examples/readme_examples.py +0 -0
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: docstring-tailor
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Formats Python docstrings to PEP 257 style with configurable line length.
|
|
5
|
+
Author-email: Auke Bruinsma <afbruinsma@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Auke Bruinsma
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
29
|
+
Requires-Python: >=3.11
|
|
30
|
+
Requires-Dist: libcst>=1.8.6
|
|
31
|
+
Requires-Dist: typer>=0.26.4
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# Docstring Tailor 🪡
|
|
35
|
+
|
|
36
|
+
Formats Python docstrings to PEP 257 style with configurable line length.
|
|
37
|
+
|
|
38
|
+
[](https://pypi.org/project/docstring-tailor/)
|
|
39
|
+
[](https://pypi.org/project/docstring-tailor/)
|
|
40
|
+
[](https://pypi.org/project/docstring-tailor/)
|
|
41
|
+
[](https://pypi.org/project/docstring-tailor/)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
## Table of Contents
|
|
45
|
+
1. [Demo](#demo)
|
|
46
|
+
2. [Installation](#Installation)
|
|
47
|
+
3. [Quick start](#quick_start)
|
|
48
|
+
4. [API Overview](#api-overview)
|
|
49
|
+
- [Command](#command)
|
|
50
|
+
- [Options](#options)
|
|
51
|
+
- [Examples](#examples)
|
|
52
|
+
5. [Example docstrings](#example-docstrings)
|
|
53
|
+
6. [What Your Line Length Says About You!](#what-your-line-length-says-about-you)
|
|
54
|
+
7. [Resources](#resources)
|
|
55
|
+
8. [Release Notes](#release_notes)
|
|
56
|
+
9. [Roadmap](#roadmap)
|
|
57
|
+
|
|
58
|
+
## Demo
|
|
59
|
+
|
|
60
|
+
<details>
|
|
61
|
+
<summary><b>Show demo</b></summary>
|
|
62
|
+
|
|
63
|
+
<br>
|
|
64
|
+
|
|
65
|
+
- `docstring-tailor` formats docstrings to fit a given line length, while preserving its structure throughout — For exapmle blank lines, argument indentation, continuation line alignment, and code blocks in the Examples section all remain intact.
|
|
66
|
+
- **Note**: The slider in the [Marimo notebook](https://marimo.io/) is not part of the package. It was created solely to illustrate how the output changes continuously as the line length varies.
|
|
67
|
+
|
|
68
|
+
<br>
|
|
69
|
+
|
|
70
|
+
<img src="https://github.com/user-attachments/assets/983ae257-472d-465e-9924-9d90bca10f0d" alt="" />
|
|
71
|
+
<img src="https://i.imgur.com/2uG5HNh.gif" alt="" />
|
|
72
|
+
|
|
73
|
+
If the image does not show, click [here](https://github.com/user-attachments/assets/983ae257-472d-465e-9924-9d90bca10f0d).
|
|
74
|
+
|
|
75
|
+
</details>
|
|
76
|
+
|
|
77
|
+
## Installation
|
|
78
|
+
|
|
79
|
+
Installation with [UV](https://docs.astral.sh/uv/) (recommended)
|
|
80
|
+
```bash
|
|
81
|
+
uv add --dev docstring-tailor
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Or with pip:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pip install docstring-tailor
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Quick start
|
|
91
|
+
|
|
92
|
+
Run on a single file or directory:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
uv run docstring_tailor format my_file.py
|
|
96
|
+
uv run docstring_tailor format my_folder
|
|
97
|
+
```
|
|
98
|
+
Multiple files and/or folders are also accepted. Without a file path or folder path, it will try to locate the `src` folder.
|
|
99
|
+
|
|
100
|
+
The default line length is 100. To customise it:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
uv run docstring_tailor format --line-length 88
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Configure it permanently in `pyproject.toml` or in `docstring_tailor.toml`:
|
|
107
|
+
|
|
108
|
+
```toml
|
|
109
|
+
# pyproject.toml
|
|
110
|
+
[tool.docstring_tailor]
|
|
111
|
+
line-length = 88
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```toml
|
|
115
|
+
# docstring_tailor.toml
|
|
116
|
+
line-length = 88
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Define a docstring style. Two styles are currently supported: [Google](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html) and [NumPy](https://numpydoc.readthedocs.io/en/latest/format.html). Google is the default. Explicit configuration:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
uv run docstring_tailor format --style numpy
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
or in `pyproject.toml`
|
|
126
|
+
|
|
127
|
+
```toml
|
|
128
|
+
[tool.docstring_tailor]
|
|
129
|
+
style = "google"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
To convert existing docstrings from one style to another, use the `convert` command instead:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
uv run docstring_tailor convert my_file.py --from-style google --to-style numpy
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## API Overview
|
|
139
|
+
|
|
140
|
+
### Commands
|
|
141
|
+
|
|
142
|
+
`docstring_tailor` has two commands: `format` and `convert`.
|
|
143
|
+
|
|
144
|
+
**`format`** reformats docstrings in place, in a single style — use this for everyday formatting (adjusting line length, wrapping, whitespace) without changing the docstring style itself.
|
|
145
|
+
|
|
146
|
+
**`convert`** reparses and re-renders docstrings from one style into another — use this the one time you need to migrate a codebase, or part of one, between styles.
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
uv run docstring_tailor format [PATHS ...] [OPTIONS]
|
|
150
|
+
uv run docstring_tailor convert [PATHS ...] --from-style STYLE --to-style STYLE [OPTIONS]
|
|
151
|
+
```
|
|
152
|
+
`PATHS` may contain one or more files and/or directories.
|
|
153
|
+
Examples:
|
|
154
|
+
```bash
|
|
155
|
+
uv run docstring_tailor format my_file.py
|
|
156
|
+
uv run docstring_tailor format src/
|
|
157
|
+
uv run docstring_tailor format src/ tests/test_file.py
|
|
158
|
+
uv run docstring_tailor convert src/ --from-style google --to-style numpy
|
|
159
|
+
```
|
|
160
|
+
If no paths are provided, `docstring_tailor` will attempt to locate and format files inside the `src` directory.
|
|
161
|
+
|
|
162
|
+
### Options
|
|
163
|
+
|
|
164
|
+
#### `format`
|
|
165
|
+
|
|
166
|
+
| <div style="width:140px">Option</div> | <div style="width:50px">Type</div> | <div style="width:80px">Default</div> | Description |
|
|
167
|
+
|---|---|---|---|
|
|
168
|
+
| `--line-length` | `int` | 100 | Maximum number of characters allowed per line after formatting. |
|
|
169
|
+
| `--style` | `str` | google | Docstring style to format to. `google` or `numpy`. |
|
|
170
|
+
| `--exclude` | `str` | — | A glob pattern for paths to exclude. Can be passed multiple times. Single-path patterns (e.g. `tests`, `*.pyi`) match by name anywhere in the tree. Relative patterns (e.g. `src/generated/*.py`) match against the path relative to the project root. |
|
|
171
|
+
| `--diff` | flag | — | Print a unified diff of changes to stdout instead of modifying files. No files are written when this flag is set. |
|
|
172
|
+
|
|
173
|
+
#### `convert`
|
|
174
|
+
|
|
175
|
+
| <div style="width:140px">Option</div> | <div style="width:50px">Type</div> | <div style="width:80px">Default</div> | Description |
|
|
176
|
+
|---|---|---|---|
|
|
177
|
+
| `--from-style` | `str` | *required* | Docstring style to convert from. `google` or `numpy`. |
|
|
178
|
+
| `--to-style` | `str` | *required* | Docstring style to convert to. `google` or `numpy`. Must differ from `--from-style`. |
|
|
179
|
+
| `--line-length` | `int` | 100 | Maximum number of characters allowed per line after formatting. |
|
|
180
|
+
| `--exclude` | `str` | — | A glob pattern for paths to exclude. Can be passed multiple times. Single-path patterns (e.g. `tests`, `*.pyi`) match by name anywhere in the tree. Relative patterns (e.g. `src/generated/*.py`) match against the path relative to the project root. |
|
|
181
|
+
| `--diff` | flag | — | Print a unified diff of changes to stdout instead of modifying files. No files are written when this flag is set. |
|
|
182
|
+
|
|
183
|
+
`--from-style` and `--to-style` have no config-file or default fallback — both must be given explicitly on every `convert` invocation, and must be different from each other.
|
|
184
|
+
|
|
185
|
+
#### Global
|
|
186
|
+
|
|
187
|
+
| <div style="width:140px">Option</div> | <div style="width:50px">Type</div> | <div style="width:80px">Default</div> | Description |
|
|
188
|
+
|---|---|---|---|
|
|
189
|
+
| `--version`, `-V` | flag | — | Print the installed version and exit. |
|
|
190
|
+
| `--help` | flag | — | Show the help message and exit. |
|
|
191
|
+
|
|
192
|
+
### Examples
|
|
193
|
+
|
|
194
|
+
`CLI`
|
|
195
|
+
```bash
|
|
196
|
+
uv run docstring_tailor format src/ --line-length 88
|
|
197
|
+
uv run docstring_tailor format my_file.py --style numpy
|
|
198
|
+
uv run docstring_tailor format src/ --exclude tests --exclude "src/generated/*.py"
|
|
199
|
+
uv run docstring_tailor format src/ --diff
|
|
200
|
+
uv run docstring_tailor convert src/ --from-style google --to-style numpy
|
|
201
|
+
uv run docstring_tailor convert my_file.py --from-style numpy --to-style google --diff
|
|
202
|
+
uv run docstring_tailor --version
|
|
203
|
+
uv run docstring_tailor --help
|
|
204
|
+
```
|
|
205
|
+
`pyproject.toml`
|
|
206
|
+
```toml
|
|
207
|
+
[tool.docstring_tailor]
|
|
208
|
+
line-length = 88
|
|
209
|
+
style = "google"
|
|
210
|
+
exclude = ["tests", "src/generated/*.py"]
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
`docstring_tailor.toml`
|
|
214
|
+
```toml
|
|
215
|
+
line-length = 88
|
|
216
|
+
style = "google"
|
|
217
|
+
exclude = ["tests", "src/generated/*.py"]
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Example docstrings
|
|
221
|
+
|
|
222
|
+
1. [Module docstring](#module-docstring)
|
|
223
|
+
2. [Class docstring](#class-docstring)
|
|
224
|
+
3. [Function docstring](#function-docstring)
|
|
225
|
+
4. [Codeblocks](#codeblocks)
|
|
226
|
+
5. [Other sections](#other-sections)
|
|
227
|
+
6. [Unordered and numbered lists](#unordered-and-numbered-lists)
|
|
228
|
+
|
|
229
|
+
### Module docstring
|
|
230
|
+
|
|
231
|
+
**Google / Numpy** (identical for this example)
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
"""Demonstrates a minimal Google or Numpy style module docstring.
|
|
235
|
+
|
|
236
|
+
This module exists as a formatting example and illustrates the typical
|
|
237
|
+
structure of a docstring, including a concise summary line followed by
|
|
238
|
+
an additional descriptive paragraph.
|
|
239
|
+
"""
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
- Leave a **blank line** between the summary line and the more elaborate description. This applies to both styles.
|
|
243
|
+
|
|
244
|
+
### Class docstring
|
|
245
|
+
|
|
246
|
+
**Google**
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
class ExampleConfiguration:
|
|
250
|
+
"""Represents a configuration object used to demonstrate Google-
|
|
251
|
+
style class docstrings.
|
|
252
|
+
|
|
253
|
+
This class is provided as a formatting example and illustrates how
|
|
254
|
+
attributes are documented consistently in the Google docstring
|
|
255
|
+
style.
|
|
256
|
+
|
|
257
|
+
Attributes:
|
|
258
|
+
example_argument_1 (str): Stores the first configuration value
|
|
259
|
+
provided at initialization.
|
|
260
|
+
example_argument_2 (int): Stores the second configuration
|
|
261
|
+
value provided at initialization.
|
|
262
|
+
"""
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
- The `Attributes` section is recognized by the formatter and triggers special indentation rules for attribute entries.
|
|
266
|
+
- If an attribute's description runs onto the next line, it **must be indented one extra level beyond the attribute name**. The formatter relies on this indentation to tell a new attribute entry apart from a continuation of the previous one.
|
|
267
|
+
|
|
268
|
+
**NumPy**
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
class ExampleConfiguration:
|
|
272
|
+
"""Represents a configuration object used to demonstrate NumPy-
|
|
273
|
+
style class docstrings.
|
|
274
|
+
|
|
275
|
+
This class is provided as a formatting example and illustrates how
|
|
276
|
+
attributes are documented consistently in the NumPy docstring
|
|
277
|
+
style.
|
|
278
|
+
|
|
279
|
+
Attributes
|
|
280
|
+
----------
|
|
281
|
+
example_argument_1 : str
|
|
282
|
+
Stores the first configuration value provided at
|
|
283
|
+
initialization.
|
|
284
|
+
example_argument_2 : int
|
|
285
|
+
Stores the second configuration value provided at
|
|
286
|
+
initialization.
|
|
287
|
+
"""
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
- The `Attributes` section header is followed by a line of dashes matching its length (`----------`).
|
|
291
|
+
- Each attribute is written as `name : type`, and its description starts on the next line. Continuation lines are indented to line up with the description, one level deeper than the `name : type` line.
|
|
292
|
+
|
|
293
|
+
### Function docstring
|
|
294
|
+
|
|
295
|
+
**Google**
|
|
296
|
+
|
|
297
|
+
```python
|
|
298
|
+
def example_function(example_argument_1: str, example_argument_2: int) -> str:
|
|
299
|
+
"""Demonstrates a Google-style function docstring with multiple
|
|
300
|
+
sections.
|
|
301
|
+
|
|
302
|
+
This function exists purely as a formatting example and
|
|
303
|
+
illustrates how Args, Returns, Examples, and Raises sections are
|
|
304
|
+
structured in a Google-style docstring.
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
example_argument_1 (str): First example input value used to
|
|
308
|
+
construct a formatted result string.
|
|
309
|
+
example_argument_2 (int): Second example input value used to
|
|
310
|
+
influence the transformation logic.
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
str: A formatted string combining both input arguments into a
|
|
314
|
+
single human-readable representation.
|
|
315
|
+
|
|
316
|
+
Examples:
|
|
317
|
+
Basic usage with typical inputs produces a simple combined
|
|
318
|
+
string:
|
|
319
|
+
|
|
320
|
+
>>> example_function("alpha", 3)
|
|
321
|
+
'alpha-3'
|
|
322
|
+
|
|
323
|
+
You can also write text in between two Python REPL sections,
|
|
324
|
+
and this part will be formatted, while the two small code
|
|
325
|
+
sections won't be formatted.
|
|
326
|
+
|
|
327
|
+
>>> example_function(
|
|
328
|
+
... "beta",
|
|
329
|
+
... 7,
|
|
330
|
+
... )
|
|
331
|
+
'beta-7'
|
|
332
|
+
|
|
333
|
+
Raises:
|
|
334
|
+
ValueError: Raised when example_argument_2 is negative or
|
|
335
|
+
zero, as only positive integers are considered valid in
|
|
336
|
+
this demonstration.
|
|
337
|
+
"""
|
|
338
|
+
if example_argument_2 <= 0:
|
|
339
|
+
raise ValueError("example_argument_2 must be positive")
|
|
340
|
+
|
|
341
|
+
return f"{example_argument_1}-{example_argument_2}"
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
- `Args`, `Returns`, `Examples`, and `Raises` are all keywords recognized by the package.
|
|
345
|
+
- You can use either `Args` or `Arguments` for the argument section, and `Example` or `Examples` for the example section.
|
|
346
|
+
- As with the `Attributes` section above, add **one extra level of indentation** for the description of an argument, return value, or error, whenever it spans multiple lines.
|
|
347
|
+
- In the `Example(s)` section, start the Python REPL with `>>>` and use `...` for continuation lines, matching Pydoc conventions.
|
|
348
|
+
- These same keywords can also be used in module or class docstrings — for example, an `Args` section in a class docstring, or an `Example(s)` section in a module docstring.
|
|
349
|
+
|
|
350
|
+
**NumPy**
|
|
351
|
+
|
|
352
|
+
```python
|
|
353
|
+
def example_function(example_argument_1: str, example_argument_2: int) -> str:
|
|
354
|
+
"""Demonstrates a NumPy-style function docstring with multiple
|
|
355
|
+
sections.
|
|
356
|
+
|
|
357
|
+
This function exists purely as a formatting example and
|
|
358
|
+
illustrates how Parameters, Returns, Examples, and Raises sections
|
|
359
|
+
are structured in a NumPy-style docstring.
|
|
360
|
+
|
|
361
|
+
Parameters
|
|
362
|
+
----------
|
|
363
|
+
example_argument_1 : str
|
|
364
|
+
First example input value used to construct a formatted
|
|
365
|
+
result string.
|
|
366
|
+
example_argument_2 : int
|
|
367
|
+
Second example input value used to influence the
|
|
368
|
+
transformation logic.
|
|
369
|
+
|
|
370
|
+
Returns
|
|
371
|
+
-------
|
|
372
|
+
str
|
|
373
|
+
A formatted string combining both input arguments into a
|
|
374
|
+
single human-readable representation.
|
|
375
|
+
|
|
376
|
+
Examples
|
|
377
|
+
--------
|
|
378
|
+
Basic usage with typical inputs produces a simple combined string:
|
|
379
|
+
|
|
380
|
+
>>> example_function("alpha", 3)
|
|
381
|
+
'alpha-3'
|
|
382
|
+
|
|
383
|
+
You can also write text in between two Python REPL sections, and
|
|
384
|
+
this part will be formatted, while the two small code sections
|
|
385
|
+
won't be formatted.
|
|
386
|
+
|
|
387
|
+
>>> example_function(
|
|
388
|
+
... "beta",
|
|
389
|
+
... 7,
|
|
390
|
+
... )
|
|
391
|
+
'beta-7'
|
|
392
|
+
|
|
393
|
+
Raises
|
|
394
|
+
------
|
|
395
|
+
ValueError
|
|
396
|
+
Raised when example_argument_2 is negative or zero, as only
|
|
397
|
+
positive integers are considered valid in this demonstration.
|
|
398
|
+
"""
|
|
399
|
+
if example_argument_2 <= 0:
|
|
400
|
+
raise ValueError("example_argument_2 must be positive")
|
|
401
|
+
|
|
402
|
+
return f"{example_argument_1}-{example_argument_2}"
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
- `Parameters`, `Returns`, `Examples`, and `Raises` are all keywords recognized by the package. Each is followed by an underline of dashes matching the header's length.
|
|
406
|
+
- Parameters and return values are documented as `name : type` (or just `type` for a return value), with the description indented on the following line(s).
|
|
407
|
+
- As with the `Attributes` section above, add **one extra level of indentation** for a description that spans multiple lines, so it lines up under the `name : type` entry rather than under the header.
|
|
408
|
+
- In the `Examples` section, start the Python REPL with `>>>` and use `...` for continuation lines, matching Pydoc conventions — same as Google style.
|
|
409
|
+
- These same section keywords can also be used in module or class docstrings — for example, a `Parameters` section in a class docstring, or an `Examples` section in a module docstring.
|
|
410
|
+
|
|
411
|
+
### Codeblocks
|
|
412
|
+
|
|
413
|
+
**Google / Numpy** (identical for this example)
|
|
414
|
+
|
|
415
|
+
```python
|
|
416
|
+
"""Demonstrates a Google or Numpy style module docstring containing
|
|
417
|
+
a code block.
|
|
418
|
+
|
|
419
|
+
This module-level docstring is used as a formatting example and shows
|
|
420
|
+
how code blocks can be embedded inside docstrings using fenced
|
|
421
|
+
delimiters.
|
|
422
|
+
|
|
423
|
+
~~~
|
|
424
|
+
def example_function(x, y):
|
|
425
|
+
return x + y
|
|
426
|
+
~~~
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
- A code block can appear inside the `Example(s)` section, but it doesn't have to — it can also stand on its own outside of it.
|
|
430
|
+
- Either backticks (` ``` `) or tildes (`~~~`) can be used to fence the block, the same way code blocks work in markdown files. This is true for both styles.
|
|
431
|
+
|
|
432
|
+
### Other sections
|
|
433
|
+
|
|
434
|
+
**Google — Yields**
|
|
435
|
+
|
|
436
|
+
```python
|
|
437
|
+
def example_generator(n):
|
|
438
|
+
"""Generators have a ``Yields`` section instead of a ``Returns``
|
|
439
|
+
section.
|
|
440
|
+
|
|
441
|
+
Args:
|
|
442
|
+
n (int): The upper limit of the range to generate, from 0 to
|
|
443
|
+
`n` - 1.
|
|
444
|
+
|
|
445
|
+
Yields:
|
|
446
|
+
int: The next number in the range of 0 to `n` - 1.
|
|
447
|
+
"""
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
**NumPy — Yields**
|
|
451
|
+
|
|
452
|
+
```python
|
|
453
|
+
def example_generator(n):
|
|
454
|
+
"""Generators have a ``Yields`` section instead of a ``Returns``
|
|
455
|
+
section.
|
|
456
|
+
|
|
457
|
+
Parameters
|
|
458
|
+
----------
|
|
459
|
+
n : int
|
|
460
|
+
The upper limit of the range to generate, from 0 to `n` - 1.
|
|
461
|
+
|
|
462
|
+
Yields
|
|
463
|
+
------
|
|
464
|
+
int
|
|
465
|
+
The next number in the range of 0 to `n` - 1.
|
|
466
|
+
"""
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
- `Yields` is supported as a drop-in replacement for `Returns` in both styles, for use in generator functions.
|
|
470
|
+
|
|
471
|
+
**Google — Note**
|
|
472
|
+
|
|
473
|
+
```python
|
|
474
|
+
"""Demonstrates a Google-style module docstring containing a Note
|
|
475
|
+
section.
|
|
476
|
+
|
|
477
|
+
This module-level docstring is used as a formatting example and
|
|
478
|
+
illustrates how additional informational sections can be included
|
|
479
|
+
alongside the main description in a Google-style docstring.
|
|
480
|
+
|
|
481
|
+
Note:
|
|
482
|
+
The formatting of this docstring is intentionally designed to test
|
|
483
|
+
how note sections are detected and preserved during docstring
|
|
484
|
+
transformation.
|
|
485
|
+
"""
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
- `Note` is a supported keyword; you can use either `Note` or `Notes`.
|
|
489
|
+
|
|
490
|
+
**NumPy — Notes**
|
|
491
|
+
|
|
492
|
+
```python
|
|
493
|
+
"""Demonstrates a NumPy-style module docstring containing a Notes
|
|
494
|
+
section.
|
|
495
|
+
|
|
496
|
+
This module-level docstring is used as a formatting example and
|
|
497
|
+
illustrates how additional informational sections can be included
|
|
498
|
+
alongside the main description in a NumPy-style docstring.
|
|
499
|
+
|
|
500
|
+
Notes
|
|
501
|
+
-----
|
|
502
|
+
The formatting of this docstring is intentionally designed to test how
|
|
503
|
+
notes sections are detected and preserved during docstring
|
|
504
|
+
transformation.
|
|
505
|
+
"""
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
- `Notes` is the conventional NumPy keyword for this section (as opposed to `Note`, which is the singular form used in Google style).
|
|
509
|
+
|
|
510
|
+
### Unordered and numbered lists
|
|
511
|
+
|
|
512
|
+
The following examples are valid for **both Google and NumPy** styles, since list formatting isn't tied to a particular section keyword.
|
|
513
|
+
|
|
514
|
+
```python
|
|
515
|
+
"""Demonstrates that docstrings can include structured lists.
|
|
516
|
+
|
|
517
|
+
This module-level docstring is used as a formatting example and shows
|
|
518
|
+
how unordered lists can be represented inside a docstring. Each list
|
|
519
|
+
item is recognized by the formatter and rendered on a separate line.
|
|
520
|
+
|
|
521
|
+
Items:
|
|
522
|
+
- Demonstrates that docstrings may contain structured unordered lists
|
|
523
|
+
that are parsed and formatted consistently by the docstring
|
|
524
|
+
formatter.
|
|
525
|
+
- Shows that each list item is treated as an independent element and
|
|
526
|
+
is wrapped separately when exceeding the configured line length.
|
|
527
|
+
- Illustrates that long list items may span multiple lines while
|
|
528
|
+
preserving indentation and list structure integrity across
|
|
529
|
+
formatting operations.
|
|
530
|
+
"""
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
```python
|
|
534
|
+
"""Demonstrates that docstrings can include structured lists.
|
|
535
|
+
|
|
536
|
+
This module-level docstring is used as a formatting example and shows
|
|
537
|
+
how numbered lists can be represented inside a docstring. Each list
|
|
538
|
+
item is recognized by the formatter and rendered on a separate line.
|
|
539
|
+
|
|
540
|
+
Steps:
|
|
541
|
+
1. Demonstrates that docstrings may contain structured numbered lists
|
|
542
|
+
that are parsed and formatted consistently by the docstring
|
|
543
|
+
formatter.
|
|
544
|
+
2. Shows that each list item is treated as a separate logical element
|
|
545
|
+
and is wrapped independently when exceeding the configured line
|
|
546
|
+
length.
|
|
547
|
+
3. Illustrates that long list items may span multiple lines while
|
|
548
|
+
preserving indentation and list structure integrity across
|
|
549
|
+
formatting operations.
|
|
550
|
+
"""
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
- Unordered and numbered lists can be a nice addition to a docstring from time to time. As with the sections above, **indentation** is what the formatter uses to detect where a new list item begins.
|
|
554
|
+
|
|
555
|
+
## What Your `line-length` says about You!
|
|
556
|
+
|
|
557
|
+
### 60 characters per line — The Minimalist Monk 🧘
|
|
558
|
+
|
|
559
|
+
You believe every character has a purpose and every extra column is a personal failure 😤. You keep your docstrings short, your functions tiny, and your emotional attachment to whitespace surprisingly strong. You don't need room to explain your code because your code should be obvious. If a sentence doesn't fit in 60 characters, you simply rewrite the sentence until it does. Brevity is not a preference for you. Brevity is a lifestyle.
|
|
560
|
+
|
|
561
|
+
### 80 characters per line — The Digital Archaeologist 🦖
|
|
562
|
+
|
|
563
|
+
You have been programming for at least half a century, and you still remember when computers were mysterious machines instead of fancy boxes running websites. You believe software peaked before color displays, and honestly, you are a little disappointed with where things went 😔. You know that everything after assembly was already too high-level and a mistake, because real programming means understanding the machine, not asking some framework to do the work for you. You hate GenAI because you believe thinking is the programmer's job. Python? Far too comfortable. Your motto is simple: real programmers toggle individual transistors. Everything after that is just frameworks ⚙️.
|
|
564
|
+
|
|
565
|
+
### 88 characters per line — The Black Ritualist 🖤
|
|
566
|
+
|
|
567
|
+
You are nostalgic for the comforting embrace of Black, where every formatting decision has already been made for you. You don't want to risk the chaos of choosing your own line length because what if you accidentally become different? 😨 You trust the collective wisdom of the formatter, the community, and the thousands of developers who came before you. You are not afraid of change exactly; you are just very comfortable knowing that Black has already decided your fate. Peace through formatting consistency ✨.
|
|
568
|
+
|
|
569
|
+
### 100 characters per line — The Peacekeeper 🤝
|
|
570
|
+
|
|
571
|
+
You chose 100 characters because you wanted everyone to be happy, including the people who review your code and the people who have to read it on a laptop. You looked at 80 characters and thought it felt a little cramped, but you looked at 120 and felt society was moving too fast 😅. You carefully live in the middle, avoiding formatting wars and unnecessary debates. Nobody writes angry comments about your line length, nobody praises it either, and that quiet neutrality is exactly the comfortable existence you wanted.
|
|
572
|
+
|
|
573
|
+
### 240 characters per line — The Ultrawide Warrior 🖥️
|
|
574
|
+
|
|
575
|
+
You claim you increased your line length because it improves readability, but everyone knows the real reason: you want people to notice your enormous ultrawide monitor. You paid for every pixel, and you refuse to leave any of them unemployed 😎. Your docstrings stretch from one side of the screen to the other just to prove your setup is bigger than everyone else's. Whenever someone questions your line length, you casually mention your monitor resolution, refresh rate, and somehow the GPU model.
|
|
576
|
+
|
|
577
|
+
### 500 characters per line — The Horizon Programmer 🌌
|
|
578
|
+
|
|
579
|
+
You don't wrap text because wrapping is a skill issue. You let photons travel uninterrupted across the entire display because your docstrings deserve the full cinematic experience 🎬. You combine programming with neck exercises, allowing you to safely skip neck day at the gym. You don't use a monitor anymore; you rent a cinema, sit in the back row, and program using a telescope pointed at your code 🔭. Your Git diffs require geological surveys, satellite mapping, and a team of explorers. NASA can read your docstrings from orbit 🚀.
|
|
580
|
+
|
|
581
|
+
## Resources
|
|
582
|
+
|
|
583
|
+
### Core resources
|
|
584
|
+
|
|
585
|
+
| <div style="width:70px">Resource</div> | <div style="width:100px">Description</div> | <div style="width:130px">Link</div>
|
|
586
|
+
|---|---|---|
|
|
587
|
+
| PEP 257 - Docstring Conventions | Documents the semantics and conventions associated with Python docstrings. | [Link](https://peps.python.org/pep-0257/) |
|
|
588
|
+
| Google Python Style Guide | Lists *dos and don'ts* for Python programs. | [Link](https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings) |
|
|
589
|
+
| Numpy Style Guide | Describes the syntax and best practices for docstrings used with the numpydoc extension for Sphinx | [Link](https://numpydoc.readthedocs.io/en/latest/format.html) |
|
|
590
|
+
| Types of indentation | Wikipedia article that defines different kinds of indentation | [Link](https://en.wikipedia.org/wiki/Indentation_(typesetting)) |
|
|
591
|
+
|
|
592
|
+
### Additional resources
|
|
593
|
+
|
|
594
|
+
| <div style="width:70px">Resource</div> | <div style="width:100px">Description</div> | <div style="width:130px">Link</div>
|
|
595
|
+
|---|---|---|
|
|
596
|
+
| PEP 8 - Style Guide for Python Code | Gives coding conventions for the Python code comprising the standard library in the main Python distribution. | [Link](https://peps.python.org/pep-0008/) |
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
## Release Notes
|
|
600
|
+
|
|
601
|
+
| <div style="width:70px">Version</div> | <div style="width:100px">Release date</div> | <div style="width:130px">Type</div> | Details |
|
|
602
|
+
|---|---|---|---|
|
|
603
|
+
| `0.1.0` | 2026-05-31 | Initial release | First public release of `docstring-tailor`. Includes <ul><li>Automatic docstring wrapping for module, class and function docstrings, for both one line and multi line docstrings, with a configurable `line-length` parameter.</li><li>Paragraph-aware formatting, differentiating between 'Args', 'Examples' or normal text sections.</li> <li> Docstring support for the Google `style` (Numpy, Sphinx, Epydoc not yet supported). </li><li>TOML-based configuration support.</li><li> Test coverage: 52% </ul> |
|
|
604
|
+
| `0.1.1` | 2026-05-31 | Documentation update | Updated the `README.md` file with the 'Installation' and 'Quick Start' section. |
|
|
605
|
+
| `0.2.0` | 2026-06-07 | Feature update | <ul><li>Implemented the `detect-lists` parameter, adding support for unordered and ordered (numbered) lists in docstrings. When enabled, list structures are detected automatically and each list item is formatted onto its own line.</li><li>Introduced a declarative golden-file test framework for formatter validation. Test cases are now generated from parametrized templates using Cartesian-product expansion, significantly reducing boilerplate and improving scalability for configuration coverage.</li><li>Expanded this `README.md` with the 'API Overview', 'Release Notes', 'Example docstrings' and 'Roadmap' sections.</li><li>Test coverage: 75%</li></ul> |
|
|
606
|
+
| `0.2.1` | 2026-06-11 | Feature update | <ul><li>Added the `-V`/`--version` command to the CLI.</li><li>Added the `--exclude` command to the CLI.</li><li>Added the `--diff` command to the CLI.</li><li>Added the 'Demo' part to to the `README.md`.</ul> |
|
|
607
|
+
| `0.3.0` | 2026-07-20 | Feature update & bug fixes | <ul><li>Introduced a style-agnostic intermediate representation (IR) model and refactored parsing into an abstract base class hierarchy. Google and NumPy docstrings now parse into the same IR via `IndentationBasedParser` subclasses, enabling lossless conversion between styles. Structured list parsing is delegated to style-specific implementations to handle syntactic differences (Google's inline `name (type):` vs. NumPy's `name : type` on separate lines).</li><li>Refactored rendering to match the parser architecture: `DocstringRendererBase` (ABC) with style-specific subclasses that implement two hooks — section header formatting (Google's `Args:` vs. NumPy's `Parameters` + underline) and section body indentation rules (confirmed against numpy's own docstrings to keep bodies flush with headers, unlike Google). Keyword translation between styles happens automatically during conversion.</li><li>Code sections and Python REPL blocks now also can be created outside the 'Example(s)' section.</li><li>Fixed a bug when codeblock sections contain blank lines.</li><li>Fixed a bug when the docstring starts immediately with an (un)ordered list.</li><li>Removed `detect-lists` as CLI parameter, because the logic should always be applied if the docstring contains (un)ordered lists.</li><li>Changed behaviour for empty docstrings so that it consistent with Ruff.</li></ul> |
|
|
608
|
+
|
|
609
|
+
## Roadmap
|
|
610
|
+
|
|
611
|
+
### Must have
|
|
612
|
+
- Parsing-time validation: the parser enforces structural rules on a docstring
|
|
613
|
+
(e.g. well-formed sections, consistent indentation, correctly closed lists and
|
|
614
|
+
code blocks) and rejects it if those rules aren't met. Formatting, rendering, and
|
|
615
|
+
conversion must never run on a docstring that fails this check — malformed input
|
|
616
|
+
should be refused at the parsing stage, not silently passed through. A dedicated
|
|
617
|
+
lint/check command exposes these errors directly to the user, with clear and
|
|
618
|
+
actionable messages, rather than only blocking format/convert silently.
|
|
619
|
+
- Parsing module for the remaining docstring formats (Sphinx, Epydoc), extending
|
|
620
|
+
the existing style-agnostic intermediate representation (IR) to cover all four
|
|
621
|
+
major styles.
|
|
622
|
+
- Formatting module for the remaining docstring formats (Sphinx, Epydoc), driven
|
|
623
|
+
entirely by the same IR already used for Google and NumPy.
|
|
624
|
+
|
|
625
|
+
### Nice to have
|
|
626
|
+
- Make sure the package can be used as a pre-commit hook.
|
|
627
|
+
- LSP (Language Server Protocol) support, enabling real-time feedback on malformed
|
|
628
|
+
docstrings directly in editors like VS Code, PyCharm and Neovim. Built on top of
|
|
629
|
+
the validation layer and the existing parser, with `pygls` handling the protocol.
|
|
630
|
+
Requires position tracking in the IR (line/column numbers per node) as a
|
|
631
|
+
prerequisite, for precise diagnostics and editor highlighting.
|
|
632
|
+
- Make the package available as a VSCode extension.
|
|
633
|
+
|
|
634
|
+
### Maybe later
|
|
635
|
+
- Parameter that allows the user to format module, class and function docstrings
|
|
636
|
+
independently.
|