diff --git a/docs/upgrade.rst b/docs/upgrade.rst index f13fbcf56d..c173a71bbe 100644 --- a/docs/upgrade.rst +++ b/docs/upgrade.rst @@ -8,6 +8,47 @@ to a new version. But it goes into more detail. This includes things like deprecated APIs and their replacements, build system changes, general code modernization and other useful information. +.. _upgrade-guide-2.7: + +v2.7 +==== + +The previously-deprecated constructor of ``py::module_`` now creates a Python +module object that is *not* used as the top-level module of a C extension. +Previous usage of the deprecated ``PYBIND11_PLUGIN`` macro using the constructor +instead of ``py::module_::create_extension_module`` will result in the following error +on import: ``SystemError: initialization of example did not return an extension module``. + +In this case, change the following doubly-deprecated, memory-leaking pattern: + + .. code-block:: cpp + + PYBIND11_PLUGIN(example) { + auto m = pybind11::module_("example", "pybind11 example plugin"); + /// Set up bindings here + return m.ptr(); + } + +into this: + + .. code-block:: cpp + + static pybind11::module_::module_def example_module_def; + PYBIND11_PLUGIN(example) { + auto m = pybind11::module_::create_extension_module( + "example", "pybind11 example plugin", &example_module_def); + /// Set up bindings here + return m.ptr(); + } + +or, preferably, avoid the deprecated ``PYBIND11_PLUGIN`` completely: + + .. code-block:: cpp + + PYBIND11_MODULE(example, m) { + /// Set up bindings here + } + .. _upgrade-guide-2.6: v2.6 diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index cb05bd14d1..898bd11e12 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -272,8 +272,10 @@ extern "C" { .. code-block:: cpp + static pybind11::module_::module_def example_module_def; PYBIND11_PLUGIN(example) { - pybind11::module_ m("example", "pybind11 example plugin"); + auto m = pybind11::module_::create_extension_module( + "example", "pybind11 example plugin", &example_module_def); /// Set up bindings here return m.ptr(); } diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 96f3ff805b..3f47390af3 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -887,19 +887,38 @@ class cpp_function : public function { } }; -/// Wrapper for Python extension modules +/// Wrapper for Python modules class module_ : public object { public: PYBIND11_OBJECT_DEFAULT(module_, object, PyModule_Check) - /// Create a new top-level Python module with the given name and docstring - PYBIND11_DEPRECATED("Use PYBIND11_MODULE or module_::create_extension_module instead") + /** \rst + Create a new top-level Python module with the given name and docstring. + + Note that this cannot be used as the top-level module for a C extension. + Use `module_::create_extension_module` to create a module object that is + accepted by Python as top-level C extension module, returned from the + extension's ``PyInit_foo`` entry point (``initfoo`` in Python 2). + If you do *not* need a top-level C extension module, this constructor has + the advantage of not needing a ``PyModuleDef`` and thus being easier to use + w.r.t. memory management. + \endrst */ explicit module_(const char *name, const char *doc = nullptr) { -#if PY_MAJOR_VERSION >= 3 - *this = create_extension_module(name, doc, new PyModuleDef()); +#if defined(PYPY_VERSION) && (PYPY_VERSION_NUM < 0x07030400) + m_ptr = PyModule_New(const_cast(name)); #else - *this = create_extension_module(name, doc, nullptr); + m_ptr = PyModule_New(name); #endif + if (!m_ptr) + pybind11_fail("Could not allocate module object!"); + if (doc && options::show_user_defined_docstrings()) { +#if PY_MAJOR_VERSION >= 3 && !defined(PYPY_VERSION) + if (PyModule_SetDocString(m_ptr, doc) != 0) + throw error_already_set(); +#else + setattr(m_ptr, "__doc__", PYBIND11_STR_TYPE(doc)); +#endif + } } /** \rst diff --git a/tests/test_modules.cpp b/tests/test_modules.cpp index 67387e809b..897cf89c46 100644 --- a/tests/test_modules.cpp +++ b/tests/test_modules.cpp @@ -62,8 +62,7 @@ TEST_SUBMODULE(modules, m) { class Dupe3 { }; class DupeException { }; - // Go ahead and leak, until we have a non-leaking py::module_ constructor - auto dm = py::module_::create_extension_module("dummy", nullptr, new py::module_::module_def); + auto dm = py::module_("dummy"); auto failures = py::list(); py::class_(dm, "Dupe1");