Skip to content

Commit 5c19270

Browse files
c++: move errors/exception -> errors.cpp
1 parent b4cd2e9 commit 5c19270

3 files changed

Lines changed: 85 additions & 73 deletions

File tree

src/errors.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//
2+
// libsemigroups_pybind11
3+
// Copyright (C) 2025 James D. Mitchell
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU General Public License
16+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
//
18+
19+
#include <stdexcept>
20+
#include <string>
21+
22+
// libsemigroups headers
23+
#include <libsemigroups/exception.hpp>
24+
25+
// pybind11....
26+
#include <pybind11/pybind11.h>
27+
28+
// libsemigroups_pybind11....
29+
#include "main.hpp" // for init_error
30+
31+
namespace libsemigroups {
32+
33+
bool ERROR_MESSAGE_WITH_PREFIX = false;
34+
35+
void error_message_with_prefix(bool value) {
36+
ERROR_MESSAGE_WITH_PREFIX = value;
37+
}
38+
39+
bool error_message_with_prefix() {
40+
return ERROR_MESSAGE_WITH_PREFIX;
41+
}
42+
43+
std::string formatted_error_message(std::runtime_error const& e) {
44+
if (error_message_with_prefix()) {
45+
return std::string(e.what());
46+
} else {
47+
// TODO this doesn't work well if backward is enabled.
48+
std::string out(e.what());
49+
size_t pos = out.find(": ");
50+
if (pos != std::string::npos) {
51+
out.erase(0, pos + 2);
52+
}
53+
return out;
54+
}
55+
}
56+
57+
void init_error(py::module& m) {
58+
// TODO this doesn't seem to properly catch all LibsemigroupsExceptions,
59+
// particularly on macOS. This may have been resolved in pybind11 2.12.0
60+
static py::exception<LibsemigroupsException> exc(
61+
m, "LibsemigroupsError", PyExc_RuntimeError);
62+
py::register_exception_translator([](std::exception_ptr p) {
63+
try {
64+
if (p) {
65+
std::rethrow_exception(p);
66+
}
67+
} catch (LibsemigroupsException const& e) {
68+
exc(formatted_error_message(e).c_str());
69+
} catch (py::stop_iteration const& e) {
70+
throw e;
71+
} catch (std::runtime_error const& e) {
72+
exc(formatted_error_message(e).c_str());
73+
}
74+
});
75+
// TODO: Doc
76+
m.def("error_message_with_prefix",
77+
py::overload_cast<>(&error_message_with_prefix));
78+
m.def("error_message_with_prefix",
79+
py::overload_cast<bool>(&error_message_with_prefix));
80+
}
81+
} // namespace libsemigroups

src/main.cpp

Lines changed: 3 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -18,54 +18,16 @@
1818

1919
#include "main.hpp"
2020

21-
// C std headers....
22-
#include <cstddef> // for size_t
23-
#include <stdexcept>
24-
2521
// libsemigroups....
26-
#include <libsemigroups/config.hpp> // for LIBSEMIGROUPS_EIGEN_ENABLED
27-
#include <libsemigroups/constants.hpp> // for PositiveInfinity, Undefined, POSI...
28-
#include <libsemigroups/detail/kbe.hpp> // for KBE, operator<<
22+
#include <libsemigroups/config.hpp> // for LIBSEMIGROUPS_EIGEN_ENABLED
2923
#include <libsemigroups/detail/report.hpp> // for ReportGuard
30-
#include <libsemigroups/detail/string.hpp> // for to_string
31-
#include <libsemigroups/detail/tce.hpp> // for TCE
32-
#include <libsemigroups/exception.hpp> // for LibsemigroupsException
33-
#include <libsemigroups/types.hpp> // for tril, tril::FALSE, tril::TRUE
34-
35-
#include <libsemigroups/detail/cong-common-class.hpp> // for congruence_kind, congruence_kind:...
3624

3725
// pybind11....
38-
#include <pybind11/operators.h> // for self, operator<, operator==, self_t
39-
#include <pybind11/pybind11.h> // for module_, class_, enum_, init
26+
#include <pybind11/pybind11.h> // for module_, class_, enum_, init
4027

4128
namespace libsemigroups {
4229
namespace py = pybind11;
4330

44-
// TODO move to separate fil
45-
bool ERROR_MESSAGE_WITH_PREFIX = false;
46-
47-
void error_message_with_prefix(bool value) {
48-
ERROR_MESSAGE_WITH_PREFIX = value;
49-
}
50-
51-
bool error_message_with_prefix() {
52-
return ERROR_MESSAGE_WITH_PREFIX;
53-
}
54-
55-
std::string formatted_error_message(std::runtime_error const& e) {
56-
if (error_message_with_prefix()) {
57-
return std::string(e.what());
58-
} else {
59-
// TODO this doesn't work well if backward is enabled.
60-
std::string out(e.what());
61-
size_t pos = out.find(": ");
62-
if (pos != std::string::npos) {
63-
out.erase(0, pos + 2);
64-
}
65-
return out;
66-
}
67-
}
68-
6931
PYBIND11_MODULE(_libsemigroups_pybind11, m) {
7032
////////////////////////////////////////////////////////////////////////
7133
// Module attributes
@@ -90,28 +52,6 @@ namespace libsemigroups {
9052
m.attr("LIBSEMIGROUPS_HPCOMBI_ENABLED") = false;
9153
#endif
9254

93-
////////////////////////////////////////////////////////////////////////
94-
// Exceptions
95-
////////////////////////////////////////////////////////////////////////
96-
97-
// TODO this doesn't seem to properly catch all LibsemigroupsExceptions,
98-
// particularly on macOS. This may have been resolved in pybind11 2.12.0
99-
static py::exception<LibsemigroupsException> exc(
100-
m, "LibsemigroupsError", PyExc_RuntimeError);
101-
py::register_exception_translator([](std::exception_ptr p) {
102-
try {
103-
if (p) {
104-
std::rethrow_exception(p);
105-
}
106-
} catch (LibsemigroupsException const& e) {
107-
exc(formatted_error_message(e).c_str());
108-
} catch (py::stop_iteration const& e) {
109-
throw e;
110-
} catch (std::runtime_error const& e) {
111-
exc(formatted_error_message(e).c_str());
112-
}
113-
});
114-
11555
////////////////////////////////////////////////////////////////////////
11656
// Classes that need to be initialised early
11757
////////////////////////////////////////////////////////////////////////
@@ -136,6 +76,7 @@ namespace libsemigroups {
13676
init_bmat8(m);
13777
init_cong(m);
13878
init_dot(m);
79+
init_error(m);
13980
init_forest(m);
14081
init_freeband(m);
14182
init_froidure_pin_base(m); // Must be before init_froidure_pin
@@ -193,16 +134,5 @@ default.
193134
:type val:
194135
bool
195136
)pbdoc");
196-
197-
////////////////////////////////////////////////////////////////////////
198-
// Global variables
199-
////////////////////////////////////////////////////////////////////////
200-
201-
// TODO: Doc
202-
m.def("error_message_with_prefix",
203-
py::overload_cast<>(&error_message_with_prefix));
204-
m.def("error_message_with_prefix",
205-
py::overload_cast<bool>(&error_message_with_prefix));
206137
}
207-
208138
} // namespace libsemigroups

src/main.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ namespace libsemigroups {
4141
void init_cong(py::module&);
4242
void init_constants(py::module&);
4343
void init_dot(py::module&);
44+
void init_error(py::module&);
4445
void init_forest(py::module&);
4546
void init_freeband(py::module&);
4647
void init_froidure_pin(py::module&);

0 commit comments

Comments
 (0)