6 # pragma warning(disable: 4996) 20 Widget(std::string message) : message(message) { }
21 virtual ~Widget() =
default;
24 virtual int the_answer()
const = 0;
38 .def(py::init<std::string>())
41 m.
def(
"add", [](
int i,
int j) {
return i + j; });
45 throw std::runtime_error(
"C++ Error");
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"));
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);
129 pybind11::detail::get_internals();
133 py::module::import(
"external_module").attr(
"internals_at")().cast<uintptr_t>());
140 py::module::import(
"__main__").attr(
"internals_destroy_test") =
141 py::capsule(&ran, [](
void *ran) { py::detail::get_internals(); *
static_cast<bool *
>(ran) =
true; });
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");
187 REQUIRE_FALSE(
py::hasattr(m,
"extension_module_tag"));
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);
221 auto threads = std::vector<std::thread>();
222 for (
auto i = 0;
i < num_threads; ++
i) {
223 threads.emplace_back([&]() {
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 exec(str expr, object global=globals(), object local=object())
scope_exit(std::function< void()> f) noexcept
bool has_pybind11_internals_static()
glibc defines I as a macro which breaks things, e.g., boost template names
internals **& get_internals_pp()
TEST_CASE("Pass classes and data between modules defined in C++ and Python")
PYBIND11_EMBEDDED_MODULE(widget_module, m)
bool has_pybind11_internals_builtin()
void finalize_interpreter()
#define PYBIND11_INTERNALS_ID
void initialize_interpreter(bool init_signal_handlers=true)
detail::enable_if_t<!detail::move_never< T >::value, T > move(object &&obj)
#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn,...)
bool typename Extra class_ & def(const char *name_, Func &&f, const Extra &... extra)
std::function< void()> f_
bool hasattr(handle obj, handle name)