mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-30 08:57:11 +00:00
de4ba92c9f
* Add `error_scope` to `detail::get_internals()` * Adjust test to tolerate macOS PyPy behavior.
52 lines
1.7 KiB
C++
52 lines
1.7 KiB
C++
/*
|
|
Copyright (c) 2022 Google LLC
|
|
|
|
All rights reserved. Use of this source code is governed by a
|
|
BSD-style license that can be found in the LICENSE file.
|
|
*/
|
|
|
|
#include <pybind11/pybind11.h>
|
|
|
|
// This file mimics a DSO that makes pybind11 calls but does not define a PYBIND11_MODULE,
|
|
// so that the first call of cross_module_error_already_set() triggers the first call of
|
|
// pybind11::detail::get_internals().
|
|
|
|
namespace {
|
|
|
|
namespace py = pybind11;
|
|
|
|
void interleaved_error_already_set() {
|
|
PyErr_SetString(PyExc_RuntimeError, "1st error.");
|
|
try {
|
|
throw py::error_already_set();
|
|
} catch (const py::error_already_set &) {
|
|
// The 2nd error could be conditional in a real application.
|
|
PyErr_SetString(PyExc_RuntimeError, "2nd error.");
|
|
} // Here the 1st error is destroyed before the 2nd error is fetched.
|
|
// The error_already_set dtor triggers a pybind11::detail::get_internals()
|
|
// call via pybind11::gil_scoped_acquire.
|
|
if (PyErr_Occurred()) {
|
|
throw py::error_already_set();
|
|
}
|
|
}
|
|
|
|
constexpr char kModuleName[] = "cross_module_interleaved_error_already_set";
|
|
|
|
struct PyModuleDef moduledef = {
|
|
PyModuleDef_HEAD_INIT, kModuleName, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr};
|
|
|
|
} // namespace
|
|
|
|
extern "C" PYBIND11_EXPORT PyObject *PyInit_cross_module_interleaved_error_already_set() {
|
|
PyObject *m = PyModule_Create(&moduledef);
|
|
if (m != nullptr) {
|
|
static_assert(sizeof(&interleaved_error_already_set) == sizeof(void *),
|
|
"Function pointer must have the same size as void *");
|
|
PyModule_AddObject(
|
|
m,
|
|
"funcaddr",
|
|
PyLong_FromVoidPtr(reinterpret_cast<void *>(&interleaved_error_already_set)));
|
|
}
|
|
return m;
|
|
}
|