docstringify 1.1.0__tar.gz → 1.1.1__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.
- {docstringify-1.1.0 → docstringify-1.1.1}/PKG-INFO +1 -1
- {docstringify-1.1.0 → docstringify-1.1.1}/pyproject.toml +1 -1
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/nodes/base.py +10 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/traversal/transformer.py +55 -9
- {docstringify-1.1.0 → docstringify-1.1.1}/uv.lock +1 -1
- {docstringify-1.1.0 → docstringify-1.1.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/.github/dependabot.yml +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/.github/pull_request_template.md +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/.github/release.yml +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/.github/workflows/ci.yml +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/.github/workflows/greetings.yml +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/.github/workflows/pypi-publish.yml +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/.gitignore +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/.pre-commit-config.yaml +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/.pre-commit-hooks.yaml +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/.python-version +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/CODE_OF_CONDUCT.md +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/CONTRIBUTING.md +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/LICENSE +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/README.md +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/__init__.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/__main__.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/cli.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/components.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/converters/__init__.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/converters/base.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/converters/google.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/converters/numpydoc.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/converters/stub.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/exceptions.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/nodes/__init__.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/nodes/function.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/traversal/__init__.py +0 -0
- {docstringify-1.1.0 → docstringify-1.1.1}/src/docstringify/traversal/visitor.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docstringify
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: Flag missing docstrings and, optionally, generate them from signatures and type annotations.
|
|
5
5
|
Project-URL: Documentation, https://github.com/stefmolin/docstringify
|
|
6
6
|
Project-URL: Homepage, https://github.com/stefmolin/docstringify
|
|
@@ -70,6 +70,16 @@ class DocstringNode:
|
|
|
70
70
|
)
|
|
71
71
|
"""Callable to get the source code for the AST node (:attr:`.ast_node`)."""
|
|
72
72
|
|
|
73
|
+
self.original_docstring_location: tuple[int, int] | None = (
|
|
74
|
+
None
|
|
75
|
+
if self.docstring is None
|
|
76
|
+
else (self.ast_node.body[0].lineno, self.ast_node.body[0].end_lineno)
|
|
77
|
+
)
|
|
78
|
+
"""Start and end line of the docstring in the original file, if there was one,
|
|
79
|
+
otherwise, ``None``. This is necessary for the rewriting algorithm to exclude
|
|
80
|
+
lines containing "empty" docstrings from the file. Empty docstrings are empty
|
|
81
|
+
strings or strings containing only whitespace characters."""
|
|
82
|
+
|
|
73
83
|
@property
|
|
74
84
|
def docstring(self) -> str | None:
|
|
75
85
|
"""
|
|
@@ -6,6 +6,7 @@ on the source code.
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
import ast
|
|
9
|
+
import itertools
|
|
9
10
|
from textwrap import indent
|
|
10
11
|
from typing import TYPE_CHECKING
|
|
11
12
|
|
|
@@ -79,6 +80,7 @@ class DocstringTransformer(ast.NodeTransformer, DocstringVisitor):
|
|
|
79
80
|
source_code = self.source_code.splitlines()
|
|
80
81
|
output_lines = []
|
|
81
82
|
write_line = start_line = 0
|
|
83
|
+
skip_lines = None
|
|
82
84
|
|
|
83
85
|
for missing_docstring in self.missing_docstrings:
|
|
84
86
|
docstring_node = missing_docstring.ast_node.body[0]
|
|
@@ -88,28 +90,72 @@ class DocstringTransformer(ast.NodeTransformer, DocstringVisitor):
|
|
|
88
90
|
# write everything before docstring
|
|
89
91
|
if not isinstance(missing_docstring.ast_node, ast.Module):
|
|
90
92
|
# line before a code node
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if
|
|
94
|
-
start_line =
|
|
95
|
-
|
|
93
|
+
skip_lines = missing_docstring.original_docstring_location
|
|
94
|
+
|
|
95
|
+
if skip_lines:
|
|
96
|
+
start_line = skip_lines[-1]
|
|
97
|
+
else:
|
|
98
|
+
# search for the start of the body code (may be comment, blank line,
|
|
99
|
+
# an empty docstring, etc.). restrict the search to between the
|
|
100
|
+
# class/function definition start and the first body item
|
|
101
|
+
search_end_line_number = missing_docstring.ast_node.body[1].lineno
|
|
102
|
+
node_source_code = missing_docstring.get_source_segment(
|
|
103
|
+
missing_docstring.ast_node
|
|
104
|
+
).splitlines()[
|
|
105
|
+
: search_end_line_number - missing_docstring.ast_node.lineno
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
expected_indent = ' ' * 4
|
|
109
|
+
for line_number, line in zip(
|
|
110
|
+
itertools.count(start=search_end_line_number, step=-1),
|
|
111
|
+
node_source_code[::-1],
|
|
112
|
+
strict=False,
|
|
113
|
+
):
|
|
114
|
+
# starting from the end line of the search to the definition
|
|
115
|
+
# line, the first, non-empty line without the required indent
|
|
116
|
+
# will be the start of the body logic
|
|
117
|
+
if line and not line.startswith(expected_indent):
|
|
118
|
+
start_line = line_number
|
|
119
|
+
break
|
|
120
|
+
|
|
121
|
+
if start_line == missing_docstring.ast_node.body[1].lineno:
|
|
122
|
+
# the above logic handles multiline definitions, but if it is
|
|
123
|
+
# a single line and code is immediately afterward, we need to
|
|
124
|
+
# make sure to not overwrite that
|
|
125
|
+
start_line = docstring_node.lineno
|
|
126
|
+
elif (
|
|
127
|
+
skip_lines is None
|
|
128
|
+
and start_line < missing_docstring.ast_node.body[1].lineno
|
|
129
|
+
):
|
|
130
|
+
start_line -= 1
|
|
131
|
+
|
|
132
|
+
# handle edge case of "single line" definitions like `def test(): ...`
|
|
96
133
|
if len(body := missing_docstring.ast_node.body) == 2:
|
|
97
134
|
code_node = body[1]
|
|
98
135
|
line_number = code_node.lineno - 1
|
|
99
136
|
line = source_code[line_number]
|
|
100
137
|
|
|
101
138
|
if line.strip() != (function_body := line[code_node.col_offset :]):
|
|
102
|
-
# if the function body is on the same line as the signature,
|
|
103
|
-
# in order to inject the docstring in the right spot
|
|
139
|
+
# if the function body is on the same line as the signature,
|
|
140
|
+
# cut it out in order to inject the docstring in the right spot
|
|
104
141
|
source_code[line_number] = source_code[line_number][
|
|
105
142
|
: code_node.col_offset
|
|
106
143
|
].rstrip()
|
|
107
144
|
|
|
108
145
|
# add the logic under the docstring
|
|
109
|
-
start_line =
|
|
146
|
+
start_line = body[1].lineno
|
|
110
147
|
suffix = function_body
|
|
111
148
|
|
|
112
|
-
|
|
149
|
+
if skip_lines:
|
|
150
|
+
# need to skip over the empty docstring in the original file
|
|
151
|
+
# note that line numbers are one-based so we have to account for that
|
|
152
|
+
# in the slicing logic
|
|
153
|
+
output_lines += (
|
|
154
|
+
source_code[write_line : skip_lines[0] - 1]
|
|
155
|
+
+ source_code[skip_lines[1] : start_line]
|
|
156
|
+
)
|
|
157
|
+
else:
|
|
158
|
+
output_lines += source_code[write_line:start_line]
|
|
113
159
|
|
|
114
160
|
# write docstring
|
|
115
161
|
if not (docstring := missing_docstring.docstring):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|