docstring-generator-ext 2.0.11__tar.gz → 2.0.12__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 (28) hide show
  1. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/PKG-INFO +1 -1
  2. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/docstring_generator_ext.egg-info/PKG-INFO +1 -1
  3. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/pyproject.toml +1 -1
  4. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/FunctionFormat.cpp +5 -32
  5. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/FunctionFormat.hpp +14 -18
  6. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/GoogleDocstring.cpp +42 -50
  7. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/GoogleDocstring.hpp +1 -0
  8. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/IDocstringFormat.cpp +21 -10
  9. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/IDocstringFormat.hpp +2 -0
  10. docstring_generator_ext-2.0.12/src/NumpyDocstring.cpp +144 -0
  11. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/NumpyDocstring.hpp +1 -0
  12. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/ReStructuredDocstring.cpp +15 -7
  13. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/ReStructuredDocstring.hpp +2 -0
  14. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/docstringFormat.cpp +25 -17
  15. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/docstringFormat.hpp +2 -0
  16. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/parser.cpp +19 -10
  17. docstring_generator_ext-2.0.11/src/NumpyDocstring.cpp +0 -122
  18. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/MANIFEST.in +0 -0
  19. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/README.md +0 -0
  20. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/docstring_generator_ext.egg-info/SOURCES.txt +0 -0
  21. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/docstring_generator_ext.egg-info/dependency_links.txt +0 -0
  22. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/docstring_generator_ext.egg-info/requires.txt +0 -0
  23. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/docstring_generator_ext.egg-info/top_level.txt +0 -0
  24. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/setup.cfg +0 -0
  25. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/setup.py +0 -0
  26. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/docComparator.cpp +0 -0
  27. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/docComparator.hpp +0 -0
  28. {docstring_generator_ext-2.0.11 → docstring_generator_ext-2.0.12}/src/parser.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.12
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.12
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
  [project]
2
2
  name = "docstring_generator_ext"
3
- version = "2.0.11"
3
+ version = "2.0.12"
4
4
  description = "Generate Docstrings with type-hint information."
5
5
  authors = [
6
6
  { name = "FelixTheC", email = "fberndt87@gmail.com" },
@@ -23,38 +23,7 @@ ParameterKind from_str(const std::string &kind) {
23
23
  }
24
24
 
25
25
  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;
26
+ return out << parameter_kind::to_str(obj);
58
27
  }
59
28
 
60
29
  void FunctionParameter::update_description(const std::string &descr, const DocstringFormatStyle &formatStyle) noexcept {
@@ -176,6 +145,10 @@ void FunctionInfo::update_descriptions(const DocstringFormatStyle &formatStyle)
176
145
  }
177
146
  }
178
147
 
148
+ bool FunctionInfo::summary_only() const noexcept {
149
+ return args.empty() && returns.type.empty() && exceptions.empty();
150
+ }
151
+
179
152
  void FunctionDocstring::detect_format_style() noexcept {
180
153
  bool could_be_numpy = false;
181
154
  bool could_be_google = false;
@@ -41,27 +41,22 @@ ParameterKind from_str(const std::string &kind);
41
41
  std::ostream &operator<<(std::ostream &out, ParameterKind const &obj) noexcept;
42
42
 
43
43
  namespace parameter_kind{
44
- std::string to_str(const ParameterKind &kind);
44
+ inline std::string to_str(const ParameterKind &kind) {
45
+ switch (kind) {
46
+ case ParameterKind::ARG: return "Argument";
47
+ case ParameterKind::POS_ONLY: return "Positional only argument";
48
+ case ParameterKind::KW_ONLY: return "Keyword only argument";
49
+ case ParameterKind::VARIADIC_ARG: return "Variadic arguments";
50
+ case ParameterKind::KEYWORD_ARG: return "Keyword arguments";
51
+ }
52
+ return "UNKNOWN";
53
+ }
45
54
  }
46
55
 
47
56
  template<>
48
- struct std::formatter<ParameterKind> : std::formatter<std::string_view> {
49
- // Format the enum by mapping it to a string_view
50
- auto format(ParameterKind kind, std::format_context &ctx) const {
51
- std::string_view name = "UNKNOWN";
52
- switch (kind) {
53
- case ParameterKind::ARG: name = "Argument";
54
- break;
55
- case ParameterKind::POS_ONLY: name = "Positional only argument";
56
- break;
57
- case ParameterKind::KW_ONLY: name = "Keyword only argument";
58
- break;
59
- case ParameterKind::VARIADIC_ARG: name = "Variadic arguments";
60
- break;
61
- case ParameterKind::KEYWORD_ARG: name = "Keyword arguments";
62
- break;
63
- }
64
- return std::formatter<std::string_view>::format(name, ctx);
57
+ struct std::formatter<ParameterKind> : std::formatter<std::string> {
58
+ auto format(const ParameterKind &kind, std::format_context &ctx) const {
59
+ return std::formatter<std::string>::format(parameter_kind::to_str(kind), ctx);
65
60
  }
66
61
  };
67
62
 
@@ -113,6 +108,7 @@ struct FunctionInfo {
113
108
 
114
109
  [[nodiscard]] int get_file_write_position() const noexcept;
115
110
  void update_descriptions(const DocstringFormatStyle &formatStyle) noexcept;
111
+ [[nodiscard]] bool summary_only() const noexcept;
116
112
  };
117
113
 
118
114
  #endif //DOCSTRING_GENERATOR_EXT_FUNCTIONFORMAT_HPP
@@ -1,17 +1,16 @@
1
1
  #include "GoogleDocstring.hpp"
2
-
3
- #include <format>
4
-
5
2
  #include "parser.hpp"
6
3
 
7
4
  void GoogleDocstring::check_current_docstring() noexcept {
8
5
  auto current_py_tab = get_tabs();
9
6
  auto google_args_begin = functionInfo.docstring.docstring.find("Args:");
10
7
 
11
- if (google_args_begin < std::string::npos) {
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;
12
11
  functionInfo.docstring.docstring = functionInfo.docstring.docstring.substr(
13
12
  0,
14
- google_args_begin - (current_py_tab.size() + 1)
13
+ trim_pos
15
14
  );
16
15
  functionInfo.docstring.end_line = functionInfo.docstring.start_line + google_args_begin;
17
16
  }
@@ -20,11 +19,11 @@ void GoogleDocstring::check_current_docstring() noexcept {
20
19
  std::string GoogleDocstring::cleanArgsDescription(const std::string &arg, const std::string &description) noexcept {
21
20
  std::string res = std::string {description};
22
21
 
23
- if (const auto startPos = description.find("Args:\n"); startPos < std::string::npos) {
22
+ if (const auto startPos = description.find("Args:\n"); startPos != std::string::npos) {
24
23
  res = res.substr(startPos, res.size() - startPos);
25
24
  }
26
25
 
27
- if (const auto startPos = res.find(arg); startPos < std::string::npos) {
26
+ if (const auto startPos = res.find(arg); startPos != std::string::npos) {
28
27
  const auto pos = startPos + arg.size() + 1;
29
28
  if (pos > res.size())
30
29
  return res;
@@ -34,20 +33,25 @@ std::string GoogleDocstring::cleanArgsDescription(const std::string &arg, const
34
33
  return res;
35
34
  }
36
35
 
37
- std::string GoogleDocstring::docstringArgs() noexcept {
38
- auto current_py_tab = get_tabs();
39
-
40
- std::string result;
41
- result.reserve(256); // rough upfront guess for typical arg count
42
-
43
- if (!functionInfo.docstring.docstring.empty()) {
44
- result += functionInfo.docstring.docstring;
45
- result += "\n";
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';
46
43
  }
44
+ return res;
45
+ }
47
46
 
47
+ std::string GoogleDocstring::docstringArgs() noexcept {
48
48
  if (functionInfo.args.empty())
49
49
  return "";
50
50
 
51
+ auto current_py_tab = get_tabs();
52
+
53
+ std::string result;
54
+
51
55
  if (PY_TAB != current_py_tab) {
52
56
  result += current_py_tab;
53
57
  current_py_tab += PY_TAB;
@@ -55,49 +59,45 @@ std::string GoogleDocstring::docstringArgs() noexcept {
55
59
  result += PY_TAB;
56
60
  current_py_tab = PY_TAB + PY_TAB;
57
61
  }
58
-
59
- int idx = 0;
60
- const int last_idx = functionInfo.args.size();
61
62
  result += "Args:\n";
62
63
  for (const auto &val : functionInfo.args) {
63
- ++idx;
64
- result += current_py_tab;
65
- result += val.name;
66
- if (!val.type.empty()) {
67
- result += " (";
64
+ result += std::format("{}{} (", current_py_tab, val.name);
65
+ if (val.type.empty())
66
+ result += "Any";
67
+ else
68
68
  result += val.type;
69
- if (!val.default_value.empty()) {
70
- result += ", optional";
71
- }
72
- result += ")";
69
+ if (!val.default_value.empty()) {
70
+ result += ", optional";
73
71
  }
72
+ result += "): ";
73
+
74
+ if (val.kind != ParameterKind::ARG) {
75
+ result += std::format("{}. ", parameter_kind::to_str(val.kind));
76
+ }
77
+
74
78
  if (!val.description.empty()) {
75
- result += ": ";
76
- result += cleanArgsDescription(val.name, val.description);
79
+ result += std::format("{}", cleanArgsDescription(val.name, val.description));
80
+ if (!result.ends_with('.'))
81
+ result += '.';
82
+ result += ' ';
77
83
  }
84
+
78
85
  if (!val.default_value.empty()) {
79
- result += " (default is ";
80
- result += val.default_value;
81
- result += ")";
86
+ result += std::format("Defaults to {}.", val.default_value);
82
87
  }
83
88
 
84
- if (idx < last_idx) {
85
- result += "\n";
86
- }
89
+ result += '\n';
87
90
  }
88
91
  return result;
89
92
  }
90
93
 
91
94
  std::string GoogleDocstring::docstringReturn() noexcept {
92
95
  std::string result;
93
- result.reserve(256); // rough upfront guess for typical arg count
94
96
 
95
97
  auto current_py_tab = get_tabs();
96
98
 
97
99
  if (!functionInfo.returns.description.empty() || !functionInfo.returns.type.empty()) {
98
- result += "\n";
99
100
  result += current_py_tab;
100
-
101
101
  result += "Returns:\n";
102
102
  current_py_tab += PY_TAB;
103
103
  result += current_py_tab;
@@ -108,6 +108,7 @@ std::string GoogleDocstring::docstringReturn() noexcept {
108
108
  if (!functionInfo.returns.description.empty()) {
109
109
  result += functionInfo.returns.description;
110
110
  }
111
+ result += '\n';
111
112
  } else {
112
113
  result = "";
113
114
  }
@@ -120,22 +121,16 @@ std::string GoogleDocstring::docstringExceptions() noexcept {
120
121
  return "\n";
121
122
 
122
123
  std::string result;
123
- result.reserve(256); // rough upfront guess for typical arg count
124
124
  auto current_py_tab = get_tabs();
125
125
 
126
- result += "\n";
127
126
  result += current_py_tab;
128
127
 
129
128
  current_py_tab += PY_TAB;
130
129
 
131
130
  result += "Raises:\n";
132
- result += current_py_tab;
133
131
 
134
- int idx = 0;
135
- const int last_exception = functionInfo.exceptions.size();
136
132
  for (const auto &[name, description] : functionInfo.exceptions) {
137
- ++idx;
138
-
133
+ result += current_py_tab;
139
134
  if (!name.empty()) {
140
135
  result += std::format("{}: ", name);
141
136
  }
@@ -143,10 +138,7 @@ std::string GoogleDocstring::docstringExceptions() noexcept {
143
138
  result += description;
144
139
  }
145
140
 
146
- result += "\n";
147
- if (idx < last_exception) {
148
- result += current_py_tab;
149
- }
141
+ result += '\n';
150
142
  }
151
143
 
152
144
  return result;
@@ -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;
@@ -1,6 +1,12 @@
1
1
  #include "IDocstringFormat.hpp"
2
2
  #include "parser.hpp"
3
3
 
4
+ bool onlyQuotesAndWhitespace(const std::string& s) {
5
+ return std::ranges::all_of(s, [](char c) {
6
+ return c == '"' || std::isspace(static_cast<unsigned char>(c));
7
+ });
8
+ }
9
+
4
10
  [[ nodiscard ]] std::string DocstringFormat::docstring() noexcept {
5
11
  std::string result;
6
12
  result.reserve(1024); // rough upfront guess for typical arg count
@@ -8,23 +14,28 @@
8
14
 
9
15
  result += current_pytab;
10
16
  result += R"(""")";
11
- if (functionInfo.docstring.docstring.empty()) {
12
- result += "\n";
17
+ if (const auto summaryTxt = docstringSummary(); !summaryTxt.empty()) {
18
+ result += summaryTxt;
19
+ } else {
20
+ result += '\n';
13
21
  }
22
+
14
23
  if (const auto argTxt = docstringArgs(); !argTxt.empty()) {
15
24
  result += argTxt;
16
25
  }
17
- if (const auto returnTxt = docstringReturn(); !returnTxt.empty())
18
- result += docstringReturn();
19
- if (const auto exceptionTxt = docstringExceptions(); !exceptionTxt.empty())
20
- result += docstringExceptions();
26
+ if (const auto returnTxt = docstringReturn(); !returnTxt.empty()) {
27
+ result += returnTxt;
28
+ }
29
+ if (const auto exceptionTxt = docstringExceptions(); !exceptionTxt.empty() && exceptionTxt != "\n") {
30
+ result += exceptionTxt;
31
+ }
21
32
 
22
- result += current_pytab;
33
+ if (result.ends_with('\n'))
34
+ result += current_pytab;
23
35
  result += R"(""")";
24
- if (functionInfo.docstring.docstring.empty()) {
25
- result += "\n";
26
- }
27
36
 
37
+ if (onlyQuotesAndWhitespace(result))
38
+ return "";
28
39
  return result;
29
40
  }
30
41
 
@@ -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,144 @@
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
+ }
27
+ return res;
28
+ }
29
+
30
+ std::string NumpyDocstring::docstringArgs() noexcept {
31
+ std::string docstream;
32
+ const auto current_py_tab = get_tabs();
33
+
34
+ if (functionInfo.args.empty()) {
35
+ return docstream;
36
+ }
37
+
38
+ docstream.reserve(1024);
39
+
40
+ docstream += std::format("{}Parameters\n", current_py_tab);
41
+ docstream += std::format("{}----------\n", current_py_tab);
42
+ std::ranges::for_each(
43
+ functionInfo.args,
44
+ [&docstream, &current_py_tab](const FunctionParameter &val) {
45
+ std::string result;
46
+ result.reserve(256);
47
+
48
+ if (val.name.empty())
49
+ result += std::format("{}PLACEHOLDER", current_py_tab);
50
+ else
51
+ result += std::format("{}{}", current_py_tab,val.name);
52
+
53
+ result += " :";
54
+
55
+ if (!val.type.empty()) {
56
+ result += std::format(" {}", val.type);
57
+
58
+ if (!val.default_value.empty()) {
59
+ result += ", optional";
60
+ }
61
+ } else {
62
+ result += " Any";
63
+ }
64
+
65
+ if (val.kind != ParameterKind::ARG) {
66
+ result += '\n';
67
+ result += std::format("{}{}{}", current_py_tab, PY_TAB, parameter_kind::to_str(val.kind));
68
+ }
69
+
70
+ if (!val.description.empty()) {
71
+ result += '\n';
72
+ result += std::format("{}{}{}", current_py_tab, PY_TAB, remove_whitespace(val.description));
73
+ if (!result.ends_with('.'))
74
+ result += '.';
75
+ }
76
+
77
+ if (!val.default_value.empty()) {
78
+ std::string offset = " ";
79
+ if (val.description.empty()) {
80
+ result += '\n';
81
+ offset = std::format("{}{}", current_py_tab, PY_TAB);
82
+ }
83
+
84
+ result += std::format("{}default: {}", offset, val.default_value);
85
+ }
86
+
87
+ result = remove_trailing_whitespace(result);
88
+
89
+ docstream += std::format("{}\n", result);
90
+ }
91
+ );
92
+ docstream += '\n';
93
+ return docstream;
94
+ }
95
+
96
+ std::string NumpyDocstring::docstringReturn() noexcept {
97
+ std::string result;
98
+ const auto current_py_tab = get_tabs();
99
+ if (functionInfo.returns.type.empty() and functionInfo.returns.description.empty())
100
+ return "";
101
+
102
+ result.reserve(256);
103
+
104
+ if (!functionInfo.returns.type.empty()) {
105
+ result += std::format("{}Returns\n", current_py_tab);
106
+ result += std::format("{}-------\n", current_py_tab);
107
+
108
+ result += std::format("{}{}", current_py_tab, functionInfo.returns.type);
109
+ }
110
+
111
+ if (!functionInfo.returns.description.empty()) {
112
+ result += '\n';
113
+ result += std::format("{}{}{}", current_py_tab, PY_TAB, functionInfo.returns.description);
114
+ }
115
+
116
+ result += '\n';
117
+ result += '\n';
118
+ return result;
119
+ }
120
+
121
+ std::string NumpyDocstring::docstringExceptions() noexcept {
122
+ if (functionInfo.exceptions.empty())
123
+ return "";
124
+
125
+ std::string result;
126
+ result.reserve(256);
127
+ const auto current_py_tab = get_tabs();
128
+
129
+ result += std::format("{}Raises\n", current_py_tab);
130
+ result += std::format("{}------\n", current_py_tab);
131
+
132
+ for (const auto &[name, description]: functionInfo.exceptions) {
133
+ if (!name.empty()) {
134
+ result += std::format("{}{}", current_py_tab, name);
135
+ result += '\n';
136
+ }
137
+ if (!description.empty()) {
138
+ result += std::format("{}{}{}", current_py_tab, PY_TAB, description);
139
+ }
140
+ result += '\n';
141
+ }
142
+
143
+ return result;
144
+ }
@@ -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;
@@ -7,25 +7,33 @@ void reStructuredDocstring::check_current_docstring() noexcept {
7
7
  const auto current_py_tab = get_tabs();
8
8
  const auto rest_args_begin = functionInfo.docstring.docstring.find(":param");
9
9
 
10
- if (rest_args_begin < std::string::npos) {
10
+ if (rest_args_begin != std::string::npos) {
11
+ const auto strip_len = current_py_tab.size() + 1;
12
+ const auto trim_pos = rest_args_begin > strip_len ? rest_args_begin - strip_len : 0;
11
13
  functionInfo.docstring.docstring = functionInfo.docstring.docstring.substr(
12
14
  0,
13
- rest_args_begin - (current_py_tab.size() + 1)
15
+ trim_pos
14
16
  );
15
17
  functionInfo.docstring.end_line = functionInfo.docstring.start_line + rest_args_begin;
16
18
  }
17
19
  }
18
20
 
21
+ std::string reStructuredDocstring::docstringSummary() noexcept {
22
+ std::string res = functionInfo.docstring.docstring;
23
+ if (res.empty())
24
+ return res;
25
+ if (!functionInfo.summary_only()) {
26
+ if (!res.ends_with('\n'))
27
+ res += '\n';
28
+ }
29
+ return res;
30
+ }
31
+
19
32
  std::string reStructuredDocstring::docstringArgs() noexcept {
20
33
  std::stringstream docstream;
21
34
 
22
35
  const auto current_py_tab = get_tabs();
23
36
 
24
- if (!functionInfo.docstring.docstring.empty()) {
25
- docstream << functionInfo.docstring.docstring;
26
- docstream << "\n";
27
- }
28
-
29
37
  std::ranges::for_each(
30
38
  functionInfo.args,
31
39
  [&docstream, &current_py_tab](const FunctionParameter &val) {
@@ -10,6 +10,8 @@
10
10
  struct reStructuredDocstring : DocstringFormat {
11
11
  void check_current_docstring() noexcept override;
12
12
 
13
+ std::string docstringSummary() noexcept override;
14
+
13
15
  std::string docstringArgs() noexcept override;
14
16
 
15
17
  std::string docstringReturn() noexcept override;
@@ -146,6 +146,27 @@ std::map<std::string, int> check_docstrings(std::string &file_path, const bool &
146
146
  };
147
147
  }
148
148
 
149
+ [[nodiscard]] std::string create_docstring_from_function_info(const FunctionInfo &function_info, const DocstringFormatStyle &formatStyle) noexcept {
150
+ std::unique_ptr<DocstringFormat> docstring_format;
151
+
152
+ switch (formatStyle) {
153
+ case DocstringFormatStyle::reST:
154
+ docstring_format = std::make_unique<reStructuredDocstring>();
155
+ break;
156
+ case DocstringFormatStyle::GOOGLE:
157
+ docstring_format = std::make_unique<GoogleDocstring>();
158
+ break;
159
+ case DocstringFormatStyle::NUMPY:
160
+ docstring_format = std::make_unique<NumpyDocstring>();
161
+ break;
162
+ }
163
+
164
+ docstring_format->functionInfo = function_info;
165
+ docstring_format->check_current_docstring();
166
+
167
+ return docstring_format->docstring();
168
+ }
169
+
149
170
  [[nodiscard]] WriteResult write_to_file_position(
150
171
  std::vector<FunctionInfo> &&infos,
151
172
  const std::string &file_path,
@@ -191,24 +212,11 @@ std::map<std::string, int> check_docstrings(std::string &file_path, const bool &
191
212
 
192
213
  lines.erase(lines.begin() + start_pos, lines.begin() + end_pos);
193
214
 
194
- std::unique_ptr<DocstringFormat> docstring_format;
195
-
196
- switch (formatStyle) {
197
- case DocstringFormatStyle::reST:
198
- docstring_format = std::make_unique<reStructuredDocstring>();
199
- break;
200
- case DocstringFormatStyle::GOOGLE:
201
- docstring_format = std::make_unique<GoogleDocstring>();
202
- break;
203
- case DocstringFormatStyle::NUMPY:
204
- docstring_format = std::make_unique<NumpyDocstring>();
205
- break;
206
- }
207
-
208
- docstring_format->functionInfo = val;
209
- docstring_format->check_current_docstring();
215
+ const auto txt = create_docstring_from_function_info(val, formatStyle);
216
+ if (txt.empty() || txt == "\n")
217
+ continue;
210
218
 
211
- lines.insert(lines.begin() + start_pos, docstring_format->docstring());
219
+ lines.insert(lines.begin() + start_pos, txt);
212
220
  }
213
221
 
214
222
  std::ofstream out_file(file_path);
@@ -20,6 +20,8 @@ void get_docstring_arg_descr(FunctionInfo &functionInfo) noexcept;
20
20
 
21
21
  void parse_file(const std::string &file_path, const DocstringFormatStyle &formatStyle, const bool &allow_overwrite = false, const bool &ignore_magic = false);
22
22
 
23
+ [[nodiscard]] std::string create_docstring_from_function_info(const FunctionInfo &function_info, const DocstringFormatStyle &formatStyle) noexcept;
24
+
23
25
  /*
24
26
  * {
25
27
  * 'num_functions_checked': 0,
@@ -55,9 +55,17 @@ std::string parse_ast_name(const py::object &obj, py::module &) noexcept {
55
55
  }
56
56
 
57
57
  std::string parse_ast_subscript(const py::object &obj, py::module &ast_module) noexcept {
58
- auto value = py::getattr(obj, "value");
59
- auto slice = py::getattr(obj, "slice");
60
- return parse_ast_obj(value, ast_module) + "[" + parse_ast_obj(slice, ast_module) + "]";
58
+ const auto value = py::getattr(obj, "value");
59
+ const auto slice = py::getattr(obj, "slice");
60
+ const std::string module_name = parse_ast_obj(value, ast_module);
61
+ const std::string inner_obj = parse_ast_obj(slice, ast_module);
62
+ if (module_name == "Annotated" || module_name == "Union") {
63
+ return inner_obj;
64
+ }
65
+ if (module_name == "Optional")
66
+ return std::format( "{} | None", inner_obj);
67
+ const std::string res = std::format( "{}[{}]",module_name, inner_obj);
68
+ return res;
61
69
  }
62
70
 
63
71
  std::string parse_ast_attribute(const py::object &obj, py::module &ast_module) noexcept {
@@ -79,21 +87,22 @@ std::string parse_ast_tuple_list(const py::object &obj, py::module &ast_module)
79
87
 
80
88
  for (py::handle item: elts) {
81
89
  auto py_obj = py::reinterpret_borrow<py::object>(item);
82
- result += parse_ast_obj(py_obj, ast_module) + ", ";
90
+ result += parse_ast_obj(py_obj, ast_module) + " | ";
83
91
  }
84
92
 
85
- return result.substr(0, result.size() - 2);
93
+ std::string res = result.substr(0, result.size() - 3);
94
+ if (res.ends_with(" | "))
95
+ res = res.substr(0, res.size() - 3);
96
+ return res;
86
97
  }
87
98
 
88
99
  std::string parse_ast_binop(const py::object &obj, py::module &ast_module) noexcept {
89
100
  auto left = py::getattr(obj, "left");
90
101
  auto right = py::getattr(obj, "right");
91
102
 
92
- std::string result = "Union["
93
- + parse_ast_obj(left, ast_module)
94
- + ", "
95
- + parse_ast_obj(right, ast_module)
96
- + "]";
103
+ std::string result = std::format("{} | {}",
104
+ parse_ast_obj(left, ast_module),
105
+ parse_ast_obj(right, ast_module));
97
106
  return result;
98
107
  }
99
108
 
@@ -1,122 +0,0 @@
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
- functionInfo.docstring.docstring = functionInfo.docstring.docstring.substr(
11
- 0,
12
- numpy_args_begin - (current_py_tab.size() + 1)
13
- );
14
- functionInfo.docstring.end_line = functionInfo.docstring.start_line + numpy_args_begin;
15
- }
16
- }
17
-
18
- std::string NumpyDocstring::docstringArgs() noexcept {
19
- std::stringstream docstream;
20
- const auto current_py_tab = get_tabs();
21
-
22
- if (!functionInfo.docstring.docstring.empty()) {
23
- docstream << functionInfo.docstring.docstring;
24
- docstream << "\n";
25
- }
26
-
27
- if (functionInfo.args.empty())
28
- return "";
29
-
30
- docstream << current_py_tab << "Parameters\n";
31
- docstream << current_py_tab << "----------\n";
32
- std::ranges::for_each(
33
- functionInfo.args,
34
- [&docstream, &current_py_tab](const FunctionParameter &val) {
35
- std::stringstream sstream;
36
-
37
- if (val.name.empty())
38
- sstream << current_py_tab << "PLACEHOLDER";
39
- else
40
- sstream << current_py_tab << val.name;
41
-
42
- sstream << " :";
43
-
44
- if (!val.type.empty()) {
45
- sstream << " " << val.type;
46
-
47
- if (!val.default_value.empty()) {
48
- sstream << ", optional";
49
- }
50
- }
51
-
52
- if (!val.default_value.empty()) {
53
- if (!val.type.empty()) {
54
- sstream << ", ";
55
- }
56
- sstream << "default: " << val.default_value;
57
- }
58
-
59
- sstream << " [" << val.kind << "]";
60
-
61
- if (!val.description.empty()) {
62
- sstream << "\n";
63
- sstream << current_py_tab << PY_TAB << remove_whitespace(val.description);
64
- }
65
-
66
- auto docstring = sstream.str();
67
- docstring = remove_trailing_whitespace(docstring);
68
-
69
- docstream << docstring << "\n";
70
- }
71
- );
72
-
73
- return docstream.str();
74
- }
75
-
76
- std::string NumpyDocstring::docstringReturn() noexcept {
77
- std::stringstream sstream;
78
- const auto current_py_tab = get_tabs();
79
-
80
- if (!functionInfo.returns.type.empty()) {
81
- sstream << "\n";
82
- sstream << current_py_tab << "Returns\n";
83
- sstream << current_py_tab << "-------\n";
84
-
85
- sstream << current_py_tab << functionInfo.returns.type;
86
- }
87
-
88
- if (!functionInfo.returns.description.empty()) {
89
- sstream << "\n";
90
- sstream << current_py_tab << PY_TAB << functionInfo.returns.description;
91
- }
92
-
93
- if (!functionInfo.returns.type.empty() || !functionInfo.returns.description.empty())
94
- sstream << "\n";
95
-
96
- return sstream.str();
97
- }
98
-
99
- std::string NumpyDocstring::docstringExceptions() noexcept {
100
- if (functionInfo.exceptions.empty())
101
- return "";
102
-
103
- std::stringstream sstream;
104
- const auto current_py_tab = get_tabs();
105
-
106
- sstream << "\n";
107
- sstream << current_py_tab << "Raises\n";
108
- sstream << current_py_tab << "-------\n";
109
-
110
- for (const auto &[name, description]: functionInfo.exceptions) {
111
- if (!name.empty()) {
112
- sstream << current_py_tab << name;
113
- sstream << "\n";
114
- }
115
- if (!description.empty()) {
116
- sstream << current_py_tab << PY_TAB << description;
117
- }
118
- sstream << "\n";
119
- }
120
-
121
- return sstream.str();
122
- }