Warning, file /include/pybind11/embed.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #pragma once
0011
0012 #include "pybind11.h"
0013 #include "eval.h"
0014
0015 #include <memory>
0016 #include <vector>
0017
0018 #if defined(PYPY_VERSION)
0019 # error Embedding the interpreter is not supported with PyPy
0020 #endif
0021
0022 #define PYBIND11_EMBEDDED_MODULE_IMPL(name) \
0023 extern "C" PyObject *pybind11_init_impl_##name(); \
0024 extern "C" PyObject *pybind11_init_impl_##name() { return pybind11_init_wrapper_##name(); }
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #define PYBIND11_EMBEDDED_MODULE(name, variable) \
0042 static ::pybind11::module_::module_def PYBIND11_CONCAT(pybind11_module_def_, name); \
0043 static void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &); \
0044 static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() { \
0045 auto m = ::pybind11::module_::create_extension_module( \
0046 PYBIND11_TOSTRING(name), nullptr, &PYBIND11_CONCAT(pybind11_module_def_, name)); \
0047 try { \
0048 PYBIND11_CONCAT(pybind11_init_, name)(m); \
0049 return m.ptr(); \
0050 } \
0051 PYBIND11_CATCH_INIT_EXCEPTIONS \
0052 } \
0053 PYBIND11_EMBEDDED_MODULE_IMPL(name) \
0054 ::pybind11::detail::embedded_module PYBIND11_CONCAT(pybind11_module_, name)( \
0055 PYBIND11_TOSTRING(name), PYBIND11_CONCAT(pybind11_init_impl_, name)); \
0056 void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ \
0057 & variable)
0058
0059 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0060 PYBIND11_NAMESPACE_BEGIN(detail)
0061
0062
0063 struct embedded_module {
0064 using init_t = PyObject *(*) ();
0065 embedded_module(const char *name, init_t init) {
0066 if (Py_IsInitialized() != 0) {
0067 pybind11_fail("Can't add new modules after the interpreter has been initialized");
0068 }
0069
0070 auto result = PyImport_AppendInittab(name, init);
0071 if (result == -1) {
0072 pybind11_fail("Insufficient memory to add a new module");
0073 }
0074 }
0075 };
0076
0077 struct wide_char_arg_deleter {
0078 void operator()(wchar_t *ptr) const {
0079
0080 PyMem_RawFree(ptr);
0081 }
0082 };
0083
0084 inline wchar_t *widen_chars(const char *safe_arg) {
0085 wchar_t *widened_arg = Py_DecodeLocale(safe_arg, nullptr);
0086 return widened_arg;
0087 }
0088
0089 inline void precheck_interpreter() {
0090 if (Py_IsInitialized() != 0) {
0091 pybind11_fail("The interpreter is already running");
0092 }
0093 }
0094
0095 #if !defined(PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX)
0096 # define PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX (0x03080000)
0097 #endif
0098
0099 #if PY_VERSION_HEX < PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
0100 inline void initialize_interpreter_pre_pyconfig(bool init_signal_handlers,
0101 int argc,
0102 const char *const *argv,
0103 bool add_program_dir_to_path) {
0104 detail::precheck_interpreter();
0105 Py_InitializeEx(init_signal_handlers ? 1 : 0);
0106
0107
0108
0109 bool special_case = (argv == nullptr || argc <= 0);
0110
0111 const char *const empty_argv[]{"\0"};
0112 const char *const *safe_argv = special_case ? empty_argv : argv;
0113 if (special_case) {
0114 argc = 1;
0115 }
0116
0117 auto argv_size = static_cast<size_t>(argc);
0118
0119 std::unique_ptr<wchar_t *[]> widened_argv(new wchar_t *[argv_size]);
0120 std::vector<std::unique_ptr<wchar_t[], detail::wide_char_arg_deleter>> widened_argv_entries;
0121 widened_argv_entries.reserve(argv_size);
0122 for (size_t ii = 0; ii < argv_size; ++ii) {
0123 widened_argv_entries.emplace_back(detail::widen_chars(safe_argv[ii]));
0124 if (!widened_argv_entries.back()) {
0125
0126
0127 return;
0128 }
0129 widened_argv[ii] = widened_argv_entries.back().get();
0130 }
0131
0132 auto *pysys_argv = widened_argv.get();
0133
0134 PySys_SetArgvEx(argc, pysys_argv, static_cast<int>(add_program_dir_to_path));
0135 }
0136 #endif
0137
0138 PYBIND11_NAMESPACE_END(detail)
0139
0140 #if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
0141 inline void initialize_interpreter(PyConfig *config,
0142 int argc = 0,
0143 const char *const *argv = nullptr,
0144 bool add_program_dir_to_path = true) {
0145 detail::precheck_interpreter();
0146 PyStatus status = PyConfig_SetBytesArgv(config, argc, const_cast<char *const *>(argv));
0147 if (PyStatus_Exception(status) != 0) {
0148
0149
0150 PyConfig_Clear(config);
0151 throw std::runtime_error(PyStatus_IsError(status) != 0 ? status.err_msg
0152 : "Failed to prepare CPython");
0153 }
0154 status = Py_InitializeFromConfig(config);
0155 if (PyStatus_Exception(status) != 0) {
0156 PyConfig_Clear(config);
0157 throw std::runtime_error(PyStatus_IsError(status) != 0 ? status.err_msg
0158 : "Failed to init CPython");
0159 }
0160 if (add_program_dir_to_path) {
0161 PyRun_SimpleString("import sys, os.path; "
0162 "sys.path.insert(0, "
0163 "os.path.abspath(os.path.dirname(sys.argv[0])) "
0164 "if sys.argv and os.path.exists(sys.argv[0]) else '')");
0165 }
0166 PyConfig_Clear(config);
0167 }
0168 #endif
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189 inline void initialize_interpreter(bool init_signal_handlers = true,
0190 int argc = 0,
0191 const char *const *argv = nullptr,
0192 bool add_program_dir_to_path = true) {
0193 #if PY_VERSION_HEX < PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
0194 detail::initialize_interpreter_pre_pyconfig(
0195 init_signal_handlers, argc, argv, add_program_dir_to_path);
0196 #else
0197 PyConfig config;
0198 PyConfig_InitPythonConfig(&config);
0199
0200 config.parse_argv = 0;
0201
0202 config.install_signal_handlers = init_signal_handlers ? 1 : 0;
0203 initialize_interpreter(&config, argc, argv, add_program_dir_to_path);
0204 #endif
0205 }
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 inline void finalize_interpreter() {
0243
0244
0245
0246 detail::internals **internals_ptr_ptr = detail::get_internals_pp();
0247
0248 if (object internals_obj
0249 = get_internals_obj_from_state_dict(detail::get_python_state_dict())) {
0250 internals_ptr_ptr = detail::get_internals_pp_from_capsule(internals_obj);
0251 }
0252
0253
0254 detail::get_local_internals().registered_types_cpp.clear();
0255 detail::get_local_internals().registered_exception_translators.clear();
0256
0257 Py_Finalize();
0258
0259 if (internals_ptr_ptr) {
0260 delete *internals_ptr_ptr;
0261 *internals_ptr_ptr = nullptr;
0262 }
0263 }
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280 class scoped_interpreter {
0281 public:
0282 explicit scoped_interpreter(bool init_signal_handlers = true,
0283 int argc = 0,
0284 const char *const *argv = nullptr,
0285 bool add_program_dir_to_path = true) {
0286 initialize_interpreter(init_signal_handlers, argc, argv, add_program_dir_to_path);
0287 }
0288
0289 #if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
0290 explicit scoped_interpreter(PyConfig *config,
0291 int argc = 0,
0292 const char *const *argv = nullptr,
0293 bool add_program_dir_to_path = true) {
0294 initialize_interpreter(config, argc, argv, add_program_dir_to_path);
0295 }
0296 #endif
0297
0298 scoped_interpreter(const scoped_interpreter &) = delete;
0299 scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; }
0300 scoped_interpreter &operator=(const scoped_interpreter &) = delete;
0301 scoped_interpreter &operator=(scoped_interpreter &&) = delete;
0302
0303 ~scoped_interpreter() {
0304 if (is_valid) {
0305 finalize_interpreter();
0306 }
0307 }
0308
0309 private:
0310 bool is_valid = true;
0311 };
0312
0313 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)