format-docstring 0.2.1__tar.gz → 0.2.3__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.2.1 → format_docstring-0.2.3}/.pre-commit-config.yaml +19 -10
- {format_docstring-0.2.1 → format_docstring-0.2.3}/CHANGELOG.md +19 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/PKG-INFO +11 -11
- {format_docstring-0.2.1 → format_docstring-0.2.3}/README.md +5 -5
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring/base_fixer.py +2 -2
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring/config.py +5 -4
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring/docstring_rewriter.py +102 -27
- format_docstring-0.2.3/format_docstring/line_wrap_google.py +15 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring/line_wrap_numpy.py +31 -26
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring/line_wrap_utils.py +21 -19
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring/main_jupyter.py +6 -6
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring/main_py.py +5 -3
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring.egg-info/PKG-INFO +11 -11
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring.egg-info/SOURCES.txt +1 -0
- format_docstring-0.2.3/muff.toml +116 -0
- format_docstring-0.2.3/pyproject.toml +58 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/helpers.py +5 -2
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_base_fixer.py +4 -3
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_config.py +3 -3
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/fix_rst_backticks.txt +1 -1
- format_docstring-0.2.3/tests/test_data/end_to_end/numpy/signature_sync_class_docstrings.txt +203 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/signature_sync_parameters.txt +57 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_docstring_rewriter.py +24 -14
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_line_wrap_numpy.py +20 -13
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_line_wrap_utils.py +12 -10
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_main_jupyter.py +4 -4
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_main_py.py +4 -4
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tox.ini +0 -7
- format_docstring-0.2.1/format_docstring/line_wrap_google.py +0 -13
- format_docstring-0.2.1/muff.toml +0 -48
- format_docstring-0.2.1/pyproject.toml +0 -60
- {format_docstring-0.2.1 → format_docstring-0.2.3}/.github/workflows/python-package.yml +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/.github/workflows/python-publish.yml +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/.gitignore +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/.pre-commit-hooks.yaml +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/AGENTS.md +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/LICENSE +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring/__init__.py +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring.egg-info/dependency_links.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring.egg-info/entry_points.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring.egg-info/requires.txt +1 -1
- {format_docstring-0.2.1 → format_docstring-0.2.3}/format_docstring.egg-info/top_level.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/requirements.dev +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/setup.cfg +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/__init__.py +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/README.md +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/colon_spacing_fix.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/contents_that_are_not_wrapped.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/default_value_standardization.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/empty_lines_are_respected.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/examples_section.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/existing_linebreaks_should_not_be_respected.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/four_level_nested_classes.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/indent_four_levels_16_spaces_width_10.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/indent_misaligned_all.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/indent_two_levels_8_spaces.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/line_length_2.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/mismatched_underlines.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/mismatched_underlines_one_dash.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/mismatched_underlines_two_dashes.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/module_level_docstring.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/new_lines_before_and_after.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/no_format_docstring_comment.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/param_signature_without_type.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/parameters_returns_raises_wrapping.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/returns_signature_and_description.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/section_headings_with_colons.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/section_title_fixed.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/sections_notes_examples.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/signature_dont_sync_raises.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/signature_line_is_not_wrapped.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/signature_sync_returns.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/signature_sync_yields.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/single_line_docstring.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/texts_are_rewrapped.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/end_to_end/numpy/very_long_unbreakable_word.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/integration_test/numpy/after.ipynb +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/integration_test/numpy/after.py +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/integration_test/numpy/after_50.ipynb +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/integration_test/numpy/after_50.py +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/integration_test/numpy/before.ipynb +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/integration_test/numpy/before.py +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/jupyter/before.ipynb +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/jupyter/verbose_before.ipynb +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/README.md +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/colon_spacing_fix.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/contents_that_are_not_wrapped.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/default_value_standardization.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/empty_lines_are_respected.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/examples_section.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/existing_linebreaks_should_not_be_respected.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/fix_rst_backticks.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/indent_four_levels_16_spaces_width_10.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/indent_two_levels_8_spaces.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/line_length_2.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/mismatched_underlines.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/mismatched_underlines_one_dash.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/mismatched_underlines_two_dashes.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/module_level_docstring.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/param_signature_without_type.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/parameters_returns_raises_wrapping.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/returns_signature_and_description.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/section_headings_with_colons.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/section_title_fixed.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/sections_notes_examples.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/signature_line_is_not_wrapped.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/texts_are_rewrapped.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/line_wrap/numpy/very_long_unbreakable_word.txt +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_data/playground.py +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_line_wrap_google.py +0 -0
- {format_docstring-0.2.1 → format_docstring-0.2.3}/tests/test_playground.py +0 -0
|
@@ -6,10 +6,7 @@ repos:
|
|
|
6
6
|
- id: trailing-whitespace
|
|
7
7
|
- id: end-of-file-fixer
|
|
8
8
|
exclude: \.json$|\.ipynb$
|
|
9
|
-
- id: debug-statements
|
|
10
|
-
- id: double-quote-string-fixer
|
|
11
9
|
- id: requirements-txt-fixer
|
|
12
|
-
exclude: \.ipynb$
|
|
13
10
|
- id: check-added-large-files
|
|
14
11
|
args: [--maxkb=1000]
|
|
15
12
|
- id: check-toml
|
|
@@ -18,11 +15,6 @@ repos:
|
|
|
18
15
|
args: [--pytest-test-first]
|
|
19
16
|
exclude: ^tests/test_data/|^tests/helpers\.py$
|
|
20
17
|
- id: check-merge-conflict
|
|
21
|
-
- repo: https://github.com/asottile/pyupgrade
|
|
22
|
-
rev: v3.20.0
|
|
23
|
-
hooks:
|
|
24
|
-
- id: pyupgrade
|
|
25
|
-
args: [--py310-plus]
|
|
26
18
|
- repo: https://github.com/jsh9/muff-pre-commit
|
|
27
19
|
rev: 0.13.2
|
|
28
20
|
hooks:
|
|
@@ -37,11 +29,27 @@ repos:
|
|
|
37
29
|
rev: 1.18.0
|
|
38
30
|
hooks:
|
|
39
31
|
- id: yamlfix
|
|
32
|
+
- repo: https://github.com/pappasam/toml-sort
|
|
33
|
+
rev: v0.24.2
|
|
34
|
+
hooks:
|
|
35
|
+
- id: toml-sort-fix
|
|
36
|
+
args:
|
|
37
|
+
- --in-place
|
|
38
|
+
- --sort-table-keys
|
|
39
|
+
- --sort-inline-tables
|
|
40
|
+
- --sort-first=name,version,dependencies,requires-python,authors,maintainers
|
|
41
|
+
- --trailing-comma-inline-array
|
|
42
|
+
- --sort-inline-arrays
|
|
43
|
+
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
|
|
44
|
+
rev: v2.15.0
|
|
45
|
+
hooks:
|
|
46
|
+
- id: pretty-format-ini
|
|
47
|
+
args: [--autofix]
|
|
40
48
|
- repo: https://github.com/hukkin/mdformat
|
|
41
49
|
rev: 1.0.0
|
|
42
50
|
hooks:
|
|
43
51
|
- id: mdformat
|
|
44
|
-
args: [--wrap
|
|
52
|
+
args: [--wrap=79, --number]
|
|
45
53
|
additional_dependencies: [mdformat-gfm]
|
|
46
54
|
- repo: https://github.com/jsh9/format-json
|
|
47
55
|
rev: 0.1.2
|
|
@@ -54,9 +62,10 @@ repos:
|
|
|
54
62
|
- --no-sort-keys
|
|
55
63
|
- --no-eof-newline
|
|
56
64
|
- repo: https://github.com/jsh9/markdown-toc-creator
|
|
57
|
-
rev: 0.0
|
|
65
|
+
rev: 0.1.0
|
|
58
66
|
hooks:
|
|
59
67
|
- id: markdown-toc-creator
|
|
68
|
+
exclude: ^tests/test_data/|^AGENTS\.md$|^CHANGELOG\.md$
|
|
60
69
|
- repo: https://github.com/jsh9/markdown-heading-numbering
|
|
61
70
|
rev: 0.1.0
|
|
62
71
|
hooks:
|
|
@@ -6,6 +6,25 @@ 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.3] - 2025-10-22
|
|
10
|
+
|
|
11
|
+
- Added
|
|
12
|
+
- A lot more linters
|
|
13
|
+
- Formatters for TOML and INI config files
|
|
14
|
+
- Changed
|
|
15
|
+
- A lot of code changes to pass the linter checks
|
|
16
|
+
- Removed
|
|
17
|
+
- Unnecessary pre-commit hooks
|
|
18
|
+
- Full diff
|
|
19
|
+
- https://github.com/jsh9/format-docstring/compare/0.2.2...0.2.3
|
|
20
|
+
|
|
21
|
+
## [0.2.2] - 2025-10-20
|
|
22
|
+
|
|
23
|
+
- Added
|
|
24
|
+
- Formatting support for type hints and default values in class docstrings
|
|
25
|
+
- Full diff
|
|
26
|
+
- https://github.com/jsh9/format-docstring/compare/0.2.1...0.2.2
|
|
27
|
+
|
|
9
28
|
## [0.2.1] - 2025-10-20
|
|
10
29
|
|
|
11
30
|
- Fixed
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: format-docstring
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
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>
|
|
7
7
|
License: MIT
|
|
8
8
|
Project-URL: Homepage, https://github.com/your/repo
|
|
9
|
-
Project-URL: Repository, https://github.com/your/repo.git
|
|
10
9
|
Project-URL: Issues, https://github.com/your/repo/issues
|
|
11
|
-
|
|
10
|
+
Project-URL: Repository, https://github.com/your/repo.git
|
|
11
|
+
Keywords: code-style,docstring,formatter,python
|
|
12
12
|
Classifier: Development Status :: 3 - Alpha
|
|
13
13
|
Classifier: Environment :: Console
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: License :: OSI Approved :: MIT License
|
|
16
16
|
Classifier: Operating System :: OS Independent
|
|
17
|
-
Classifier: Programming Language :: Python
|
|
18
|
-
Classifier: Programming Language :: Python :: 3
|
|
19
17
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python
|
|
23
23
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
24
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
25
25
|
Requires-Python: >=3.10
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
License-File: LICENSE
|
|
28
|
-
Requires-Dist: jupyter-notebook-parser>=0.1.4
|
|
29
28
|
Requires-Dist: click>=8.0
|
|
29
|
+
Requires-Dist: jupyter-notebook-parser>=0.1.4
|
|
30
30
|
Requires-Dist: tomli>=1.1.0; python_version < "3.11"
|
|
31
31
|
Dynamic: license-file
|
|
32
32
|
|
|
@@ -34,11 +34,11 @@ Dynamic: license-file
|
|
|
34
34
|
|
|
35
35
|
A Python formatter to automatically format numpy-style docstrings.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
<!--TOC-->
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
______________________________________________________________________
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
**Table of Contents**
|
|
42
42
|
|
|
43
43
|
- [1. Overview](#1-overview)
|
|
44
44
|
- [2. Before vs After Examples](#2-before-vs-after-examples)
|
|
@@ -59,10 +59,10 @@ ______________________________________________________________________
|
|
|
59
59
|
- [5.3. `pyproject.toml` Configuration](#53-pyprojecttoml-configuration)
|
|
60
60
|
- [6. Caveat](#6-caveat)
|
|
61
61
|
|
|
62
|
-
<!--TOC-->
|
|
63
|
-
|
|
64
62
|
______________________________________________________________________
|
|
65
63
|
|
|
64
|
+
<!--TOC-->
|
|
65
|
+
|
|
66
66
|
## 1. Overview
|
|
67
67
|
|
|
68
68
|
`format-docstring` is a tool that automatically formats and wraps docstring
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
A Python formatter to automatically format numpy-style docstrings.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<!--TOC-->
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
______________________________________________________________________
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**Table of Contents**
|
|
10
10
|
|
|
11
11
|
- [1. Overview](#1-overview)
|
|
12
12
|
- [2. Before vs After Examples](#2-before-vs-after-examples)
|
|
@@ -27,10 +27,10 @@ ______________________________________________________________________
|
|
|
27
27
|
- [5.3. `pyproject.toml` Configuration](#53-pyprojecttoml-configuration)
|
|
28
28
|
- [6. Caveat](#6-caveat)
|
|
29
29
|
|
|
30
|
-
<!--TOC-->
|
|
31
|
-
|
|
32
30
|
______________________________________________________________________
|
|
33
31
|
|
|
32
|
+
<!--TOC-->
|
|
33
|
+
|
|
34
34
|
## 1. Overview
|
|
35
35
|
|
|
36
36
|
`format-docstring` is a tool that automatically formats and wraps docstring
|
|
@@ -15,7 +15,7 @@ class BaseFixer:
|
|
|
15
15
|
----------
|
|
16
16
|
path : str
|
|
17
17
|
Target file or directory to process.
|
|
18
|
-
exclude_pattern : str, default='\.git|\.tox|\.pytest_cache'
|
|
18
|
+
exclude_pattern : str, default=r'\.git|\.tox|\.pytest_cache'
|
|
19
19
|
Regular expression describing paths to skip.
|
|
20
20
|
verbose : str, default='default'
|
|
21
21
|
Verbosity mode; ``'diff'`` prints unified diffs for rewritten files.
|
|
@@ -42,7 +42,7 @@ class BaseFixer:
|
|
|
42
42
|
if not should_exclude_file(f, self.exclude_pattern)
|
|
43
43
|
]
|
|
44
44
|
|
|
45
|
-
def
|
|
45
|
+
def print_diff(self, filename: str, before: str, after: str) -> None:
|
|
46
46
|
"""Print a unified diff when verbose mode is enabled."""
|
|
47
47
|
if self.verbose != 'diff':
|
|
48
48
|
return
|
|
@@ -4,9 +4,10 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import sys
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
import click
|
|
10
11
|
|
|
11
12
|
if sys.version_info >= (3, 11):
|
|
12
13
|
import tomllib
|
|
@@ -132,7 +133,7 @@ def load_config_from_file(config_file: Path) -> dict[str, Any]:
|
|
|
132
133
|
return {}
|
|
133
134
|
|
|
134
135
|
try:
|
|
135
|
-
with open(
|
|
136
|
+
with Path(config_file).open('rb') as fp:
|
|
136
137
|
raw_config = tomllib.load(fp)
|
|
137
138
|
|
|
138
139
|
# Extract [tool.format_docstring] section
|
|
@@ -144,7 +145,7 @@ def load_config_from_file(config_file: Path) -> dict[str, Any]:
|
|
|
144
145
|
return {
|
|
145
146
|
k.replace('-', '_'): v for k, v in format_docstring_section.items()
|
|
146
147
|
}
|
|
147
|
-
except Exception:
|
|
148
|
+
except Exception: # noqa: BLE001
|
|
148
149
|
# If there's any error reading/parsing the file, return empty config
|
|
149
150
|
return {}
|
|
150
151
|
|
|
@@ -2,14 +2,18 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import ast
|
|
4
4
|
import io
|
|
5
|
+
import operator
|
|
5
6
|
import tokenize
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
6
8
|
|
|
7
9
|
from format_docstring.line_wrap_google import wrap_docstring_google
|
|
8
10
|
from format_docstring.line_wrap_numpy import (
|
|
9
11
|
handle_single_line_docstring,
|
|
10
12
|
wrap_docstring_numpy,
|
|
11
13
|
)
|
|
12
|
-
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from format_docstring.line_wrap_utils import ParameterMetadata
|
|
13
17
|
|
|
14
18
|
ModuleClassOrFunc = (
|
|
15
19
|
ast.Module | ast.ClassDef | ast.FunctionDef | ast.AsyncFunctionDef
|
|
@@ -91,11 +95,13 @@ def _normalize_signature_segment(segment: str | None) -> str | None:
|
|
|
91
95
|
# iterator order mirrors the unparse traversal so we can reapply them.
|
|
92
96
|
original_strings: list[str] = []
|
|
93
97
|
try:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
98
|
+
original_strings.extend(
|
|
99
|
+
tok.string
|
|
100
|
+
for tok in tokenize.generate_tokens(
|
|
101
|
+
io.StringIO(normalized).readline
|
|
102
|
+
)
|
|
103
|
+
if tok.type == tokenize.STRING
|
|
104
|
+
)
|
|
99
105
|
except tokenize.TokenError:
|
|
100
106
|
original_strings = []
|
|
101
107
|
|
|
@@ -105,6 +111,7 @@ def _normalize_signature_segment(segment: str | None) -> str | None:
|
|
|
105
111
|
for tok in tokenize.generate_tokens(
|
|
106
112
|
io.StringIO(canonical).readline
|
|
107
113
|
):
|
|
114
|
+
current_tok: tokenize.TokenInfo = tok
|
|
108
115
|
if tok.type == tokenize.STRING:
|
|
109
116
|
replacement = next(string_iter, None)
|
|
110
117
|
if replacement is not None:
|
|
@@ -116,12 +123,12 @@ def _normalize_signature_segment(segment: str | None) -> str | None:
|
|
|
116
123
|
if ast.literal_eval(
|
|
117
124
|
replacement
|
|
118
125
|
) == ast.literal_eval(tok.string):
|
|
119
|
-
|
|
120
|
-
except Exception:
|
|
126
|
+
current_tok = tok._replace(string=replacement)
|
|
127
|
+
except Exception: # noqa: BLE001
|
|
121
128
|
pass
|
|
122
129
|
|
|
123
|
-
rebuilt_tokens.append(
|
|
124
|
-
if
|
|
130
|
+
rebuilt_tokens.append(current_tok)
|
|
131
|
+
if current_tok.type == tokenize.ENDMARKER:
|
|
125
132
|
break
|
|
126
133
|
|
|
127
134
|
# Untokenize the rebuilt stream while trimming the leading/trailing
|
|
@@ -221,6 +228,53 @@ def _collect_param_metadata(
|
|
|
221
228
|
return metadata
|
|
222
229
|
|
|
223
230
|
|
|
231
|
+
def _collect_class_metadata(
|
|
232
|
+
node: ast.ClassDef,
|
|
233
|
+
source_code: str,
|
|
234
|
+
) -> tuple[ParameterMetadata, ParameterMetadata]:
|
|
235
|
+
"""
|
|
236
|
+
Build metadata for class docstrings using ``__init__`` and class attrs.
|
|
237
|
+
"""
|
|
238
|
+
init_metadata: ParameterMetadata = {}
|
|
239
|
+
attribute_metadata: ParameterMetadata = {}
|
|
240
|
+
|
|
241
|
+
init_method: ast.FunctionDef | None = None
|
|
242
|
+
for stmt in node.body:
|
|
243
|
+
if isinstance(stmt, ast.FunctionDef) and stmt.name == '__init__':
|
|
244
|
+
init_method = stmt
|
|
245
|
+
break
|
|
246
|
+
|
|
247
|
+
if init_method is not None:
|
|
248
|
+
init_metadata = _collect_param_metadata(init_method, source_code)
|
|
249
|
+
# ``self``/``cls`` rarely appear in docstrings; drop to avoid noise.
|
|
250
|
+
init_metadata.pop('self', None)
|
|
251
|
+
init_metadata.pop('cls', None)
|
|
252
|
+
|
|
253
|
+
for stmt in node.body:
|
|
254
|
+
if isinstance(stmt, ast.AnnAssign):
|
|
255
|
+
target = stmt.target
|
|
256
|
+
if not isinstance(target, ast.Name):
|
|
257
|
+
continue
|
|
258
|
+
|
|
259
|
+
annotation = _render_signature_piece(stmt.annotation, source_code)
|
|
260
|
+
default = _render_signature_piece(stmt.value, source_code)
|
|
261
|
+
attribute_metadata[target.id] = (annotation, default)
|
|
262
|
+
continue
|
|
263
|
+
|
|
264
|
+
if isinstance(stmt, ast.Assign):
|
|
265
|
+
if len(stmt.targets) != 1:
|
|
266
|
+
continue
|
|
267
|
+
|
|
268
|
+
assign_target = stmt.targets[0]
|
|
269
|
+
if not isinstance(assign_target, ast.Name):
|
|
270
|
+
continue
|
|
271
|
+
|
|
272
|
+
# Record that this attribute explicitly has no annotation/default.
|
|
273
|
+
attribute_metadata[assign_target.id] = ('', None)
|
|
274
|
+
|
|
275
|
+
return init_metadata, attribute_metadata
|
|
276
|
+
|
|
277
|
+
|
|
224
278
|
def fix_src(
|
|
225
279
|
source_code: str,
|
|
226
280
|
*,
|
|
@@ -255,19 +309,20 @@ def fix_src(
|
|
|
255
309
|
spans directly in the original text to preserve non-docstring formatting
|
|
256
310
|
and comments.
|
|
257
311
|
"""
|
|
258
|
-
tree: ast.Module = ast.parse(source_code)
|
|
312
|
+
tree: ast.Module = ast.parse(source_code, type_comments=True)
|
|
259
313
|
line_starts: list[int] = calc_line_starts(source_code)
|
|
260
314
|
|
|
315
|
+
# Store (start, end, replacement text) tuples
|
|
261
316
|
replacements: list[tuple[int, int, str]] = []
|
|
262
317
|
|
|
263
318
|
# Module-level docstring
|
|
264
319
|
replacement = build_replacement_docstring(
|
|
265
320
|
tree,
|
|
266
|
-
source_code,
|
|
267
|
-
line_starts,
|
|
268
|
-
line_length,
|
|
269
|
-
docstring_style,
|
|
270
|
-
fix_rst_backticks,
|
|
321
|
+
source_code=source_code,
|
|
322
|
+
line_starts=line_starts,
|
|
323
|
+
line_length=line_length,
|
|
324
|
+
docstring_style=docstring_style,
|
|
325
|
+
fix_rst_backticks=fix_rst_backticks,
|
|
271
326
|
)
|
|
272
327
|
if replacement is not None:
|
|
273
328
|
replacements.append(replacement)
|
|
@@ -279,11 +334,11 @@ def fix_src(
|
|
|
279
334
|
):
|
|
280
335
|
replacement = build_replacement_docstring(
|
|
281
336
|
node,
|
|
282
|
-
source_code,
|
|
283
|
-
line_starts,
|
|
284
|
-
line_length,
|
|
285
|
-
docstring_style,
|
|
286
|
-
fix_rst_backticks,
|
|
337
|
+
source_code=source_code,
|
|
338
|
+
line_starts=line_starts,
|
|
339
|
+
line_length=line_length,
|
|
340
|
+
docstring_style=docstring_style,
|
|
341
|
+
fix_rst_backticks=fix_rst_backticks,
|
|
287
342
|
)
|
|
288
343
|
if replacement is not None:
|
|
289
344
|
replacements.append(replacement)
|
|
@@ -292,7 +347,8 @@ def fix_src(
|
|
|
292
347
|
if not replacements:
|
|
293
348
|
return source_code
|
|
294
349
|
|
|
295
|
-
|
|
350
|
+
# Sort by starting index descending
|
|
351
|
+
replacements.sort(key=operator.itemgetter(0), reverse=True)
|
|
296
352
|
new_src = source_code
|
|
297
353
|
for start, end, text in replacements:
|
|
298
354
|
new_src = new_src[:start] + text + new_src[end:]
|
|
@@ -324,6 +380,7 @@ def calc_line_starts(source_code: str) -> list[int]:
|
|
|
324
380
|
|
|
325
381
|
def build_replacement_docstring(
|
|
326
382
|
node: ModuleClassOrFunc,
|
|
383
|
+
*,
|
|
327
384
|
source_code: str,
|
|
328
385
|
line_starts: list[int],
|
|
329
386
|
line_length: int,
|
|
@@ -364,7 +421,7 @@ def build_replacement_docstring(
|
|
|
364
421
|
return None
|
|
365
422
|
|
|
366
423
|
start: int = calc_abs_pos(line_starts, val.lineno, val.col_offset)
|
|
367
|
-
end: int = calc_abs_pos(line_starts, val.end_lineno, val.end_col_offset) # type: ignore[arg-type]
|
|
424
|
+
end: int = calc_abs_pos(line_starts, val.end_lineno, val.end_col_offset) # type: ignore[arg-type]
|
|
368
425
|
original_literal = source_code[start:end]
|
|
369
426
|
|
|
370
427
|
if _has_inline_no_format_comment(source_code, end):
|
|
@@ -387,10 +444,20 @@ def build_replacement_docstring(
|
|
|
387
444
|
)
|
|
388
445
|
|
|
389
446
|
param_metadata: ParameterMetadata | None = None
|
|
447
|
+
attribute_metadata: ParameterMetadata | None = None
|
|
390
448
|
return_annotation: str | None = None
|
|
391
449
|
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
392
450
|
param_metadata = _collect_param_metadata(node, source_code)
|
|
393
451
|
return_annotation = _render_signature_piece(node.returns, source_code)
|
|
452
|
+
elif isinstance(node, ast.ClassDef):
|
|
453
|
+
init_metadata, class_attr_metadata = _collect_class_metadata(
|
|
454
|
+
node, source_code
|
|
455
|
+
)
|
|
456
|
+
if init_metadata:
|
|
457
|
+
param_metadata = init_metadata
|
|
458
|
+
|
|
459
|
+
if class_attr_metadata:
|
|
460
|
+
attribute_metadata = class_attr_metadata
|
|
394
461
|
|
|
395
462
|
wrapped: str = wrap_docstring(
|
|
396
463
|
doc,
|
|
@@ -400,6 +467,7 @@ def build_replacement_docstring(
|
|
|
400
467
|
fix_rst_backticks=fix_rst_backticks,
|
|
401
468
|
function_param_metadata=param_metadata,
|
|
402
469
|
function_return_annotation=return_annotation,
|
|
470
|
+
class_attribute_metadata=attribute_metadata,
|
|
403
471
|
)
|
|
404
472
|
|
|
405
473
|
new_literal: str | None = rebuild_literal(original_literal, wrapped)
|
|
@@ -496,10 +564,10 @@ def rebuild_literal(original_literal: str, content: str) -> str | None:
|
|
|
496
564
|
prefix = original_literal[:i]
|
|
497
565
|
|
|
498
566
|
delim = ''
|
|
499
|
-
if original_literal[i : i + 3] in
|
|
567
|
+
if original_literal[i : i + 3] in {'"""', "'''"}:
|
|
500
568
|
delim = original_literal[i : i + 3]
|
|
501
569
|
i += 3
|
|
502
|
-
elif i < n and original_literal[i] in
|
|
570
|
+
elif i < n and original_literal[i] in {'"', "'"}:
|
|
503
571
|
delim = original_literal[i]
|
|
504
572
|
i += 1
|
|
505
573
|
else:
|
|
@@ -518,9 +586,11 @@ def wrap_docstring(
|
|
|
518
586
|
line_length: int = 79,
|
|
519
587
|
docstring_style: str = 'numpy',
|
|
520
588
|
leading_indent: int = 0,
|
|
589
|
+
*,
|
|
521
590
|
fix_rst_backticks: bool = True,
|
|
522
591
|
function_param_metadata: ParameterMetadata | None = None,
|
|
523
592
|
function_return_annotation: str | None = None,
|
|
593
|
+
class_attribute_metadata: ParameterMetadata | None = None,
|
|
524
594
|
) -> str:
|
|
525
595
|
"""
|
|
526
596
|
Wrap a docstring to the given line length (stub).
|
|
@@ -544,6 +614,9 @@ def wrap_docstring(
|
|
|
544
614
|
function_return_annotation : str | None, default=None
|
|
545
615
|
The function's return annotation text (normalized), used to keep
|
|
546
616
|
``Returns``/``Yields`` signature lines synchronized.
|
|
617
|
+
class_attribute_metadata : ParameterMetadata | None, default=None
|
|
618
|
+
Attribute metadata for class docstrings (names mapped to annotations
|
|
619
|
+
and default values) collected from class-level assignments.
|
|
547
620
|
|
|
548
621
|
Returns
|
|
549
622
|
-------
|
|
@@ -560,18 +633,20 @@ def wrap_docstring(
|
|
|
560
633
|
if style == 'google':
|
|
561
634
|
return wrap_docstring_google(
|
|
562
635
|
docstring,
|
|
563
|
-
line_length,
|
|
636
|
+
line_length=line_length,
|
|
564
637
|
leading_indent=leading_indent,
|
|
565
638
|
fix_rst_backticks=fix_rst_backticks,
|
|
566
639
|
parameter_metadata=function_param_metadata,
|
|
567
640
|
return_annotation=function_return_annotation,
|
|
641
|
+
attribute_metadata=class_attribute_metadata,
|
|
568
642
|
)
|
|
569
643
|
# Default to NumPy-style for unknown/unspecified styles to be permissive.
|
|
570
644
|
return wrap_docstring_numpy(
|
|
571
645
|
docstring,
|
|
572
|
-
line_length,
|
|
646
|
+
line_length=line_length,
|
|
573
647
|
leading_indent=leading_indent,
|
|
574
648
|
fix_rst_backticks=fix_rst_backticks,
|
|
575
649
|
parameter_metadata=function_param_metadata,
|
|
650
|
+
attribute_metadata=class_attribute_metadata,
|
|
576
651
|
return_annotation=function_return_annotation,
|
|
577
652
|
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from format_docstring.line_wrap_utils import ParameterMetadata
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def wrap_docstring_google(
|
|
5
|
+
docstring: str, # noqa: ARG001
|
|
6
|
+
*,
|
|
7
|
+
line_length: int, # noqa: ARG001
|
|
8
|
+
leading_indent: int | None = None, # noqa: ARG001
|
|
9
|
+
fix_rst_backticks: bool = True, # noqa: ARG001
|
|
10
|
+
parameter_metadata: ParameterMetadata | None = None, # noqa: ARG001
|
|
11
|
+
return_annotation: str | None = None, # noqa: ARG001
|
|
12
|
+
attribute_metadata: ParameterMetadata | None = None, # noqa: ARG001
|
|
13
|
+
) -> str:
|
|
14
|
+
"""A placeholder for now.""" # noqa: D401
|
|
15
|
+
return ''
|