docstring-generator-ext 2.0.11__tar.gz → 2.0.13__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_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/PKG-INFO +1 -1
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/docstring_generator_ext.egg-info/PKG-INFO +1 -1
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/docstring_generator_ext.egg-info/SOURCES.txt +3 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/pyproject.toml +1 -1
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/setup.py +1 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/FunctionFormat.cpp +34 -56
- docstring_generator_ext-2.0.13/src/FunctionFormat.hpp +123 -0
- docstring_generator_ext-2.0.13/src/GoogleDocstring.cpp +153 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/GoogleDocstring.hpp +1 -0
- docstring_generator_ext-2.0.13/src/IDocstringFormat.cpp +55 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/IDocstringFormat.hpp +2 -0
- docstring_generator_ext-2.0.13/src/NumpyDocstring.cpp +140 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/NumpyDocstring.hpp +1 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/ReStructuredDocstring.cpp +15 -7
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/ReStructuredDocstring.hpp +2 -0
- docstring_generator_ext-2.0.13/src/docstringFormat.cpp +279 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/docstringFormat.hpp +2 -0
- docstring_generator_ext-2.0.13/src/existingDocstringExtractor.cpp +600 -0
- docstring_generator_ext-2.0.13/src/existingDocstringExtractor.hpp +60 -0
- docstring_generator_ext-2.0.13/src/formatStyles.hpp +13 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/parser.cpp +19 -10
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/parser.hpp +21 -0
- docstring_generator_ext-2.0.11/src/FunctionFormat.hpp +0 -118
- docstring_generator_ext-2.0.11/src/GoogleDocstring.cpp +0 -153
- docstring_generator_ext-2.0.11/src/IDocstringFormat.cpp +0 -38
- docstring_generator_ext-2.0.11/src/NumpyDocstring.cpp +0 -122
- docstring_generator_ext-2.0.11/src/docstringFormat.cpp +0 -261
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/MANIFEST.in +0 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/README.md +0 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/docstring_generator_ext.egg-info/dependency_links.txt +0 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/docstring_generator_ext.egg-info/requires.txt +0 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/docstring_generator_ext.egg-info/top_level.txt +0 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/setup.cfg +0 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/docComparator.cpp +0 -0
- {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/docComparator.hpp +0 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#include "FunctionFormat.hpp"
|
|
2
2
|
|
|
3
|
+
#include <complex>
|
|
3
4
|
#include <map>
|
|
4
5
|
#include <ranges>
|
|
5
6
|
|
|
7
|
+
#include "existingDocstringExtractor.hpp"
|
|
6
8
|
#include "parser.hpp"
|
|
7
9
|
|
|
8
10
|
const std::map<std::string, ParameterKind> ParameterKinds = {
|
|
@@ -23,38 +25,7 @@ ParameterKind from_str(const std::string &kind) {
|
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
std::ostream &operator<<(std::ostream &out, ParameterKind const &obj) noexcept {
|
|
26
|
-
|
|
27
|
-
case ParameterKind::ARG:
|
|
28
|
-
return out << "Argument";
|
|
29
|
-
case ParameterKind::POS_ONLY:
|
|
30
|
-
return out << "Positional only argument";
|
|
31
|
-
case ParameterKind::KW_ONLY:
|
|
32
|
-
return out << "Keyword only argument";
|
|
33
|
-
case ParameterKind::VARIADIC_ARG:
|
|
34
|
-
return out << "Variadic arguments";
|
|
35
|
-
case ParameterKind::KEYWORD_ARG:
|
|
36
|
-
return out << "Keyword arguments";
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return out;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
std::string parameter_kind::to_str(const ParameterKind &kind) {
|
|
43
|
-
std::string name = "UNKNOWN";
|
|
44
|
-
switch (kind) {
|
|
45
|
-
case ParameterKind::ARG: name = "Argument";
|
|
46
|
-
break;
|
|
47
|
-
case ParameterKind::POS_ONLY: name = "Positional only argument";
|
|
48
|
-
break;
|
|
49
|
-
case ParameterKind::KW_ONLY: name = "Keyword only argument";
|
|
50
|
-
break;
|
|
51
|
-
case ParameterKind::VARIADIC_ARG: name = "Variadic arguments";
|
|
52
|
-
break;
|
|
53
|
-
case ParameterKind::KEYWORD_ARG: name = "Keyword arguments";
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return name;
|
|
28
|
+
return out << parameter_kind::to_str(obj);
|
|
58
29
|
}
|
|
59
30
|
|
|
60
31
|
void FunctionParameter::update_description(const std::string &descr, const DocstringFormatStyle &formatStyle) noexcept {
|
|
@@ -128,6 +99,16 @@ void FunctionParameter::update_rest_description(const std::string &descr) noexce
|
|
|
128
99
|
description = remove_whitespace(remove_trailing_whitespace(new_description));
|
|
129
100
|
}
|
|
130
101
|
|
|
102
|
+
void FunctionParameter::erase() {
|
|
103
|
+
name.clear();
|
|
104
|
+
default_value.clear();
|
|
105
|
+
type.clear();
|
|
106
|
+
kind = ParameterKind::ARG;
|
|
107
|
+
line_no = 0;
|
|
108
|
+
description.clear();
|
|
109
|
+
skip = true;
|
|
110
|
+
}
|
|
111
|
+
|
|
131
112
|
[[nodiscard]] int FunctionInfo::get_file_write_position() const noexcept {
|
|
132
113
|
if (!docstring.docstring.empty()) {
|
|
133
114
|
return docstring.start_line;
|
|
@@ -148,32 +129,29 @@ void FunctionParameter::update_rest_description(const std::string &descr) noexce
|
|
|
148
129
|
}
|
|
149
130
|
|
|
150
131
|
void FunctionInfo::update_descriptions(const DocstringFormatStyle &formatStyle) noexcept {
|
|
151
|
-
for (size_t idx = 0; idx < args.size(); ++idx) {
|
|
152
|
-
size_t start_pos;
|
|
153
|
-
|
|
154
|
-
if (formatStyle == DocstringFormatStyle::reST) {
|
|
155
|
-
start_pos = docstring.docstring.find(":param " + args[idx].name + ":");
|
|
156
|
-
} else {
|
|
157
|
-
start_pos = docstring.docstring.find(args[idx].name);
|
|
158
|
-
}
|
|
159
132
|
|
|
160
|
-
|
|
161
|
-
|
|
133
|
+
const auto extractor = ExistingDocstringExtractor::parse_text(docstring.docstring, formatStyle);
|
|
134
|
+
if (!extractor.get_return_info().empty())
|
|
135
|
+
returns.description = extractor.get_return_info()[0].description;
|
|
162
136
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (const auto return_pos = docstring.docstring.find("Returns"); return_pos != std::string::npos) {
|
|
167
|
-
end_pos = return_pos - 1;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (end_pos != std::string::npos) {
|
|
172
|
-
std::string part_of_interest = docstring.docstring.substr(start_pos, end_pos - start_pos);
|
|
173
|
-
args[idx].update_description(part_of_interest, formatStyle);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
137
|
+
if (!extractor.get_exception_info().empty()) {
|
|
138
|
+
for (const auto &exception: extractor.get_exception_info()) {
|
|
139
|
+
exceptions.emplace(exception.type, exception.description);
|
|
176
140
|
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
docstring.docstring = extractor.get_reduced_docstring();
|
|
144
|
+
size_t param_idx = 0;
|
|
145
|
+
// we expect that the params are in the same order, cause otherwise we had somewhere a violation agains a PEP
|
|
146
|
+
for (const auto ¶m: extractor.get_extracted_parameters()) {
|
|
147
|
+
// args[param_idx].default_value = param.default_val;
|
|
148
|
+
args[param_idx].description = param.description;
|
|
149
|
+
++param_idx;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
bool FunctionInfo::summary_only() const noexcept {
|
|
154
|
+
return args.empty() && returns.type.empty() && exceptions.empty();
|
|
177
155
|
}
|
|
178
156
|
|
|
179
157
|
void FunctionDocstring::detect_format_style() noexcept {
|
|
@@ -270,7 +248,7 @@ void FunctionDocstring::detect_format_style() noexcept {
|
|
|
270
248
|
if (end_pos == -1 || static_cast<size_t>(end_pos) > lines.size())
|
|
271
249
|
return -1;
|
|
272
250
|
|
|
273
|
-
std::string tmp
|
|
251
|
+
std::string tmp;
|
|
274
252
|
lines.clear();
|
|
275
253
|
for (const auto&line : std::views::split(docstring, '\n') | std::views::transform([](const auto &obj){ return std::string(obj.begin(), obj.end()); })) {
|
|
276
254
|
lines.emplace_back(line);
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#ifndef DOCSTRING_GENERATOR_EXT_FUNCTIONFORMAT_HPP
|
|
2
|
+
#define DOCSTRING_GENERATOR_EXT_FUNCTIONFORMAT_HPP
|
|
3
|
+
|
|
4
|
+
#include "formatStyles.hpp"
|
|
5
|
+
|
|
6
|
+
#include <format>
|
|
7
|
+
#include <map>
|
|
8
|
+
#include <set>
|
|
9
|
+
#include <string>
|
|
10
|
+
#include <vector>
|
|
11
|
+
|
|
12
|
+
#include <pybind11/pybind11.h>
|
|
13
|
+
namespace py = pybind11;
|
|
14
|
+
|
|
15
|
+
enum class ParameterKind {
|
|
16
|
+
ARG,
|
|
17
|
+
POS_ONLY,
|
|
18
|
+
KW_ONLY,
|
|
19
|
+
VARIADIC_ARG,
|
|
20
|
+
KEYWORD_ARG,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
using StyleSections = std::array<std::string_view, 3>;
|
|
24
|
+
constexpr std::array<std::pair<std::string_view, StyleSections>, 3> TypicalFormatStyle = {
|
|
25
|
+
{
|
|
26
|
+
{"numpy", {"Parameters\n", "Returns\n", "Raises\n"}},
|
|
27
|
+
{"google", {"Args:", "Returns:", "Raises:"}},
|
|
28
|
+
{"rest", {":param", ":returns:", ":raises"}}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
constexpr std::array<std::pair<std::string_view, StyleSections>, 3> TypicalSectionStyle = {
|
|
33
|
+
{
|
|
34
|
+
{"numpy", {"Parameters", "Returns", "Raises"}},
|
|
35
|
+
{"google", {"Args:", "Returns:", "Raises:"}},
|
|
36
|
+
{"rest", {":param", ":returns:", ":raises"}}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
ParameterKind from_str(const std::string &kind);
|
|
41
|
+
|
|
42
|
+
std::ostream &operator<<(std::ostream &out, ParameterKind const &obj) noexcept;
|
|
43
|
+
|
|
44
|
+
namespace parameter_kind {
|
|
45
|
+
inline std::string to_str(const ParameterKind &kind) {
|
|
46
|
+
switch (kind) {
|
|
47
|
+
case ParameterKind::ARG: return "Argument";
|
|
48
|
+
case ParameterKind::POS_ONLY: return "Positional only argument";
|
|
49
|
+
case ParameterKind::KW_ONLY: return "Keyword only argument";
|
|
50
|
+
case ParameterKind::VARIADIC_ARG: return "Variadic arguments";
|
|
51
|
+
case ParameterKind::KEYWORD_ARG: return "Keyword arguments";
|
|
52
|
+
}
|
|
53
|
+
return "UNKNOWN";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
template<>
|
|
58
|
+
struct std::formatter<ParameterKind> : std::formatter<std::string> {
|
|
59
|
+
auto format(const ParameterKind &kind, std::format_context &ctx) const {
|
|
60
|
+
return std::formatter<std::string>::format(parameter_kind::to_str(kind), ctx);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
struct FunctionParameter {
|
|
65
|
+
std::string name;
|
|
66
|
+
std::string default_value;
|
|
67
|
+
std::string type;
|
|
68
|
+
ParameterKind kind;
|
|
69
|
+
uint32_t line_no;
|
|
70
|
+
std::string description{};
|
|
71
|
+
bool skip {false};
|
|
72
|
+
|
|
73
|
+
void update_description(const std::string &descr, const DocstringFormatStyle &formatStyle) noexcept;
|
|
74
|
+
|
|
75
|
+
void update_description(const std::string &descr) noexcept;
|
|
76
|
+
|
|
77
|
+
void update_rest_description(const std::string &descr) noexcept;
|
|
78
|
+
|
|
79
|
+
void erase();
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
struct FunctionReturn {
|
|
83
|
+
uint32_t line_no{};
|
|
84
|
+
std::string type;
|
|
85
|
+
std::string description;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
struct FunctionDocstring {
|
|
89
|
+
uint32_t start_line{};
|
|
90
|
+
size_t end_line{};
|
|
91
|
+
std::string docstring;
|
|
92
|
+
std::optional<DocstringFormatStyle> detected_format_style{std::nullopt};
|
|
93
|
+
|
|
94
|
+
void detect_format_style() noexcept;
|
|
95
|
+
|
|
96
|
+
[[nodiscard]] int remove_old_format_style() noexcept;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
FunctionDocstring get_docstring(const py::object &obj, const py::module &ast_module) noexcept;
|
|
100
|
+
|
|
101
|
+
struct FunctionException {
|
|
102
|
+
std::string name;
|
|
103
|
+
std::string description;
|
|
104
|
+
|
|
105
|
+
auto operator<=>(const FunctionException &) const = default;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
struct FunctionInfo {
|
|
109
|
+
std::vector<FunctionParameter> args{};
|
|
110
|
+
uint32_t offset{};
|
|
111
|
+
uint64_t body_start{};
|
|
112
|
+
FunctionDocstring docstring;
|
|
113
|
+
FunctionReturn returns;
|
|
114
|
+
std::set<FunctionException> exceptions{};
|
|
115
|
+
|
|
116
|
+
[[nodiscard]] int get_file_write_position() const noexcept;
|
|
117
|
+
|
|
118
|
+
void update_descriptions(const DocstringFormatStyle &formatStyle) noexcept;
|
|
119
|
+
|
|
120
|
+
[[nodiscard]] bool summary_only() const noexcept;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
#endif //DOCSTRING_GENERATOR_EXT_FUNCTIONFORMAT_HPP
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#include "GoogleDocstring.hpp"
|
|
2
|
+
#include "parser.hpp"
|
|
3
|
+
|
|
4
|
+
void GoogleDocstring::check_current_docstring() noexcept {
|
|
5
|
+
auto current_py_tab = get_tabs();
|
|
6
|
+
auto google_args_begin = functionInfo.docstring.docstring.find("Args:");
|
|
7
|
+
|
|
8
|
+
if (google_args_begin != std::string::npos) {
|
|
9
|
+
const auto strip_len = current_py_tab.size() + 1;
|
|
10
|
+
const auto trim_pos = google_args_begin > strip_len ? google_args_begin - strip_len : 0;
|
|
11
|
+
functionInfo.docstring.docstring = functionInfo.docstring.docstring.substr(
|
|
12
|
+
0,
|
|
13
|
+
trim_pos
|
|
14
|
+
);
|
|
15
|
+
functionInfo.docstring.end_line = functionInfo.docstring.start_line + google_args_begin;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
std::string GoogleDocstring::cleanArgsDescription(const std::string &arg, const std::string &description) noexcept {
|
|
20
|
+
std::string res = std::string{description};
|
|
21
|
+
|
|
22
|
+
if (const auto startPos = description.find("Args:\n"); startPos != std::string::npos) {
|
|
23
|
+
res = res.substr(startPos, res.size() - startPos);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (const auto startPos = res.find(arg); startPos != std::string::npos) {
|
|
27
|
+
const auto pos = startPos + arg.size() + 1;
|
|
28
|
+
if (pos > res.size())
|
|
29
|
+
return res;
|
|
30
|
+
res = res.substr(pos, res.size() - pos);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return res;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
std::string GoogleDocstring::docstringSummary() noexcept {
|
|
37
|
+
std::string res = functionInfo.docstring.docstring;
|
|
38
|
+
if (res.empty())
|
|
39
|
+
return res;
|
|
40
|
+
if (!functionInfo.summary_only()) {
|
|
41
|
+
if (!res.ends_with('\n')) {
|
|
42
|
+
res += '\n';
|
|
43
|
+
res += '\n';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return res;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
std::string GoogleDocstring::docstringArgs() noexcept {
|
|
50
|
+
if (functionInfo.args.empty())
|
|
51
|
+
return "";
|
|
52
|
+
|
|
53
|
+
auto current_py_tab = get_tabs();
|
|
54
|
+
|
|
55
|
+
std::string result;
|
|
56
|
+
|
|
57
|
+
if (PY_TAB != current_py_tab) {
|
|
58
|
+
result += current_py_tab;
|
|
59
|
+
current_py_tab += PY_TAB;
|
|
60
|
+
} else {
|
|
61
|
+
result += PY_TAB;
|
|
62
|
+
current_py_tab = PY_TAB + PY_TAB;
|
|
63
|
+
}
|
|
64
|
+
result += "Args:\n";
|
|
65
|
+
for (const auto &val: functionInfo.args) {
|
|
66
|
+
result += std::format("{}{}", current_py_tab, val.name);
|
|
67
|
+
if (!val.type.empty())
|
|
68
|
+
result += std::format(" ({}", val.type);
|
|
69
|
+
if (!val.default_value.empty()) {
|
|
70
|
+
result += ", optional";
|
|
71
|
+
}
|
|
72
|
+
if (!val.type.empty() || !val.default_value.empty())
|
|
73
|
+
result += ')';
|
|
74
|
+
|
|
75
|
+
result += ": ";
|
|
76
|
+
|
|
77
|
+
if (val.kind != ParameterKind::ARG) {
|
|
78
|
+
if (val.description.empty() || val.description.find(parameter_kind::to_str(val.kind)) == std::string::npos)
|
|
79
|
+
result += std::format("{}. ", parameter_kind::to_str(val.kind));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!val.description.empty()) {
|
|
83
|
+
result += std::format("{}", cleanArgsDescription(val.name, val.description));
|
|
84
|
+
if (!result.ends_with('.'))
|
|
85
|
+
result += '.';
|
|
86
|
+
result += ' ';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!val.default_value.empty()) {
|
|
90
|
+
if (auto tmp = std::format("Defaults to {}.", val.default_value);
|
|
91
|
+
val.description.empty() || val.description.find(tmp) == std::string::npos)
|
|
92
|
+
result += tmp;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (result.ends_with(' '))
|
|
96
|
+
result.pop_back();
|
|
97
|
+
result += '\n';
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
std::string GoogleDocstring::docstringReturn() noexcept {
|
|
103
|
+
std::string result;
|
|
104
|
+
|
|
105
|
+
auto current_py_tab = get_tabs();
|
|
106
|
+
|
|
107
|
+
if (!functionInfo.returns.description.empty() || !functionInfo.returns.type.empty()) {
|
|
108
|
+
result += current_py_tab;
|
|
109
|
+
result += "Returns:\n";
|
|
110
|
+
current_py_tab += PY_TAB;
|
|
111
|
+
result += current_py_tab;
|
|
112
|
+
|
|
113
|
+
if (!functionInfo.returns.type.empty()) {
|
|
114
|
+
result += std::format("{}: ", functionInfo.returns.type);
|
|
115
|
+
}
|
|
116
|
+
if (!functionInfo.returns.description.empty()) {
|
|
117
|
+
result += functionInfo.returns.description;
|
|
118
|
+
}
|
|
119
|
+
result += '\n';
|
|
120
|
+
} else {
|
|
121
|
+
result = "";
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
std::string GoogleDocstring::docstringExceptions() noexcept {
|
|
128
|
+
if (functionInfo.exceptions.empty())
|
|
129
|
+
return "\n";
|
|
130
|
+
|
|
131
|
+
std::string result;
|
|
132
|
+
auto current_py_tab = get_tabs();
|
|
133
|
+
|
|
134
|
+
result += current_py_tab;
|
|
135
|
+
|
|
136
|
+
current_py_tab += PY_TAB;
|
|
137
|
+
|
|
138
|
+
result += "Raises:\n";
|
|
139
|
+
|
|
140
|
+
for (const auto &[name, description]: functionInfo.exceptions) {
|
|
141
|
+
result += current_py_tab;
|
|
142
|
+
if (!name.empty()) {
|
|
143
|
+
result += std::format("{}: ", name);
|
|
144
|
+
}
|
|
145
|
+
if (!description.empty()) {
|
|
146
|
+
result += description;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
result += '\n';
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
struct GoogleDocstring : DocstringFormat {
|
|
7
7
|
void check_current_docstring() noexcept override;
|
|
8
|
+
std::string docstringSummary() noexcept override;
|
|
8
9
|
std::string docstringArgs() noexcept override;
|
|
9
10
|
std::string docstringReturn() noexcept override;
|
|
10
11
|
std::string docstringExceptions() noexcept override;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#include "IDocstringFormat.hpp"
|
|
2
|
+
#include "parser.hpp"
|
|
3
|
+
|
|
4
|
+
bool onlyQuotesAndWhitespace(const std::string &s) {
|
|
5
|
+
return std::ranges::all_of(
|
|
6
|
+
s,
|
|
7
|
+
[](char c) {
|
|
8
|
+
return c == '"' || std::isspace(static_cast<unsigned char>(c));
|
|
9
|
+
}
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
[[ nodiscard ]] std::string DocstringFormat::docstring() noexcept {
|
|
14
|
+
std::string result;
|
|
15
|
+
std::string tmp{};
|
|
16
|
+
result.reserve(1024); // rough upfront guess for typical arg count
|
|
17
|
+
const auto current_pytab = get_tabs();
|
|
18
|
+
|
|
19
|
+
if (const auto argTxt = docstringArgs(); !argTxt.empty()) {
|
|
20
|
+
tmp += argTxt;
|
|
21
|
+
}
|
|
22
|
+
if (const auto returnTxt = docstringReturn(); !returnTxt.empty()) {
|
|
23
|
+
tmp += returnTxt;
|
|
24
|
+
}
|
|
25
|
+
if (const auto exceptionTxt = docstringExceptions(); !exceptionTxt.empty() && exceptionTxt != "\n") {
|
|
26
|
+
tmp += exceptionTxt;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
result += current_pytab;
|
|
30
|
+
result += R"(""")";
|
|
31
|
+
if (const auto summaryTxt = docstringSummary(); !summaryTxt.empty()) {
|
|
32
|
+
result += summaryTxt;
|
|
33
|
+
if (!result.empty() && !result.ends_with('\n') && !tmp.empty())
|
|
34
|
+
result += '\n';
|
|
35
|
+
} else {
|
|
36
|
+
result += '\n';
|
|
37
|
+
}
|
|
38
|
+
result += tmp;
|
|
39
|
+
if (result.ends_with('\n'))
|
|
40
|
+
result += current_pytab;
|
|
41
|
+
result += R"(""")";
|
|
42
|
+
|
|
43
|
+
if (onlyQuotesAndWhitespace(result))
|
|
44
|
+
return "";
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
[[ nodiscard ]] std::string DocstringFormat::get_tabs() const noexcept {
|
|
49
|
+
auto current_py_tab = PY_TAB;
|
|
50
|
+
for (uint32_t idx = 0; idx < (functionInfo.offset / 4); ++idx) {
|
|
51
|
+
current_py_tab += PY_TAB;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return current_py_tab;
|
|
55
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#include "NumpyDocstring.hpp"
|
|
2
|
+
|
|
3
|
+
#include "parser.hpp"
|
|
4
|
+
|
|
5
|
+
void NumpyDocstring::check_current_docstring() noexcept {
|
|
6
|
+
const auto current_py_tab = get_tabs();
|
|
7
|
+
const auto numpy_args_begin = functionInfo.docstring.docstring.find("Parameters");
|
|
8
|
+
|
|
9
|
+
if (numpy_args_begin != std::string::npos) {
|
|
10
|
+
const auto strip_len = current_py_tab.size() + 1;
|
|
11
|
+
const auto trim_pos = numpy_args_begin > strip_len ? numpy_args_begin - strip_len : 0;
|
|
12
|
+
functionInfo.docstring.docstring = functionInfo.docstring.docstring.substr(
|
|
13
|
+
0,
|
|
14
|
+
trim_pos
|
|
15
|
+
);
|
|
16
|
+
functionInfo.docstring.end_line = functionInfo.docstring.start_line + numpy_args_begin;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
std::string NumpyDocstring::docstringSummary() noexcept {
|
|
21
|
+
std::string res = functionInfo.docstring.docstring;
|
|
22
|
+
if (res.empty())
|
|
23
|
+
return res;
|
|
24
|
+
if (!functionInfo.summary_only()) {
|
|
25
|
+
res += '\n';
|
|
26
|
+
res += '\n';
|
|
27
|
+
}
|
|
28
|
+
return res;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
std::string NumpyDocstring::docstringArgs() noexcept {
|
|
32
|
+
std::string docstream;
|
|
33
|
+
const auto current_py_tab = get_tabs();
|
|
34
|
+
|
|
35
|
+
if (functionInfo.args.empty()) {
|
|
36
|
+
return docstream;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
docstream.reserve(1024);
|
|
40
|
+
|
|
41
|
+
docstream += std::format("{}Parameters\n", current_py_tab);
|
|
42
|
+
docstream += std::format("{}----------\n", current_py_tab);
|
|
43
|
+
std::ranges::for_each(
|
|
44
|
+
functionInfo.args,
|
|
45
|
+
[&docstream, ¤t_py_tab](const FunctionParameter &val) {
|
|
46
|
+
if (val.skip)
|
|
47
|
+
return;
|
|
48
|
+
|
|
49
|
+
std::string result;
|
|
50
|
+
result.reserve(256);
|
|
51
|
+
|
|
52
|
+
if (val.name.empty())
|
|
53
|
+
result += std::format("{}PLACEHOLDER", current_py_tab);
|
|
54
|
+
else
|
|
55
|
+
result += std::format("{}{}", current_py_tab, val.name);
|
|
56
|
+
|
|
57
|
+
if (!val.type.empty()) {
|
|
58
|
+
result += std::format(" : {}", val.type);
|
|
59
|
+
|
|
60
|
+
if (!val.default_value.empty()) {
|
|
61
|
+
result += ", optional";
|
|
62
|
+
result += std::format(", default {}", val.default_value);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (val.kind != ParameterKind::ARG) {
|
|
67
|
+
if (!val.description.empty() && val.description.find(parameter_kind::to_str(val.kind)) == std::string::npos) {
|
|
68
|
+
result += '\n';
|
|
69
|
+
result += std::format("{}{}{}", current_py_tab, PY_TAB, parameter_kind::to_str(val.kind));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!val.description.empty()) {
|
|
74
|
+
result += '\n';
|
|
75
|
+
result += std::format("{}{}{}", current_py_tab, PY_TAB, remove_whitespace(val.description));
|
|
76
|
+
if (!result.ends_with('.'))
|
|
77
|
+
result += '.';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
result = remove_trailing_whitespace(result);
|
|
81
|
+
|
|
82
|
+
docstream += std::format("{}\n", result);
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
docstream += '\n';
|
|
86
|
+
return docstream;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
std::string NumpyDocstring::docstringReturn() noexcept {
|
|
90
|
+
std::string result;
|
|
91
|
+
const auto current_py_tab = get_tabs();
|
|
92
|
+
if (functionInfo.returns.type.empty() and functionInfo.returns.description.empty())
|
|
93
|
+
return "";
|
|
94
|
+
|
|
95
|
+
result.reserve(256);
|
|
96
|
+
|
|
97
|
+
if (!functionInfo.returns.type.empty()) {
|
|
98
|
+
result += std::format("{}Returns\n", current_py_tab);
|
|
99
|
+
result += std::format("{}-------\n", current_py_tab);
|
|
100
|
+
|
|
101
|
+
result += std::format("{}{}", current_py_tab, functionInfo.returns.type);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!functionInfo.returns.description.empty()) {
|
|
105
|
+
result += '\n';
|
|
106
|
+
result += std::format("{}{}{}", current_py_tab, PY_TAB, functionInfo.returns.description);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
result += '\n';
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
std::string NumpyDocstring::docstringExceptions() noexcept {
|
|
114
|
+
if (functionInfo.exceptions.empty())
|
|
115
|
+
return "";
|
|
116
|
+
|
|
117
|
+
std::string result;
|
|
118
|
+
result.reserve(256);
|
|
119
|
+
|
|
120
|
+
if (!functionInfo.returns.type.empty())
|
|
121
|
+
result += '\n';
|
|
122
|
+
|
|
123
|
+
const auto current_py_tab = get_tabs();
|
|
124
|
+
|
|
125
|
+
result += std::format("{}Raises\n", current_py_tab);
|
|
126
|
+
result += std::format("{}------\n", current_py_tab);
|
|
127
|
+
|
|
128
|
+
for (const auto &[name, description]: functionInfo.exceptions) {
|
|
129
|
+
if (!name.empty()) {
|
|
130
|
+
result += std::format("{}{}", current_py_tab, name);
|
|
131
|
+
result += '\n';
|
|
132
|
+
}
|
|
133
|
+
if (!description.empty()) {
|
|
134
|
+
result += std::format("{}{}{}", current_py_tab, PY_TAB, description);
|
|
135
|
+
}
|
|
136
|
+
result += '\n';
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
struct NumpyDocstring : DocstringFormat {
|
|
6
6
|
void check_current_docstring() noexcept override;
|
|
7
|
+
std::string docstringSummary() noexcept override;
|
|
7
8
|
std::string docstringArgs() noexcept override;
|
|
8
9
|
std::string docstringReturn() noexcept override;
|
|
9
10
|
std::string docstringExceptions() noexcept override;
|