format-docstring 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,165 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import sys
5
+ from pathlib import Path
6
+ from typing import Any
7
+
8
+ import click
9
+ from jupyter_notebook_parser import (
10
+ JupyterNotebookParser,
11
+ JupyterNotebookRewriter,
12
+ SourceCodeContainer,
13
+ reconstruct_source,
14
+ )
15
+
16
+ import format_docstring.docstring_rewriter as doc_rewriter
17
+ from format_docstring import __version__
18
+ from format_docstring.base_fixer import BaseFixer
19
+ from format_docstring.config import inject_config_from_file
20
+
21
+
22
+ @click.command()
23
+ @click.version_option(version=__version__)
24
+ @click.argument('paths', nargs=-1, type=click.Path())
25
+ @click.option(
26
+ '--config',
27
+ type=click.Path(exists=False, file_okay=True, dir_okay=False),
28
+ is_eager=True,
29
+ callback=inject_config_from_file,
30
+ default='pyproject.toml',
31
+ help=(
32
+ 'Path to a pyproject.toml config file. '
33
+ 'If not specified, searches for pyproject.toml in parent directories. '
34
+ 'Command-line options take precedence over config file settings.'
35
+ ),
36
+ )
37
+ @click.option(
38
+ '--exclude',
39
+ type=str,
40
+ default=r'\.git|\.tox|\.pytest_cache',
41
+ help='Regex pattern to exclude files/directories',
42
+ )
43
+ @click.option(
44
+ '--line-length',
45
+ type=int,
46
+ default=79,
47
+ show_default=True,
48
+ help='Maximum line length for wrapping docstrings',
49
+ )
50
+ @click.option(
51
+ '--docstring-style',
52
+ type=click.Choice(['numpy', 'google'], case_sensitive=False),
53
+ default='numpy',
54
+ show_default=True,
55
+ help='Docstring style to target',
56
+ )
57
+ def main(
58
+ paths: tuple[str, ...],
59
+ config: str | None, # noqa: ARG001 (used by Click callback)
60
+ exclude: str,
61
+ line_length: int,
62
+ docstring_style: str,
63
+ ) -> None:
64
+ """Format .ipynb files."""
65
+ ret = 0
66
+ for path in paths:
67
+ fixer = JupyterNotebookFixer(
68
+ path=path, exclude_pattern=exclude, line_length=line_length
69
+ )
70
+ fixer.docstring_style = docstring_style
71
+ ret |= fixer.fix_one_directory_or_one_file()
72
+
73
+ if ret != 0:
74
+ raise SystemExit(ret)
75
+
76
+
77
+ class JupyterNotebookFixer(BaseFixer):
78
+ """Fixer for Jupyter notebook files."""
79
+
80
+ def __init__(
81
+ self,
82
+ path: str,
83
+ exclude_pattern: str = r'\.git|\.tox|\.pytest_cache',
84
+ line_length: int = 79,
85
+ ) -> None:
86
+ super().__init__(path=path, exclude_pattern=exclude_pattern)
87
+ self.line_length = line_length
88
+ self.docstring_style: str = 'numpy'
89
+
90
+ def fix_one_directory_or_one_file(self) -> int:
91
+ """Fix formatting in a file or all .ipynb files in a directory."""
92
+ from pathlib import Path
93
+
94
+ path_obj = Path(self.path)
95
+
96
+ if path_obj.is_file():
97
+ return self.fix_one_file(path_obj.as_posix())
98
+
99
+ # Process .ipynb files instead of .py files for Jupyter notebooks
100
+ filenames = self._get_files_to_process(path_obj, '*.ipynb')
101
+ all_status = set()
102
+ for filename in filenames:
103
+ status = self.fix_one_file(str(filename))
104
+ all_status.add(status)
105
+
106
+ return 0 if not all_status or all_status == {0} else 1
107
+
108
+ def fix_one_file(self, filename: str) -> int:
109
+ """Fix formatting in a single Jupyter notebook file."""
110
+ file_path = Path(filename)
111
+ if not file_path.is_file():
112
+ msg = f'{filename} is not a file (skipping)'
113
+ print(msg, file=sys.stderr)
114
+ return 0
115
+
116
+ try:
117
+ parsed: JupyterNotebookParser = JupyterNotebookParser(filename)
118
+ rewriter: JupyterNotebookRewriter = JupyterNotebookRewriter(
119
+ parsed_notebook=parsed
120
+ )
121
+ code_cells: list[dict[str, Any]] = parsed.get_code_cells()
122
+ code_cell_indices: list[int] = parsed.get_code_cell_indices()
123
+ code_cell_sources: list[SourceCodeContainer] = (
124
+ parsed.get_code_cell_sources()
125
+ )
126
+ except Exception as exc:
127
+ print(f'Error reading {filename}: {str(exc)}', file=sys.stderr)
128
+ return 1
129
+ else:
130
+ ret_val = 0
131
+ assert len(code_cells) == len(code_cell_indices)
132
+ assert len(code_cells) == len(code_cell_sources)
133
+
134
+ for i in range(len(code_cells)):
135
+ index: int = code_cell_indices[i]
136
+ source: SourceCodeContainer = code_cell_sources[i]
137
+ source_without_magic: str = source.source_without_magic
138
+ magics: dict[str, str] = source.magics
139
+ fixed: str = doc_rewriter.fix_src(
140
+ source_code=source_without_magic,
141
+ line_length=self.line_length,
142
+ docstring_style=self.docstring_style,
143
+ )
144
+
145
+ if fixed != source_without_magic:
146
+ ret_val = 1
147
+ fixed_with_magics = reconstruct_source(fixed, magics)
148
+ rewriter.replace_source_in_code_cell(
149
+ index=index,
150
+ new_source=fixed_with_magics,
151
+ )
152
+
153
+ if ret_val == 1:
154
+ print(f'Rewriting {filename}', file=sys.stderr)
155
+ with open(filename, 'w') as fp:
156
+ json.dump(parsed.notebook_content, fp, indent=1)
157
+ # Jupyter notebooks (.ipynb) always ends with a new line
158
+ # but json.dump does not.
159
+ fp.write('\n')
160
+
161
+ return ret_val
162
+
163
+
164
+ if __name__ == '__main__':
165
+ raise SystemExit(main())
@@ -0,0 +1,125 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ import click
7
+
8
+ import format_docstring.docstring_rewriter as rewriter
9
+ from format_docstring import __version__
10
+ from format_docstring.base_fixer import BaseFixer
11
+ from format_docstring.config import inject_config_from_file
12
+
13
+
14
+ @click.command()
15
+ @click.version_option(version=__version__)
16
+ @click.argument('paths', nargs=-1, type=click.Path())
17
+ @click.option(
18
+ '--config',
19
+ type=click.Path(exists=False, file_okay=True, dir_okay=False),
20
+ is_eager=True,
21
+ callback=inject_config_from_file,
22
+ default='pyproject.toml',
23
+ help=(
24
+ 'Path to a pyproject.toml config file. '
25
+ 'If not specified, searches for pyproject.toml in parent directories. '
26
+ 'Command-line options take precedence over config file settings.'
27
+ ),
28
+ )
29
+ @click.option(
30
+ '--exclude',
31
+ type=str,
32
+ default=r'\.git|\.tox|\.pytest_cache',
33
+ help='Regex pattern to exclude files/directories',
34
+ )
35
+ @click.option(
36
+ '--line-length',
37
+ type=int,
38
+ default=79,
39
+ show_default=True,
40
+ help='Maximum line length for wrapping docstrings',
41
+ )
42
+ @click.option(
43
+ '--docstring-style',
44
+ type=click.Choice(['numpy', 'google'], case_sensitive=False),
45
+ default='numpy',
46
+ show_default=True,
47
+ help='Docstring style to target',
48
+ )
49
+ def main(
50
+ paths: tuple[str, ...],
51
+ config: str | None, # noqa: ARG001 (used by Click callback)
52
+ exclude: str,
53
+ line_length: int,
54
+ docstring_style: str,
55
+ ) -> None:
56
+ """Format .py files."""
57
+ ret = 0
58
+
59
+ if docstring_style.lower() != 'numpy':
60
+ raise ValueError('Only "numpy" style is supported for now.')
61
+
62
+ for path in paths:
63
+ fixer = PythonFileFixer(
64
+ path=path, exclude_pattern=exclude, line_length=line_length
65
+ )
66
+ fixer.docstring_style = docstring_style
67
+ ret |= fixer.fix_one_directory_or_one_file()
68
+
69
+ if ret != 0:
70
+ raise SystemExit(ret)
71
+
72
+
73
+ class PythonFileFixer(BaseFixer):
74
+ """Fixer for Python source files."""
75
+
76
+ def __init__(
77
+ self,
78
+ path: str,
79
+ exclude_pattern: str = r'\.git|\.tox|\.pytest_cache',
80
+ line_length: int = 79,
81
+ ) -> None:
82
+ super().__init__(path=path, exclude_pattern=exclude_pattern)
83
+ self.line_length = line_length
84
+ self.docstring_style: str = 'numpy'
85
+
86
+ def fix_one_file(self, filename: str) -> int:
87
+ """Fix formatting in a single Python file."""
88
+ if filename == '-':
89
+ source_bytes: bytes = sys.stdin.buffer.read()
90
+ else:
91
+ file_path: Path = Path(filename)
92
+ if not file_path.is_file():
93
+ msg: str = f'{filename} is not a file (skipping)'
94
+ print(msg, file=sys.stderr)
95
+ return 0
96
+
97
+ with open(filename, 'rb') as fb:
98
+ source_bytes = fb.read()
99
+
100
+ try:
101
+ source_text: str = source_bytes.decode()
102
+ source_text_orig: str = source_text
103
+ except UnicodeDecodeError:
104
+ error_msg: str = f'{filename} is non-utf-8 (not supported)'
105
+ print(error_msg, file=sys.stderr)
106
+ return 1
107
+
108
+ source_text = rewriter.fix_src(
109
+ source_text,
110
+ line_length=self.line_length,
111
+ docstring_style=self.docstring_style,
112
+ )
113
+
114
+ if filename == '-':
115
+ print(source_text, end='')
116
+ elif source_text != source_text_orig:
117
+ print(f'Rewriting {filename}', file=sys.stderr)
118
+ with open(filename, 'wb') as f:
119
+ f.write(source_text.encode())
120
+
121
+ return int(source_text != source_text_orig)
122
+
123
+
124
+ if __name__ == '__main__':
125
+ raise SystemExit(main())
@@ -0,0 +1,311 @@
1
+ Metadata-Version: 2.4
2
+ Name: format-docstring
3
+ Version: 0.1.0
4
+ Summary: A Python formatter to wrap/adjust docstring lines
5
+ Author-email: jsh9 <25124332+jsh9@users.noreply.github.com>
6
+ Maintainer-email: jsh9 <25124332+jsh9@users.noreply.github.com>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/your/repo
9
+ Project-URL: Repository, https://github.com/your/repo.git
10
+ Project-URL: Issues, https://github.com/your/repo/issues
11
+ Keywords: formatter,code-style,docstring,python
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: Software Development :: Quality Assurance
25
+ Requires-Python: >=3.10
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: jupyter-notebook-parser>=0.1.4
29
+ Requires-Dist: click>=8.0
30
+ Requires-Dist: docstring_parser_fork>=0.0.14
31
+ Requires-Dist: tomli>=1.1.0; python_version < "3.11"
32
+ Dynamic: license-file
33
+
34
+ # format-docstring
35
+
36
+ A Python formatter to automatically format numpy-style docstrings.
37
+
38
+ **Table of Contents:**
39
+
40
+ <!--TOC-->
41
+
42
+ - [1. Overview](#1-overview)
43
+ - [2. Before vs After Examples](#2-before-vs-after-examples)
44
+ - [2.1. Long lines are wrapped to fit line length limit](#21-long-lines-are-wrapped-to-fit-line-length-limit)
45
+ - [2.2. One-line summaries are formatted to fit line length limit](#22-one-line-summaries-are-formatted-to-fit-line-length-limit)
46
+ - [2.3. Minor typos can be automatically fixed](#23-minor-typos-can-be-automatically-fixed)
47
+ - [2.4. Default value declarations are standardized](#24-default-value-declarations-are-standardized)
48
+ - [3. Installation](#3-installation)
49
+ - [4. Usage](#4-usage)
50
+ - [4.1. Command Line Interface](#41-command-line-interface)
51
+ - [4.2. Pre-commit Hook](#42-pre-commit-hook)
52
+ - [5. Configuration](#5-configuration)
53
+ - [5.1. Command-Line Options](#51-command-line-options)
54
+ - [5.2. Usage Examples](#52-usage-examples)
55
+ - [5.3. `pyproject.toml` Configuration](#53-pyprojecttoml-configuration)
56
+
57
+ <!--TOC-->
58
+
59
+ ## 1. Overview
60
+
61
+ `format-docstring` is a tool that automatically formats and wraps docstring
62
+ content in Python files and Jupyter notebooks.
63
+
64
+ Compared with [`docformatter`](https://github.com/PyCQA/docformatter) and
65
+ [`pydocstringformatter`](https://github.com/DanielNoord/pydocstringformatter),
66
+ this tool (`format-docstring`) goes further by intelligently wrapping docstring
67
+ contents, fixing common typos, etc.
68
+
69
+ The formatting that would be done by
70
+ [docformatter](https://github.com/PyCQA/docformatter) and
71
+ [pydocstringformatter](https://github.com/DanielNoord/pydocstringformatter) can
72
+ be readily handled by [Ruff](https://github.com/astral-sh/ruff) or
73
+ [Black](https://github.com/psf/black).
74
+
75
+ ## 2. Before vs After Examples
76
+
77
+ ### 2.1. Long lines are wrapped to fit line length limit
78
+
79
+ ```diff
80
+ def example_function(param1, param2, option='default'):
81
+ - """This summary line is intentionally very long and exceeds the line length limit to demonstrate that format-docstring will automatically wrap it across multiple lines while preserving code structure.
82
+ + """
83
+ + This summary line is intentionally very long and exceeds the line length
84
+ + limit to demonstrate that format-docstring will automatically wrap it
85
+ + across multiple lines while preserving code structure.
86
+
87
+ Parameters
88
+ ----------
89
+ - param1 : str
90
+ - This parameter description is also intentionally long to show how parameter descriptions get wrapped when they exceed the configured line length limit
91
+ - param2 : int
92
+ - Another long parameter description that demonstrates the wrapping behavior for parameter documentation in NumPy-style docstrings
93
+ + param1 : str
94
+ + This parameter description is also intentionally long to show how
95
+ + parameter descriptions get wrapped when they exceed the configured
96
+ + line length limit
97
+ + param2 : int
98
+ + Another long parameter description that demonstrates the wrapping
99
+ + behavior for parameter documentation in NumPy-style docstrings
100
+ option : str, optional
101
+ Short description (not wrapped)
102
+
103
+ Returns
104
+ -------
105
+ dict
106
+ - The return value wrapped, because it is a very long line that exceeds line length limit by a lot.
107
+ + The return value wrapped, because it is a very long line that exceeds
108
+ + line length limit by a lot.
109
+
110
+ Examples
111
+ --------
112
+ Code examples with >>> prompts are preserved without wrapping:
113
+
114
+ >>> result = example_function('test', 42, option='custom_value_with_a_very_long_name_that_exceeds_line_length')
115
+ >>> print(result)
116
+ {'status': 'success'}
117
+
118
+ rST tables are preserved without wrapping:
119
+
120
+ =========== ================== ===============================
121
+ Format Wrapped Preserved
122
+ =========== ================== ===============================
123
+ Text Yes No (in tables, code, lists)
124
+ Params Yes Signature lines preserved
125
+ =========== ================== ===============================
126
+
127
+ Content following double colons (::) is preserved::
128
+
129
+ - This indented block after :: is not wrapped
130
+ - Even if lines are very long they stay intact
131
+ - Useful for code blocks or literal content
132
+
133
+ Regular bullet lists are also preserved:
134
+
135
+ - First bullet point that is intentionally long but not wrapped
136
+ - Second point also stays on one line regardless of length
137
+ """
138
+ ```
139
+
140
+ ### 2.2. One-line summaries are formatted to fit line length limit
141
+
142
+ ```diff
143
+ def my_function():
144
+ - """Contents are short, but with quotation marks this exceeds length limit."""
145
+ + """
146
+ + Contents are short, but with quotation marks this exceeds length limit.
147
+ + """
148
+ pass
149
+ ```
150
+
151
+ ### 2.3. Minor typos can be automatically fixed
152
+
153
+ ```diff
154
+ def mu_function():
155
+ """
156
+ Minor typos in section titles or "signatures" can be fixed.
157
+
158
+ - Parameter
159
+ - ----
160
+ + Parameters
161
+ + ----------
162
+ arg1 : str
163
+ Arg 1
164
+ arg2 : bool
165
+ Arg 2
166
+ - arg3: int
167
+ + arg3 : int
168
+ Arg 3
169
+ - arg4 : int
170
+ + arg4 : int
171
+ Arg 4
172
+
173
+ - ReTurn
174
+ - ----------
175
+ + Returns
176
+ + -------
177
+ int
178
+ The return value
179
+ """
180
+ pass
181
+ ```
182
+
183
+ ### 2.4. Default value declarations are standardized
184
+
185
+ ```diff
186
+ def example_function(arg1, arg2, arg3, arg4):
187
+ """
188
+ Parameters
189
+ ----------
190
+ - arg1 : int default 10
191
+ + arg1 : int, default=10
192
+ First argument
193
+ - arg2 : str, default "hello"
194
+ + arg2 : str, default="hello"
195
+ Second argument
196
+ - arg3 : bool, default is True
197
+ + arg3 : bool, default=True
198
+ Third argument
199
+ - arg4 : float default: 3.14
200
+ + arg4 : float, default=3.14
201
+ Fourth argument
202
+ """
203
+ pass
204
+ ```
205
+
206
+ ## 3. Installation
207
+
208
+ ```bash
209
+ pip install format-docstring
210
+ ```
211
+
212
+ ## 4. Usage
213
+
214
+ ### 4.1. Command Line Interface
215
+
216
+ **For Python files:**
217
+
218
+ ```bash
219
+ format-docstring path/to/file.py
220
+ format-docstring path/to/directory/
221
+ ```
222
+
223
+ **For Jupyter notebooks:**
224
+
225
+ ```bash
226
+ format-docstring-jupyter path/to/notebook.ipynb
227
+ format-docstring-jupyter path/to/directory/
228
+ ```
229
+
230
+ ### 4.2. Pre-commit Hook
231
+
232
+ To use `format-docstring` as a pre-commit hook, add this to your
233
+ `.pre-commit-config.yaml`:
234
+
235
+ ```yaml
236
+ repos:
237
+ - repo: https://github.com/jsh9/format-docstring
238
+ rev: <LATEST_VERSION>
239
+ hooks:
240
+ - id: format-docstring
241
+ name: Format docstrings in .py files
242
+ args: [--line-length=79]
243
+ - id: format-docstring-jupyter
244
+ name: Format docstrings in .ipynb files
245
+ args: [--line-length=79]
246
+ ```
247
+
248
+ Then install the pre-commit hook:
249
+
250
+ ```bash
251
+ pre-commit install
252
+ ```
253
+
254
+ ## 5. Configuration
255
+
256
+ ### 5.1. Command-Line Options
257
+
258
+ - `--line-length INTEGER`: Maximum line length for wrapping docstrings
259
+ (default: 79)
260
+ - `--docstring-style CHOICE`: Docstring style to target (`numpy` or `google`,
261
+ default: `numpy`). Note: Currently only `numpy` style is fully supported.
262
+ - `--exclude TEXT`: Regex pattern to exclude files/directories (default:
263
+ `\.git|\.tox|\.pytest_cache`)
264
+ - `--config PATH`: Path to a `pyproject.toml` config file. If not specified,
265
+ the tool automatically searches for `pyproject.toml` in parent directories.
266
+ Command-line options take precedence over config file settings.
267
+ - `--version`: Show version information
268
+ - `--help`: Show help message
269
+
270
+ ### 5.2. Usage Examples
271
+
272
+ ```bash
273
+ # Format a single file with default settings
274
+ format-docstring my_module.py
275
+
276
+ # Format all Python files in a directory with custom line length
277
+ format-docstring --line-length 72 src/
278
+
279
+ # Format Jupyter notebooks excluding certain directories
280
+ format-docstring-jupyter --exclude "\.git|\.venv|__pycache__" notebooks/
281
+
282
+ # Use a specific config file
283
+ format-docstring --config path/to/pyproject.toml src/
284
+
285
+ # CLI options override config file settings
286
+ format-docstring --config pyproject.toml --line-length 100 src/
287
+ ```
288
+
289
+ ### 5.3. `pyproject.toml` Configuration
290
+
291
+ You can configure default values in your `pyproject.toml`. CLI arguments will
292
+ override these settings:
293
+
294
+ ```toml
295
+ [tool.format_docstring]
296
+ line_length = 79
297
+ docstring_style = "numpy"
298
+ exclude = "\\.git|\\.venv|__pycache__"
299
+ ```
300
+
301
+ **Available options:**
302
+
303
+ - `line_length` (int): Maximum line length for wrapping docstrings (default:
304
+ 79\)
305
+ - `docstring_style` (str): Docstring style, either `"numpy"` or `"google"`
306
+ (default: `"numpy"`)
307
+ - `exclude` (str): Regex pattern to exclude files/directories (default:
308
+ `"\\.git|\\.tox|\\.pytest_cache"`)
309
+
310
+ The tool searches for `pyproject.toml` starting from the target file/directory
311
+ and walking up the parent directories until one is found.
@@ -0,0 +1,15 @@
1
+ format_docstring/__init__.py,sha256=3bPK0B7mVsgqXVtcJYGKBO8JAM5gYWmdQPaRrI2tpsI,146
2
+ format_docstring/base_fixer.py,sha256=bXbIa9v6LUQXcHYLU5byuB1xo614hGoRKdnR9T3q4oc,2121
3
+ format_docstring/config.py,sha256=2VvOL1AaYM-ODCZf-U3R3ptePR_DMZXnOVItbpp6yns,5528
4
+ format_docstring/docstring_rewriter.py,sha256=bhLWep_-5Qe5XgWI8cBdpZSZPbVurrUGx1IzNob-5zE,9068
5
+ format_docstring/line_wrap_google.py,sha256=arwHkcDybu2K8TCq7UtIiZF8gq4nlcWy0KzDf3bEcZc,191
6
+ format_docstring/line_wrap_numpy.py,sha256=e0QvPeyf4pVl_1KKbVoKuuxGWGyLxJkMsqUu2q814FY,12924
7
+ format_docstring/line_wrap_utils.py,sha256=NCx8JA6GZdVvvudh5u_YbLrDte7R5lMXQ681N22043w,24389
8
+ format_docstring/main_jupyter.py,sha256=7WrbQhuoONHn3W4hOECPSXyXWr8BnJBK96KlNBORrLI,5458
9
+ format_docstring/main_py.py,sha256=l3Rzd1h02erBqpTMtaqDfr9HFtXjxiUATEfsK8-3804,3690
10
+ format_docstring-0.1.0.dist-info/licenses/LICENSE,sha256=UNm_-hqU-1dAB3bLytP6wvGtUeitoJde2xzb5wgVYn0,1061
11
+ format_docstring-0.1.0.dist-info/METADATA,sha256=iZofojbHoJgmTcrXz2CV2fhFFii-EA-U4HdHksVwUf4,9970
12
+ format_docstring-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
+ format_docstring-0.1.0.dist-info/entry_points.txt,sha256=Re2iHTzfgKJgeXDga5Z4bGNPtWGmxupOdzTolwn52sk,129
14
+ format_docstring-0.1.0.dist-info/top_level.txt,sha256=NXPwfHm_1YwwGuetwtK3pJv0jXwXelqPTNCFpm5LQyE,17
15
+ format_docstring-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ format-docstring = format_docstring.main_py:main
3
+ format-docstring-jupyter = format_docstring.main_jupyter:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 jsh9
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ format_docstring