6 # pragma warning(disable: 4996) 20 Widget(std::string message) : message(message) { }
21 virtual ~Widget() =
default;
24 virtual int the_answer()
const = 0;
37 py::class_<Widget, PyWidget>(
m,
"Widget")
38 .def(py::init<std::string>())
41 m.def(
"add", [](
int i,
int j) {
return i +
j; });
45 throw std::runtime_error(
"C++ Error");
50 d[
"missing"].cast<py::object>();
53 TEST_CASE(
"Pass classes and data between modules defined in C++ and Python") {
54 auto module = py::module::import(
"test_interpreter");
57 auto locals = py::dict(
"hello"_a=
"Hello, World!",
"x"_a=5, **
module.attr(
"__dict__"));
59 widget = DerivedWidget("{} - {}".format(hello, x)) 60 message = widget.the_message 62 REQUIRE(locals["message"].cast<std::string>() ==
"Hello, World! - 5");
64 auto py_widget =
module.attr(
"DerivedWidget")(
"The question");
65 auto message = py_widget.attr(
"the_message");
66 REQUIRE(message.cast<std::string>() ==
"The question");
68 const auto &cpp_widget = py_widget.cast<
const Widget &>();
69 REQUIRE(cpp_widget.the_answer() == 42);
73 REQUIRE_NOTHROW(py::module::import(
"widget_module"));
74 REQUIRE_THROWS_WITH(py::module::import(
"throw_exception"),
75 "ImportError: C++ Error");
76 REQUIRE_THROWS_WITH(py::module::import(
"throw_error_already_set"),
77 Catch::Contains(
"ImportError: KeyError"));
87 REQUIRE_THROWS_WITH(py::scoped_interpreter(),
"The interpreter is already running");
90 REQUIRE_NOTHROW(py::scoped_interpreter());
92 auto pyi1 = py::scoped_interpreter();
93 auto pyi2 = std::move(pyi1);
99 auto builtins = py::handle(PyEval_GetBuiltins());
110 REQUIRE(py::module::import(
"widget_module").attr(
"add")(1, 2).cast<int>() == 3);
113 REQUIRE(py::module::import(
"external_module").attr(
"A")(123).attr(
"value").cast<int>() == 123);
117 py::module::import(
"external_module").attr(
"internals_at")().cast<uintptr_t>());
121 REQUIRE(Py_IsInitialized() == 0);
124 REQUIRE(Py_IsInitialized() == 1);
133 py::module::import(
"external_module").attr(
"internals_at")().cast<uintptr_t>());
140 py::module::import(
"__main__").attr(
"internals_destroy_test") =
152 auto cpp_module = py::module::import(
"widget_module");
153 REQUIRE(cpp_module.attr(
"add")(1, 2).cast<int>() == 3);
156 auto py_module = py::module::import(
"test_interpreter");
157 auto py_widget = py_module.attr(
"DerivedWidget")(
"Hello after restart");
158 REQUIRE(py_widget.attr(
"the_message").cast<std::string>() ==
"Hello after restart");
163 py::module::import(
"__main__").attr(
"main_tag") =
"main interpreter";
165 auto m = py::module::import(
"widget_module");
166 m.attr(
"extension_module_tag") =
"added to module in main interpreter";
168 REQUIRE(
m.attr(
"add")(1, 2).cast<int>() == 3);
174 auto main_tstate = PyThreadState_Get();
175 auto sub_tstate = Py_NewInterpreter();
184 REQUIRE_FALSE(
py::hasattr(py::module::import(
"__main__"),
"tag"));
186 auto m = py::module::import(
"widget_module");
190 REQUIRE(
m.attr(
"add")(1, 2).cast<int>() == 3);
194 Py_EndInterpreter(sub_tstate);
195 PyThreadState_Swap(main_tstate);
197 REQUIRE(
py::hasattr(py::module::import(
"__main__"),
"main_tag"));
198 REQUIRE(
py::hasattr(py::module::import(
"widget_module"),
"extension_module_tag"));
205 REQUIRE(
py::globals()[
"var"][
"number"].cast<int>() == 42);
214 constexpr
auto num_threads = 10;
215 auto locals = py::dict(
"count"_a=0);
218 py::gil_scoped_release gil_release{};
221 auto threads = std::vector<std::thread>();
222 for (
auto i = 0;
i < num_threads; ++
i) {
223 threads.emplace_back([&]() {
224 py::gil_scoped_acquire gil{};
225 locals[
"count"] = locals[
"count"].cast<
int>() + 1;
229 for (
auto &thread : threads) {
234 REQUIRE(locals[
"count"].cast<int>() == num_threads);
239 std::function<void()>
f_;
248 auto sys = py::module::import(
"sys");
249 bool dont_write_bytecode = sys.attr(
"dont_write_bytecode").cast<
bool>();
250 sys.attr(
"dont_write_bytecode") =
true;
253 sys.attr(
"dont_write_bytecode") = dont_write_bytecode;
256 std::string module_name =
"test_module_reload";
257 std::string module_file = module_name +
".py";
260 std::ofstream test_module(module_file);
261 test_module <<
"def test():\n";
262 test_module <<
" return 1\n";
266 std::remove(module_file.c_str());
270 auto module = py::module::import(module_name.c_str());
271 int result = module.attr(
"test")().cast<int>();
272 REQUIRE(result == 1);
275 test_module.open(module_file);
276 test_module <<
"def test():\n";
277 test_module <<
" return 2\n";
282 result = module.attr(
"test")().cast<int>();
283 REQUIRE(result == 2);
void initialize_interpreter(bool init_signal_handlers=true)
bool hasattr(handle obj, handle name)
bool has_pybind11_internals_static()
PYBIND11_NOINLINE internals & get_internals()
Return a reference to the current internals data.
void finalize_interpreter()
Wrapper for Python extension modules.
TEST_CASE("Pass classes and data between modules defined in C++ and Python")
PYBIND11_EMBEDDED_MODULE(widget_module, m)
bool has_pybind11_internals_builtin()
scope_exit(std::function< void()> f) noexcept
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
#define PYBIND11_INTERNALS_ID
#define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn,...)
std::function< void()> f_
void exec(str expr, object global=globals(), object local=object())
internals **& get_internals_pp()