Skip to content

Mark exceptions with export to fix exceptions in shared libraries #1769

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -654,15 +654,23 @@ using expand_side_effects = bool[];
NAMESPACE_END(detail)

/// C++ bindings of builtin Python exceptions
class builtin_exception : public std::runtime_error {
//
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable: 4275) // warning C4275: An exported class was derived from a class that wasn't exported
#endif
class PYBIND11_EXPORT builtin_exception : public std::runtime_error {
public:
using std::runtime_error::runtime_error;
/// Set the error using the Python C API
virtual void set_error() const = 0;
};
#if defined(_MSC_VER)
# pragma warning(pop)
#endif

#define PYBIND11_RUNTIME_EXCEPTION(name, type) \
class name : public builtin_exception { public: \
class PYBIND11_EXPORT name : public builtin_exception { public: \
using builtin_exception::builtin_exception; \
name() : name("") { } \
void set_error() const override { PyErr_SetString(type, what()); } \
Expand Down
18 changes: 12 additions & 6 deletions include/pybind11/pytypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ using list_accessor = accessor<accessor_policies::list_item>;
using tuple_accessor = accessor<accessor_policies::tuple_item>;

/// Tag and check to identify a class which implements the Python object API
class pyobject_tag { };
class PYBIND11_EXPORT pyobject_tag { };
template <typename T> using is_pyobject = std::is_base_of<pyobject_tag, remove_reference_t<T>>;

/** \rst
A mixin class which adds common functions to `handle`, `object` and various accessors.
The only requirement for `Derived` is to implement ``PyObject *Derived::ptr() const``.
\endrst */
template <typename Derived>
class object_api : public pyobject_tag {
class PYBIND11_EXPORT object_api : public pyobject_tag {
const Derived &derived() const { return static_cast<const Derived &>(*this); }

public:
Expand Down Expand Up @@ -171,7 +171,7 @@ NAMESPACE_END(detail)
The `object` class inherits from `handle` and adds automatic reference
counting features.
\endrst */
class handle : public detail::object_api<handle> {
class PYBIND11_EXPORT handle : public detail::object_api<handle> {
public:
/// The default constructor creates a handle with a ``nullptr``-valued pointer
handle() = default;
Expand Down Expand Up @@ -227,7 +227,7 @@ class handle : public detail::object_api<handle> {
scope and is destructed. When using `object` instances consistently, it is much
easier to get reference counting right at the first attempt.
\endrst */
class object : public handle {
class PYBIND11_EXPORT object : public handle {
public:
object() = default;
PYBIND11_DEPRECATED("Use reinterpret_borrow<object>() or reinterpret_steal<object>()")
Expand Down Expand Up @@ -319,7 +319,11 @@ NAMESPACE_END(detail)
/// thrown to propagate python-side errors back through C++ which can either be caught manually or
/// else falls back to the function dispatcher (which then raises the captured error back to
/// python).
class error_already_set : public std::runtime_error {
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable: 4275) // warning C4275: An exported class was derived from a class that wasn't exported
#endif
class PYBIND11_EXPORT error_already_set : public std::runtime_error {
public:
/// Constructs a new exception from the current Python error indicator, if any. The current
/// Python error indicator will be cleared.
Expand Down Expand Up @@ -349,7 +353,9 @@ class error_already_set : public std::runtime_error {
private:
object type, value, trace;
};

#if defined(_MSC_VER)
# pragma warning(pop)
#endif
/** \defgroup python_builtins _
Unless stated otherwise, the following C++ functions behave the same
as their Python counterparts.
Expand Down