mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 06:35:12 +00:00
static allocation for PyModuleDef, to avoid leak check errors. (#2413)
* Initializing PyModuleDef object with PyModuleDef_HEAD_INIT. Python 3.8 documentation: m_base - Always initialize this member to PyModuleDef_HEAD_INIT. Long-standing (since first github commit in 2015), inconsequential bug. Also removing inconsequential Py_INCREF(def): PyModule_Create() resets the reference count to 1. * git rebase master * moving static PyModuleDef declaration to global scope, as requested by @wjakob * renaming the two new macros, to start with PYBIND11_DETAIL_MODULE
This commit is contained in:
parent
3c7ef56bb6
commit
d159a56338
@ -307,13 +307,26 @@ extern "C" {
|
||||
});
|
||||
}
|
||||
\endrst */
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#define PYBIND11_DETAIL_MODULE_STATIC_DEF(name) \
|
||||
static PyModuleDef PYBIND11_CONCAT(pybind11_module_def_, name);
|
||||
#define PYBIND11_DETAIL_MODULE_CREATE(name) \
|
||||
auto m = pybind11::module( \
|
||||
PYBIND11_TOSTRING(name), nullptr, \
|
||||
&PYBIND11_CONCAT(pybind11_module_def_, name));
|
||||
#else
|
||||
#define PYBIND11_DETAIL_MODULE_STATIC_DEF(name)
|
||||
#define PYBIND11_DETAIL_MODULE_CREATE(name) \
|
||||
auto m = pybind11::module(PYBIND11_TOSTRING(name));
|
||||
#endif
|
||||
#define PYBIND11_MODULE(name, variable) \
|
||||
PYBIND11_DETAIL_MODULE_STATIC_DEF(name) \
|
||||
PYBIND11_MAYBE_UNUSED \
|
||||
static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \
|
||||
PYBIND11_PLUGIN_IMPL(name) { \
|
||||
PYBIND11_CHECK_PYTHON_VERSION \
|
||||
PYBIND11_ENSURE_INTERNALS_READY \
|
||||
auto m = pybind11::module(PYBIND11_TOSTRING(name)); \
|
||||
PYBIND11_DETAIL_MODULE_CREATE(name) \
|
||||
try { \
|
||||
PYBIND11_CONCAT(pybind11_init_, name)(m); \
|
||||
return m.ptr(); \
|
||||
|
@ -862,18 +862,24 @@ public:
|
||||
PYBIND11_OBJECT_DEFAULT(module_, object, PyModule_Check)
|
||||
|
||||
/// Create a new top-level Python module with the given name and docstring
|
||||
explicit module_(const char *name, const char *doc = nullptr) {
|
||||
if (!options::show_user_defined_docstrings()) doc = nullptr;
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
auto *def = new PyModuleDef();
|
||||
std::memset(def, 0, sizeof(PyModuleDef));
|
||||
def->m_name = name;
|
||||
def->m_doc = doc;
|
||||
def->m_size = -1;
|
||||
Py_INCREF(def);
|
||||
explicit module_(const char *name, const char *doc = nullptr, PyModuleDef *def = nullptr) {
|
||||
if (!def) def = new PyModuleDef();
|
||||
def = new (def) PyModuleDef { // Placement new (not an allocation).
|
||||
/* m_base */ PyModuleDef_HEAD_INIT,
|
||||
/* m_name */ name,
|
||||
/* m_doc */ options::show_user_defined_docstrings() ? doc : nullptr,
|
||||
/* m_size */ -1,
|
||||
/* m_methods */ nullptr,
|
||||
/* m_slots */ nullptr,
|
||||
/* m_traverse */ nullptr,
|
||||
/* m_clear */ nullptr,
|
||||
/* m_free */ nullptr
|
||||
};
|
||||
m_ptr = PyModule_Create(def);
|
||||
#else
|
||||
m_ptr = Py_InitModule3(name, nullptr, doc);
|
||||
explicit module_(const char *name, const char *doc = nullptr) {
|
||||
m_ptr = Py_InitModule3(name, nullptr, options::show_user_defined_docstrings() ? doc : nullptr);
|
||||
#endif
|
||||
if (m_ptr == nullptr)
|
||||
pybind11_fail("Internal error in module_::module_()");
|
||||
|
Loading…
Reference in New Issue
Block a user