6 # pragma warning(disable : 4996) 22 virtual ~Widget() =
default;
25 virtual int the_answer()
const = 0;
26 virtual std::string argv0()
const = 0;
42 virtual int func() {
return 0; }
56 py::class_<Widget, PyWidget>(
m,
"Widget")
57 .def(py::init<std::string>())
60 m.def(
"add", [](
int i,
int j) {
return i +
j; });
66 std::shared_ptr<test_override_cache_helper>>(
m,
"test_override_cache_helper")
67 .def(py::init_alias<>())
75 d[
"missing"].cast<py::object>();
78 TEST_CASE(
"Pass classes and data between modules defined in C++ and Python") {
79 auto module_ = py::module_::import(
"test_interpreter");
82 auto locals = py::dict(
"hello"_a =
"Hello, World!",
"x"_a = 5, **
module_.attr(
"__dict__"));
84 widget = DerivedWidget("{} - {}".format(hello, x)) 85 message = widget.the_message 89 REQUIRE(locals["message"].cast<std::string>() ==
"Hello, World! - 5");
91 auto py_widget =
module_.attr(
"DerivedWidget")(
"The question");
92 auto message = py_widget.attr(
"the_message");
93 REQUIRE(message.cast<std::string>() ==
"The question");
95 const auto &cpp_widget = py_widget.cast<
const Widget &>();
96 REQUIRE(cpp_widget.the_answer() == 42);
100 auto module_ = py::module_::import(
"test_trampoline");
104 auto locals = py::dict(**
module_.attr(
"__dict__"));
107 for (; i < 1500; ++
i) {
108 std::shared_ptr<test_override_cache_helper> p_obj;
109 std::shared_ptr<test_override_cache_helper> p_obj2;
111 py::object loc_inst = locals[
"func"]();
112 p_obj = py::cast<std::shared_ptr<test_override_cache_helper>>(loc_inst);
114 int ret = p_obj->func();
118 loc_inst = locals[
"func2"]();
120 p_obj2 = py::cast<std::shared_ptr<test_override_cache_helper>>(loc_inst);
127 REQUIRE_NOTHROW(py::module_::import(
"widget_module"));
128 REQUIRE_THROWS_WITH(py::module_::import(
"throw_exception"),
"ImportError: C++ Error");
129 REQUIRE_THROWS_WITH(py::module_::import(
"throw_error_already_set"),
130 Catch::Contains(
"ImportError: initialization failed"));
132 auto locals = py::dict(
"is_keyerror"_a =
false,
"message"_a =
"not set");
135 import throw_error_already_set 136 except ImportError as e: 137 is_keyerror = type(e.__cause__) == KeyError 138 message = str(e.__cause__) 142 REQUIRE(locals["is_keyerror"].cast<bool>() ==
true);
143 REQUIRE(locals[
"message"].cast<std::string>() ==
"'missing'");
153 REQUIRE_THROWS_WITH(py::scoped_interpreter(),
"The interpreter is already running");
156 REQUIRE_NOTHROW(py::scoped_interpreter());
158 auto pyi1 = py::scoped_interpreter();
159 auto pyi2 = std::move(pyi1);
165 auto builtins = py::handle(PyEval_GetBuiltins());
171 return (ipp !=
nullptr) && (*ipp !=
nullptr);
176 REQUIRE(py::module_::import(
"widget_module").attr(
"add")(1, 2).cast<int>() == 3);
179 REQUIRE(py::module_::import(
"external_module").attr(
"A")(123).attr(
"value").cast<int>()
184 == py::module_::import(
"external_module").attr(
"internals_at")().cast<uintptr_t>());
188 REQUIRE(Py_IsInitialized() == 0);
191 REQUIRE(Py_IsInitialized() == 1);
200 == py::module_::import(
"external_module").attr(
"internals_at")().cast<uintptr_t>());
207 py::module_::import(
"__main__").attr(
"internals_destroy_test")
208 = py::capsule(&ran, [](
void *ran) {
210 *
static_cast<bool *
>(ran) =
true;
222 auto cpp_module = py::module_::import(
"widget_module");
223 REQUIRE(cpp_module.attr(
"add")(1, 2).cast<int>() == 3);
226 auto py_module = py::module_::import(
"test_interpreter");
227 auto py_widget = py_module.attr(
"DerivedWidget")(
"Hello after restart");
228 REQUIRE(py_widget.attr(
"the_message").cast<std::string>() ==
"Hello after restart");
233 py::module_::import(
"__main__").attr(
"main_tag") =
"main interpreter";
235 auto m = py::module_::import(
"widget_module");
236 m.attr(
"extension_module_tag") =
"added to module in main interpreter";
238 REQUIRE(
m.attr(
"add")(1, 2).cast<int>() == 3);
244 auto *main_tstate = PyThreadState_Get();
245 auto *sub_tstate = Py_NewInterpreter();
254 REQUIRE_FALSE(
py::hasattr(py::module_::import(
"__main__"),
"tag"));
256 auto m = py::module_::import(
"widget_module");
260 REQUIRE(
m.attr(
"add")(1, 2).cast<int>() == 3);
264 Py_EndInterpreter(sub_tstate);
265 PyThreadState_Swap(main_tstate);
267 REQUIRE(
py::hasattr(py::module_::import(
"__main__"),
"main_tag"));
268 REQUIRE(
py::hasattr(py::module_::import(
"widget_module"),
"extension_module_tag"));
275 REQUIRE(
py::globals()[
"var"][
"number"].cast<int>() == 42);
284 constexpr
auto num_threads = 10;
285 auto locals = py::dict(
"count"_a = 0);
288 py::gil_scoped_release gil_release{};
291 auto threads = std::vector<std::thread>();
292 for (
auto i = 0;
i < num_threads; ++
i) {
293 threads.emplace_back([&]() {
294 py::gil_scoped_acquire gil{};
295 locals[
"count"] = locals[
"count"].cast<
int>() + 1;
299 for (
auto &thread : threads) {
304 REQUIRE(locals[
"count"].cast<int>() == num_threads);
309 std::function<void()>
f_;
310 explicit scope_exit(std::function<
void()>
f) noexcept : f_(std::move(
f)) {}
322 auto sys = py::module_::import(
"sys");
323 bool dont_write_bytecode = sys.attr(
"dont_write_bytecode").cast<
bool>();
324 sys.attr(
"dont_write_bytecode") =
true;
327 [&]() { sys.attr(
"dont_write_bytecode") = dont_write_bytecode; });
330 std::string module_file = module_name +
".py";
333 std::ofstream test_module(module_file);
334 test_module <<
"def test():\n";
335 test_module <<
" return 1\n";
338 scope_exit delete_module_file([&]() { std::remove(module_file.c_str()); });
341 auto module_ = py::module_::import(module_name.c_str());
342 int result = module_.attr(
"test")().cast<int>();
343 REQUIRE(result == 1);
346 test_module.open(module_file);
347 test_module <<
"def test():\n";
348 test_module <<
" return 2\n";
353 result = module_.attr(
"test")().cast<int>();
354 REQUIRE(result == 2);
360 py::scoped_interpreter default_scope;
361 auto module = py::module::import(
"test_interpreter");
362 auto py_widget =
module.attr(
"DerivedWidget")(
"The question");
363 const auto &cpp_widget = py_widget.
cast<
const Widget &>();
364 REQUIRE(cpp_widget.argv0().empty());
368 char *argv[] = {strdup(
"a.out")};
369 py::scoped_interpreter argv_scope(
true, 1, argv);
371 auto module = py::module::import(
"test_interpreter");
372 auto py_widget =
module.attr(
"DerivedWidget")(
"The question");
373 const auto &cpp_widget = py_widget.
cast<
const Widget &>();
374 REQUIRE(cpp_widget.argv0() ==
"a.out");
379 TEST_CASE(
"make_iterator can be called before then after finalizing an interpreter") {
383 std::vector<int> container;
385 pybind11::scoped_interpreter
g;
389 REQUIRE_NOTHROW([&]() {
390 pybind11::scoped_interpreter
g;
void initialize_interpreter(bool init_signal_handlers=true, int argc=0, const char *const *argv=nullptr, bool add_program_dir_to_path=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)
iterator iter(handle obj)
bool has_pybind11_internals_builtin()
void g(const string &key, int i)
void exec(const str &expr, object global=globals(), object local=object())
scope_exit(std::function< void()> f) noexcept
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
#define PYBIND11_OVERRIDE(ret_type, cname, fn,...)
#define PYBIND11_INTERNALS_ID
iterator make_iterator(Iterator &&first, Sentinel &&last, Extra &&...extra)
Makes a python iterator from a first and past-the-end C++ InputIterator.
#define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn,...)
std::function< void()> f_
internals **& get_internals_pp()