Skip to content

Commit 7a95a23

Browse files
committed
Simple experiments contrasting Boost.Python vs pybind11 error_already_set.
1 parent 4da4c4e commit 7a95a23

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include <stdexcept>
2+
3+
std::string error_string() {
4+
return "Implementation without side-effects here.";
5+
}
6+
7+
struct error_already_set : std::exception {
8+
error_already_set() : m_py_error_indicator("Fetch here.") {}
9+
~error_already_set() { /* GIL-safe dec_ref. */
10+
}
11+
12+
void restore() { /* Restore here. */
13+
}
14+
15+
const char* what() const noexcept override {
16+
m_what = m_py_error_indicator + ": " + error_string();
17+
return m_what.c_str();
18+
}
19+
20+
std::string m_py_error_indicator;
21+
mutable std::string m_what;
22+
};
23+
24+
void use_what() {
25+
try {
26+
// Now error_already_set is not a fitting name anymore.
27+
// throw fetched_python_error(); would be a more accurate description.
28+
throw error_already_set();
29+
} catch (error_already_set& e) {
30+
e.restore();
31+
// But we could also Fetch or Clear the error here, as needed.
32+
// The reason for Fetch in the error_already_set constructor is
33+
// something rwgk@ does not know.
34+
}
35+
}
36+
37+
int main() { use_what(); }
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include <iostream>
2+
#include <stdexcept>
3+
4+
std::string error_string() {
5+
return "Implementation without side-effects here.";
6+
}
7+
8+
struct error_already_set : std::exception {
9+
const char* what() const noexcept override {
10+
m_what = error_string();
11+
return m_what.c_str();
12+
}
13+
mutable std::string m_what;
14+
};
15+
16+
void use_error_string() {
17+
try {
18+
throw error_already_set();
19+
} catch (const error_already_set&) {
20+
std::cout << error_string() << std::endl;
21+
}
22+
}
23+
24+
void use_what() {
25+
try {
26+
throw error_already_set();
27+
} catch (const error_already_set& e) {
28+
// Is enabling e.what() worth the m_what overhead?
29+
std::cout << e.what() << std::endl;
30+
}
31+
}
32+
33+
int main() {
34+
use_error_string();
35+
use_what();
36+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <iostream>
2+
#include <stdexcept>
3+
4+
// Actual & complete Boost.Python implementation (except for the EXPORT macro).
5+
struct error_already_set {
6+
virtual ~error_already_set();
7+
};
8+
9+
int main() {
10+
std::cout << sizeof(error_already_set) << std::endl;
11+
std::cout << sizeof(std::exception) << std::endl;
12+
std::cout << sizeof(std::runtime_error) << std::endl;
13+
}

0 commit comments

Comments
 (0)