@@ -360,7 +360,7 @@ T reinterpret_steal(handle h) {
360
360
}
361
361
362
362
PYBIND11_NAMESPACE_BEGIN (detail)
363
- std::string error_string();
363
+ std::string error_string(const char *called = nullptr );
364
364
PYBIND11_NAMESPACE_END (detail)
365
365
366
366
#if defined(_MSC_VER)
@@ -375,20 +375,27 @@ PYBIND11_NAMESPACE_END(detail)
375
375
// / python).
376
376
class PYBIND11_EXPORT_EXCEPTION error_already_set : public std::runtime_error {
377
377
public:
378
- // / Constructs a new exception from the current Python error indicator, if any . The current
378
+ // / Constructs a new exception from the current Python error indicator. The current
379
379
// / Python error indicator will be cleared.
380
- error_already_set () : std::runtime_error(detail::error_string()) {
380
+ error_already_set () : std::runtime_error(detail::error_string(" pybind11::error_already_set " )) {
381
381
PyErr_Fetch (&m_type.ptr (), &m_value.ptr (), &m_trace.ptr ());
382
382
}
383
383
384
+ // / WARNING: The GIL must be held when this copy constructor is invoked!
384
385
error_already_set (const error_already_set &) = default ;
385
386
error_already_set (error_already_set &&) = default ;
386
387
388
+ // / WARNING: This destructor needs to acquire the Python GIL. This can lead to
389
+ // / crashes (undefined behavior) if the Python interpreter is finalizing.
387
390
inline ~error_already_set () override ;
388
391
389
- // / Give the currently-held error back to Python, if any. If there is currently a Python error
390
- // / already set it is cleared first. After this call, the current object no longer stores the
391
- // / error variables (but the `.what()` string is still available).
392
+ // / Restores the currently-held Python error (which will clear the Python error indicator first
393
+ // / if already set). After this call, the current object no longer stores the error variables.
394
+ // / NOTE: Any copies of this object may still store the error variables. Currently there is no
395
+ // protection against calling restore() from multiple copies.
396
+ // / NOTE: This member function will always restore the normalized exception, which may or may
397
+ // / not be the original Python exception.
398
+ // / WARNING: The GIL must be held when this member function is called!
392
399
void restore () {
393
400
PyErr_Restore (m_type.release ().ptr (), m_value.release ().ptr (), m_trace.release ().ptr ());
394
401
}
@@ -405,6 +412,7 @@ class PYBIND11_EXPORT_EXCEPTION error_already_set : public std::runtime_error {
405
412
}
406
413
// / An alternate version of `discard_as_unraisable()`, where a string provides information on
407
414
// / the location of the error. For example, `__func__` could be helpful.
415
+ // / WARNING: The GIL must be held when this member function is called!
408
416
void discard_as_unraisable (const char *err_context) {
409
417
discard_as_unraisable (reinterpret_steal<object>(PYBIND11_FROM_STRING (err_context)));
410
418
}
0 commit comments