Skip to content

Commit f6871c1

Browse files
committed
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.
1 parent d3c999c commit f6871c1

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

include/pybind11/detail/common.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,13 +307,21 @@ extern "C" {
307307
});
308308
}
309309
\endrst */
310+
#if PY_MAJOR_VERSION >= 3
311+
#define PYBIND11_MODULE_DETAIL_CREATE(name) \
312+
static PyModuleDef mdef; \
313+
auto m = pybind11::module(PYBIND11_TOSTRING(name), nullptr, &mdef);
314+
#else
315+
#define PYBIND11_MODULE_DETAIL_CREATE(name) \
316+
auto m = pybind11::module(PYBIND11_TOSTRING(name));
317+
#endif
310318
#define PYBIND11_MODULE(name, variable) \
311319
PYBIND11_MAYBE_UNUSED \
312320
static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \
313321
PYBIND11_PLUGIN_IMPL(name) { \
314322
PYBIND11_CHECK_PYTHON_VERSION \
315323
PYBIND11_ENSURE_INTERNALS_READY \
316-
auto m = pybind11::module(PYBIND11_TOSTRING(name)); \
324+
PYBIND11_MODULE_DETAIL_CREATE(name) \
317325
try { \
318326
PYBIND11_CONCAT(pybind11_init_, name)(m); \
319327
return m.ptr(); \

include/pybind11/pybind11.h

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -857,18 +857,24 @@ class module_ : public object {
857857
PYBIND11_OBJECT_DEFAULT(module_, object, PyModule_Check)
858858

859859
/// Create a new top-level Python module with the given name and docstring
860-
explicit module_(const char *name, const char *doc = nullptr) {
861-
if (!options::show_user_defined_docstrings()) doc = nullptr;
862860
#if PY_MAJOR_VERSION >= 3
863-
auto *def = new PyModuleDef();
864-
std::memset(def, 0, sizeof(PyModuleDef));
865-
def->m_name = name;
866-
def->m_doc = doc;
867-
def->m_size = -1;
868-
Py_INCREF(def);
861+
explicit module(const char *name, const char *doc = nullptr, PyModuleDef *def = nullptr) {
862+
if (!def) def = new PyModuleDef();
863+
def = new (def) PyModuleDef { // Placement new (not an allocation).
864+
/* m_base */ PyModuleDef_HEAD_INIT,
865+
/* m_name */ name,
866+
/* m_doc */ options::show_user_defined_docstrings() ? doc : nullptr,
867+
/* m_size */ -1,
868+
/* m_methods */ nullptr,
869+
/* m_slots */ nullptr,
870+
/* m_traverse */ nullptr,
871+
/* m_clear */ nullptr,
872+
/* m_free */ nullptr
873+
};
869874
m_ptr = PyModule_Create(def);
870875
#else
871-
m_ptr = Py_InitModule3(name, nullptr, doc);
876+
explicit module_(const char *name, const char *doc = nullptr) {
877+
m_ptr = Py_InitModule3(name, nullptr, options::show_user_defined_docstrings() ? doc : nullptr);
872878
#endif
873879
if (m_ptr == nullptr)
874880
pybind11_fail("Internal error in module_::module_()");

0 commit comments

Comments
 (0)