docstring-generator-ext 2.0.12__tar.gz → 2.0.13b1__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.12 → docstring_generator_ext-2.0.13b1}/PKG-INFO +1 -1
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/docstring_generator_ext.egg-info/PKG-INFO +1 -1
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/docstring_generator_ext.egg-info/SOURCES.txt +3 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/pyproject.toml +1 -1
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/setup.py +1 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/src/FunctionFormat.cpp +29 -24
- docstring_generator_ext-2.0.13b1/src/FunctionFormat.hpp +123 -0
- docstring_generator_ext-2.0.13b1/src/GoogleDocstring.cpp +153 -0
- docstring_generator_ext-2.0.13b1/src/IDocstringFormat.cpp +55 -0
- docstring_generator_ext-2.0.13b1/src/NumpyDocstring.cpp +140 -0
- docstring_generator_ext-2.0.13b1/src/docstringFormat.cpp +279 -0
- docstring_generator_ext-2.0.13b1/src/existingDocstringExtractor.cpp +600 -0
- docstring_generator_ext-2.0.13b1/src/existingDocstringExtractor.hpp +60 -0
- docstring_generator_ext-2.0.13b1/src/formatStyles.hpp +13 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/src/parser.hpp +21 -0
- docstring_generator_ext-2.0.12/src/FunctionFormat.hpp +0 -114
- docstring_generator_ext-2.0.12/src/GoogleDocstring.cpp +0 -145
- docstring_generator_ext-2.0.12/src/IDocstringFormat.cpp +0 -49
- docstring_generator_ext-2.0.12/src/NumpyDocstring.cpp +0 -144
- docstring_generator_ext-2.0.12/src/docstringFormat.cpp +0 -269
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/MANIFEST.in +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/README.md +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/docstring_generator_ext.egg-info/dependency_links.txt +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/docstring_generator_ext.egg-info/requires.txt +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/docstring_generator_ext.egg-info/top_level.txt +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/setup.cfg +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/src/GoogleDocstring.hpp +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/src/IDocstringFormat.hpp +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/src/NumpyDocstring.hpp +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/src/ReStructuredDocstring.cpp +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/src/ReStructuredDocstring.hpp +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/src/docComparator.cpp +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/src/docComparator.hpp +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/src/docstringFormat.hpp +0 -0
- {docstring_generator_ext-2.0.12 → docstring_generator_ext-2.0.13b1}/src/parser.cpp +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 = {
|
|
@@ -97,6 +99,16 @@ void FunctionParameter::update_rest_description(const std::string &descr) noexce
|
|
|
97
99
|
description = remove_whitespace(remove_trailing_whitespace(new_description));
|
|
98
100
|
}
|
|
99
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
|
+
|
|
100
112
|
[[nodiscard]] int FunctionInfo::get_file_write_position() const noexcept {
|
|
101
113
|
if (!docstring.docstring.empty()) {
|
|
102
114
|
return docstring.start_line;
|
|
@@ -117,32 +129,25 @@ void FunctionParameter::update_rest_description(const std::string &descr) noexce
|
|
|
117
129
|
}
|
|
118
130
|
|
|
119
131
|
void FunctionInfo::update_descriptions(const DocstringFormatStyle &formatStyle) noexcept {
|
|
120
|
-
for (size_t idx = 0; idx < args.size(); ++idx) {
|
|
121
|
-
size_t start_pos;
|
|
122
132
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
start_pos = docstring.docstring.find(args[idx].name);
|
|
127
|
-
}
|
|
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;
|
|
128
136
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if (idx < args.size() - 1) {
|
|
133
|
-
end_pos = docstring.docstring.find(args[idx + 1].name);
|
|
134
|
-
} else if (idx == args.size() - 1 && docstring.docstring.find("Returns") < std::string::npos) {
|
|
135
|
-
if (const auto return_pos = docstring.docstring.find("Returns"); return_pos != std::string::npos) {
|
|
136
|
-
end_pos = return_pos - 1;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (end_pos != std::string::npos) {
|
|
141
|
-
std::string part_of_interest = docstring.docstring.substr(start_pos, end_pos - start_pos);
|
|
142
|
-
args[idx].update_description(part_of_interest, formatStyle);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
137
|
+
if (!extractor.get_exception_info().empty()) {
|
|
138
|
+
for (const auto &exception: extractor.get_exception_info()) {
|
|
139
|
+
exceptions.emplace(exception.type, exception.description);
|
|
145
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
|
+
}
|
|
146
151
|
}
|
|
147
152
|
|
|
148
153
|
bool FunctionInfo::summary_only() const noexcept {
|
|
@@ -243,7 +248,7 @@ void FunctionDocstring::detect_format_style() noexcept {
|
|
|
243
248
|
if (end_pos == -1 || static_cast<size_t>(end_pos) > lines.size())
|
|
244
249
|
return -1;
|
|
245
250
|
|
|
246
|
-
std::string tmp
|
|
251
|
+
std::string tmp;
|
|
247
252
|
lines.clear();
|
|
248
253
|
for (const auto&line : std::views::split(docstring, '\n') | std::views::transform([](const auto &obj){ return std::string(obj.begin(), obj.end()); })) {
|
|
249
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
|
+
}
|
|
@@ -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
|
+
}
|