embed.h
Go to the documentation of this file.
1 /*
2  pybind11/embed.h: Support for embedding the interpreter
3 
4  Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>
5 
6  All rights reserved. Use of this source code is governed by a
7  BSD-style license that can be found in the LICENSE file.
8 */
9 
10 #pragma once
11 
12 #include "pybind11.h"
13 #include "eval.h"
14 
15 #if defined(PYPY_VERSION)
16 # error Embedding the interpreter is not supported with PyPy
17 #endif
18 
19 #if PY_MAJOR_VERSION >= 3
20 # define PYBIND11_EMBEDDED_MODULE_IMPL(name) \
21  extern "C" PyObject *pybind11_init_impl_##name(); \
22  extern "C" PyObject *pybind11_init_impl_##name() { \
23  return pybind11_init_wrapper_##name(); \
24  }
25 #else
26 # define PYBIND11_EMBEDDED_MODULE_IMPL(name) \
27  extern "C" void pybind11_init_impl_##name(); \
28  extern "C" void pybind11_init_impl_##name() { \
29  pybind11_init_wrapper_##name(); \
30  }
31 #endif
32 
48 #define PYBIND11_EMBEDDED_MODULE(name, variable) \
49  static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \
50  static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() { \
51  auto m = pybind11::module(PYBIND11_TOSTRING(name)); \
52  try { \
53  PYBIND11_CONCAT(pybind11_init_, name)(m); \
54  return m.ptr(); \
55  } catch (pybind11::error_already_set &e) { \
56  PyErr_SetString(PyExc_ImportError, e.what()); \
57  return nullptr; \
58  } catch (const std::exception &e) { \
59  PyErr_SetString(PyExc_ImportError, e.what()); \
60  return nullptr; \
61  } \
62  } \
63  PYBIND11_EMBEDDED_MODULE_IMPL(name) \
64  pybind11::detail::embedded_module PYBIND11_CONCAT(pybind11_module_, name) \
65  (PYBIND11_TOSTRING(name), \
66  PYBIND11_CONCAT(pybind11_init_impl_, name)); \
67  void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &variable)
68 
69 
72 
75 #if PY_MAJOR_VERSION >= 3
76  using init_t = PyObject *(*)();
77 #else
78  using init_t = void (*)();
79 #endif
80  embedded_module(const char *name, init_t init) {
81  if (Py_IsInitialized())
82  pybind11_fail("Can't add new modules after the interpreter has been initialized");
83 
84  auto result = PyImport_AppendInittab(name, init);
85  if (result == -1)
86  pybind11_fail("Insufficient memory to add a new module");
87  }
88 };
89 
91 
92 
105 inline void initialize_interpreter(bool init_signal_handlers = true) {
106  if (Py_IsInitialized())
107  pybind11_fail("The interpreter is already running");
108 
109  Py_InitializeEx(init_signal_handlers ? 1 : 0);
110 
111  // Make .py files in the working directory available by default
112  module::import("sys").attr("path").cast<list>().append(".");
113 }
114 
150 inline void finalize_interpreter() {
151  handle builtins(PyEval_GetBuiltins());
152  const char *id = PYBIND11_INTERNALS_ID;
153 
154  // Get the internals pointer (without creating it if it doesn't exist). It's possible for the
155  // internals to be created during Py_Finalize() (e.g. if a py::capsule calls `get_internals()`
156  // during destruction), so we get the pointer-pointer here and check it after Py_Finalize().
157  detail::internals **internals_ptr_ptr = detail::get_internals_pp();
158  // It could also be stashed in builtins, so look there too:
159  if (builtins.contains(id) && isinstance<capsule>(builtins[id]))
160  internals_ptr_ptr = capsule(builtins[id]);
161 
162  Py_Finalize();
163 
164  if (internals_ptr_ptr) {
165  delete *internals_ptr_ptr;
166  *internals_ptr_ptr = nullptr;
167  }
168 }
169 
184 public:
185  scoped_interpreter(bool init_signal_handlers = true) {
186  initialize_interpreter(init_signal_handlers);
187  }
188 
189  scoped_interpreter(const scoped_interpreter &) = delete;
190  scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; }
193 
195  if (is_valid)
197  }
198 
199 private:
200  bool is_valid = true;
201 };
202 
void initialize_interpreter(bool init_signal_handlers=true)
Definition: embed.h:105
T cast() const &
Definition: cast.h:1789
embedded_module(const char *name, init_t init)
Definition: embed.h:80
Q id(Eigen::AngleAxisd(0, Q_z_axis))
scoped_interpreter(bool init_signal_handlers=true)
Definition: embed.h:185
void finalize_interpreter()
Definition: embed.h:150
Tuple< Args..., T > append(Tuple< Args... > t, T a)
the deduction function for append_base that automatically generate the IndexRange ...
scoped_interpreter(scoped_interpreter &&other) noexcept
Definition: embed.h:190
PyExc_RuntimeError[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason)
Used internally.
Values result
scoped_interpreter & operator=(const scoped_interpreter &)=delete
Python 2.7/3.x compatible version of PyImport_AppendInittab and error checks.
Definition: embed.h:74
Definition: pytypes.h:1301
#define PYBIND11_INTERNALS_ID
Definition: internals.h:202
static module_ import(const char *name)
Import and return a module or throws error_already_set.
Definition: pybind11.h:914
Annotation for function names.
Definition: attr.h:36
internals **& get_internals_pp()
Definition: internals.h:210
#define PYBIND11_NAMESPACE_END(name)
#define PYBIND11_NAMESPACE_BEGIN(name)


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:42:01