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.
Files changed (35) hide show
  1. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/PKG-INFO +1 -1
  2. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/docstring_generator_ext.egg-info/PKG-INFO +1 -1
  3. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/docstring_generator_ext.egg-info/SOURCES.txt +3 -0
  4. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/pyproject.toml +1 -1
  5. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/setup.py +1 -0
  6. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/FunctionFormat.cpp +34 -56
  7. docstring_generator_ext-2.0.13/src/FunctionFormat.hpp +123 -0
  8. docstring_generator_ext-2.0.13/src/GoogleDocstring.cpp +153 -0
  9. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/GoogleDocstring.hpp +1 -0
  10. docstring_generator_ext-2.0.13/src/IDocstringFormat.cpp +55 -0
  11. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/IDocstringFormat.hpp +2 -0
  12. docstring_generator_ext-2.0.13/src/NumpyDocstring.cpp +140 -0
  13. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/NumpyDocstring.hpp +1 -0
  14. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/ReStructuredDocstring.cpp +15 -7
  15. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/ReStructuredDocstring.hpp +2 -0
  16. docstring_generator_ext-2.0.13/src/docstringFormat.cpp +279 -0
  17. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/docstringFormat.hpp +2 -0
  18. docstring_generator_ext-2.0.13/src/existingDocstringExtractor.cpp +600 -0
  19. docstring_generator_ext-2.0.13/src/existingDocstringExtractor.hpp +60 -0
  20. docstring_generator_ext-2.0.13/src/formatStyles.hpp +13 -0
  21. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/parser.cpp +19 -10
  22. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/parser.hpp +21 -0
  23. docstring_generator_ext-2.0.11/src/FunctionFormat.hpp +0 -118
  24. docstring_generator_ext-2.0.11/src/GoogleDocstring.cpp +0 -153
  25. docstring_generator_ext-2.0.11/src/IDocstringFormat.cpp +0 -38
  26. docstring_generator_ext-2.0.11/src/NumpyDocstring.cpp +0 -122
  27. docstring_generator_ext-2.0.11/src/docstringFormat.cpp +0 -261
  28. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/MANIFEST.in +0 -0
  29. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/README.md +0 -0
  30. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/docstring_generator_ext.egg-info/dependency_links.txt +0 -0
  31. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/docstring_generator_ext.egg-info/requires.txt +0 -0
  32. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/docstring_generator_ext.egg-info/top_level.txt +0 -0
  33. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/setup.cfg +0 -0
  34. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/docComparator.cpp +0 -0
  35. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.13}/src/docComparator.hpp +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docstring_generator_ext
3
- Version: 2.0.11
3
+ Version: 2.0.13
4
4
  Summary: Generate Docstrings with type-hint information.
5
5
  Author-email: FelixTheC <fberndt87@gmail.com>
6
6
  Classifier: Environment :: Console
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docstring_generator_ext
3
- Version: 2.0.11
3
+ Version: 2.0.13
4
4
  Summary: Generate Docstrings with type-hint information.
5
5
  Author-email: FelixTheC <fberndt87@gmail.com>
6
6
  Classifier: Environment :: Console
@@ -21,5 +21,8 @@ src/docComparator.cpp
21
21
  src/docComparator.hpp
22
22
  src/docstringFormat.cpp
23
23
  src/docstringFormat.hpp
24
+ src/existingDocstringExtractor.cpp
25
+ src/existingDocstringExtractor.hpp
26
+ src/formatStyles.hpp
24
27
  src/parser.cpp
25
28
  src/parser.hpp
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "docstring_generator_ext"
3
- version = "2.0.11"
3
+ version = "2.0.13"
4
4
  description = "Generate Docstrings with type-hint information."
5
5
  authors = [
6
6
  { name = "FelixTheC", email = "fberndt87@gmail.com" },
@@ -47,6 +47,7 @@ ext_modules = [
47
47
  "src/NumpyDocstring.cpp",
48
48
  "src/ReStructuredDocstring.cpp",
49
49
  "src/docComparator.cpp",
50
+ "src/existingDocstringExtractor.cpp",
50
51
  ],
51
52
  include_dirs=["src"],
52
53
  cxx_std=20,
@@ -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
- switch (obj) {
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
- if (start_pos < std::string::npos) {
161
- size_t end_pos = docstring.docstring.size() - 1;
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
- if (idx < args.size() - 1) {
164
- end_pos = docstring.docstring.find(args[idx + 1].name);
165
- } else if (idx == args.size() - 1 && docstring.docstring.find("Returns") < std::string::npos) {
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 &param: 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
+ }
@@ -8,6 +8,8 @@
8
8
  struct DocstringFormat {
9
9
  FunctionInfo functionInfo;
10
10
 
11
+ virtual std::string docstringSummary() noexcept = 0;
12
+
11
13
  virtual std::string docstringArgs() noexcept = 0;
12
14
 
13
15
  virtual std::string docstringReturn() noexcept = 0;
@@ -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, &current_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;