15 using namespace py::literals;
18 auto sys_path = py::module::import(
"sys").attr(
"path");
25 virtual ~Widget() =
default;
28 virtual int the_answer()
const = 0;
29 virtual std::string argv0()
const = 0;
45 virtual int func() {
return 0; }
59 py::class_<Widget, PyWidget>(
m,
"Widget")
60 .def(py::init<std::string>())
63 m.def(
"add", [](
int i,
int j) {
return i +
j; });
69 std::shared_ptr<test_override_cache_helper>>(
m,
"test_override_cache_helper")
70 .def(py::init_alias<>())
78 d[
"missing"].cast<py::object>();
81 TEST_CASE(
"PYTHONPATH is used to update sys.path") {
83 auto sys_path =
py::str(py::module_::import(
"sys").attr(
"path")).cast<std::string>();
84 REQUIRE_THAT(sys_path,
85 Catch::Matchers::Contains(
"pybind11_test_embed_PYTHONPATH_2099743835476552"));
88 TEST_CASE(
"Pass classes and data between modules defined in C++ and Python") {
89 auto module_ = py::module_::import(
"test_interpreter");
92 auto locals = py::dict(
"hello"_a =
"Hello, World!",
"x"_a = 5, **
module_.attr(
"__dict__"));
94 widget = DerivedWidget("{} - {}".format(hello, x))
95 message = widget.the_message
99 REQUIRE(locals["message"].cast<std::string>() ==
"Hello, World! - 5");
101 auto py_widget =
module_.attr(
"DerivedWidget")(
"The question");
102 auto message = py_widget.attr(
"the_message");
103 REQUIRE(message.cast<std::string>() ==
"The question");
105 const auto &cpp_widget = py_widget.cast<
const Widget &>();
106 REQUIRE(cpp_widget.the_answer() == 42);
110 auto module_ = py::module_::import(
"test_trampoline");
114 auto locals = py::dict(**
module_.attr(
"__dict__"));
117 for (;
i < 1500; ++
i) {
118 std::shared_ptr<test_override_cache_helper> p_obj;
119 std::shared_ptr<test_override_cache_helper> p_obj2;
121 py::object loc_inst = locals[
"func"]();
122 p_obj = py::cast<std::shared_ptr<test_override_cache_helper>>(loc_inst);
124 int ret = p_obj->func();
128 loc_inst = locals[
"func2"]();
130 p_obj2 = py::cast<std::shared_ptr<test_override_cache_helper>>(loc_inst);
137 REQUIRE_NOTHROW(py::module_::import(
"widget_module"));
138 REQUIRE_THROWS_WITH(py::module_::import(
"throw_exception"),
"ImportError: C++ Error");
139 REQUIRE_THROWS_WITH(py::module_::import(
"throw_error_already_set"),
140 Catch::Contains(
"ImportError: initialization failed"));
142 auto locals = py::dict(
"is_keyerror"_a =
false,
"message"_a =
"not set");
145 import throw_error_already_set
146 except ImportError as e:
147 is_keyerror = type(e.__cause__) == KeyError
148 message = str(e.__cause__)
152 REQUIRE(locals["is_keyerror"].cast<bool>() ==
true);
153 REQUIRE(locals[
"message"].cast<std::string>() ==
"'missing'");
163 REQUIRE_THROWS_WITH(py::scoped_interpreter(),
"The interpreter is already running");
166 REQUIRE_NOTHROW(py::scoped_interpreter());
168 auto pyi1 = py::scoped_interpreter();
169 auto pyi2 = std::move(pyi1);
174 #if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
178 PyConfig_InitPythonConfig(&config);
179 REQUIRE_NOTHROW(py::scoped_interpreter{&config});
181 py::scoped_interpreter
p{&config};
182 REQUIRE(py::module_::import(
"widget_module").attr(
"add")(1, 41).cast<int>() == 42);
187 TEST_CASE(
"scoped_interpreter with PyConfig_InitIsolatedConfig and argv") {
191 PyConfig_InitIsolatedConfig(&config);
192 char *argv[] = {strdup(
"a.out")};
193 py::scoped_interpreter argv_scope{&config, 1, argv};
195 auto module = py::module::import(
"test_interpreter");
196 auto py_widget =
module.attr(
"DerivedWidget")(
"The question");
197 const auto &cpp_widget = py_widget.
cast<
const Widget &>();
198 REQUIRE(cpp_widget.argv0() ==
"a.out");
203 TEST_CASE(
"scoped_interpreter with PyConfig_InitPythonConfig and argv") {
207 PyConfig_InitPythonConfig(&config);
211 char *argv[] = {strdup(
"a.out"), strdup(
"arg1")};
212 py::scoped_interpreter argv_scope(&config, 2, argv);
215 auto module = py::module::import(
"test_interpreter");
216 auto py_widget =
module.attr(
"DerivedWidget")(
"The question");
217 const auto &cpp_widget = py_widget.
cast<
const Widget &>();
218 REQUIRE(cpp_widget.argv0() ==
"arg1");
226 size_t path_size_add_program_dir_to_path_false = 0;
228 py::scoped_interpreter scoped_interp{
true, 0,
nullptr,
false};
232 py::scoped_interpreter scoped_interp{};
238 #if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
241 size_t path_size_add_program_dir_to_path_false = 0;
244 PyConfig_InitPythonConfig(&config);
245 py::scoped_interpreter scoped_interp{&config, 0,
nullptr,
false};
250 PyConfig_InitPythonConfig(&config);
251 py::scoped_interpreter scoped_interp{&config};
265 return (ipp !=
nullptr) && (*ipp !=
nullptr);
270 REQUIRE(py::module_::import(
"widget_module").attr(
"add")(1, 2).cast<int>() == 3);
273 REQUIRE(py::module_::import(
"external_module").attr(
"A")(123).attr(
"value").cast<int>()
278 == py::module_::import(
"external_module").attr(
"internals_at")().cast<uintptr_t>());
282 REQUIRE(Py_IsInitialized() == 0);
285 REQUIRE(Py_IsInitialized() == 1);
294 == py::module_::import(
"external_module").attr(
"internals_at")().cast<uintptr_t>());
301 py::module_::import(
"__main__").attr(
"internals_destroy_test")
302 = py::capsule(&ran, [](
void *ran) {
304 *
static_cast<bool *
>(ran) =
true;
316 auto cpp_module = py::module_::import(
"widget_module");
317 REQUIRE(cpp_module.attr(
"add")(1, 2).cast<
int>() == 3);
320 auto py_module = py::module_::import(
"test_interpreter");
321 auto py_widget = py_module.attr(
"DerivedWidget")(
"Hello after restart");
322 REQUIRE(py_widget.attr(
"the_message").cast<std::string>() ==
"Hello after restart");
327 py::module_::import(
"__main__").attr(
"main_tag") =
"main interpreter";
329 auto m = py::module_::import(
"widget_module");
330 m.attr(
"extension_module_tag") =
"added to module in main interpreter";
332 REQUIRE(
m.attr(
"add")(1, 2).cast<
int>() == 3);
338 auto *main_tstate = PyThreadState_Get();
339 auto *sub_tstate = Py_NewInterpreter();
348 REQUIRE_FALSE(
py::hasattr(py::module_::import(
"__main__"),
"tag"));
350 auto m = py::module_::import(
"widget_module");
354 REQUIRE(
m.attr(
"add")(1, 2).cast<
int>() == 3);
358 Py_EndInterpreter(sub_tstate);
359 PyThreadState_Swap(main_tstate);
361 REQUIRE(
py::hasattr(py::module_::import(
"__main__"),
"main_tag"));
362 REQUIRE(
py::hasattr(py::module_::import(
"widget_module"),
"extension_module_tag"));
369 REQUIRE(
py::globals()[
"var"][
"number"].cast<int>() == 42);
378 constexpr
auto num_threads = 10;
379 auto locals = py::dict(
"count"_a = 0);
382 py::gil_scoped_release gil_release{};
384 auto threads = std::vector<std::thread>();
385 for (
auto i = 0;
i < num_threads; ++
i) {
386 threads.emplace_back([&]() {
387 py::gil_scoped_acquire gil{};
388 locals[
"count"] = locals[
"count"].cast<
int>() + 1;
392 for (
auto &thread : threads) {
397 REQUIRE(locals[
"count"].cast<int>() == num_threads);
402 std::function<void()>
f_;
403 explicit scope_exit(std::function<
void()>
f) noexcept : f_(std::move(
f)) {}
415 auto sys = py::module_::import(
"sys");
416 bool dont_write_bytecode = sys.attr(
"dont_write_bytecode").cast<
bool>();
417 sys.attr(
"dont_write_bytecode") =
true;
420 [&]() { sys.attr(
"dont_write_bytecode") = dont_write_bytecode; });
426 std::ofstream test_module(module_file);
427 test_module <<
"def test():\n";
428 test_module <<
" return 1\n";
431 scope_exit delete_module_file([&]() { std::remove(module_file.c_str()); });
439 test_module.open(module_file);
440 test_module <<
"def test():\n";
441 test_module <<
" return 2\n";
453 py::scoped_interpreter default_scope;
454 auto module = py::module::import(
"test_interpreter");
455 auto py_widget =
module.attr(
"DerivedWidget")(
"The question");
456 const auto &cpp_widget = py_widget.
cast<
const Widget &>();
457 REQUIRE(cpp_widget.argv0().empty());
461 char *argv[] = {strdup(
"a.out")};
462 py::scoped_interpreter argv_scope(
true, 1, argv);
464 auto module = py::module::import(
"test_interpreter");
465 auto py_widget =
module.attr(
"DerivedWidget")(
"The question");
466 const auto &cpp_widget = py_widget.
cast<
const Widget &>();
467 REQUIRE(cpp_widget.argv0() ==
"a.out");
472 TEST_CASE(
"make_iterator can be called before then after finalizing an interpreter") {
476 std::vector<int> container;
478 pybind11::scoped_interpreter
g;
482 REQUIRE_NOTHROW([&]() {
483 pybind11::scoped_interpreter
g;