Skip to content

Commit

Permalink
Deprecated public constructors of module
Browse files Browse the repository at this point in the history
  • Loading branch information
YannickJadoul committed Oct 5, 2020
1 parent 1411207 commit 19c3079
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 62 deletions.
9 changes: 5 additions & 4 deletions include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,18 +311,19 @@ extern "C" {
#define PYBIND11_DETAIL_MODULE_STATIC_DEF(name) \
static PyModuleDef PYBIND11_CONCAT(pybind11_module_def_, name);
#define PYBIND11_DETAIL_MODULE_CREATE(name) \
auto m = pybind11::detail::create_top_level_module( \
auto m = ::pybind11::detail::create_top_level_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));
auto m = ::pybind11::detail::create_top_level_module( \
PYBIND11_TOSTRING(name), nullptr)
#endif
#define PYBIND11_MODULE(name, variable) \
PYBIND11_DETAIL_MODULE_STATIC_DEF(name) \
PYBIND11_MAYBE_UNUSED \
static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module_ &); \
static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module_ &); \
PYBIND11_PLUGIN_IMPL(name) { \
PYBIND11_CHECK_PYTHON_VERSION \
PYBIND11_ENSURE_INTERNALS_READY \
Expand All @@ -332,7 +333,7 @@ extern "C" {
return m.ptr(); \
} PYBIND11_CATCH_INIT_EXCEPTIONS \
} \
void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module_ &variable)
void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &variable)


PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
Expand Down
41 changes: 21 additions & 20 deletions include/pybind11/embed.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,27 @@
});
}
\endrst */
#define PYBIND11_EMBEDDED_MODULE(name, variable) \
static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module_ &); \
static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() { \
auto m = pybind11::module_(PYBIND11_TOSTRING(name)); \
try { \
PYBIND11_CONCAT(pybind11_init_, name)(m); \
return m.ptr(); \
} catch (pybind11::error_already_set &e) { \
PyErr_SetString(PyExc_ImportError, e.what()); \
return nullptr; \
} catch (const std::exception &e) { \
PyErr_SetString(PyExc_ImportError, e.what()); \
return nullptr; \
} \
} \
PYBIND11_EMBEDDED_MODULE_IMPL(name) \
pybind11::detail::embedded_module PYBIND11_CONCAT(pybind11_module_, name) \
(PYBIND11_TOSTRING(name), \
PYBIND11_CONCAT(pybind11_init_impl_, name)); \
void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module_ &variable)
#define PYBIND11_EMBEDDED_MODULE(name, variable) \
PYBIND11_DETAIL_MODULE_STATIC_DEF(name) \
static void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &); \
static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() { \
PYBIND11_DETAIL_MODULE_CREATE(name) \
try { \
PYBIND11_CONCAT(pybind11_init_, name)(m); \
return m.ptr(); \
} catch (::pybind11::error_already_set &e) { \
PyErr_SetString(PyExc_ImportError, e.what()); \
return nullptr; \
} catch (const std::exception &e) { \
PyErr_SetString(PyExc_ImportError, e.what()); \
return nullptr; \
} \
} \
PYBIND11_EMBEDDED_MODULE_IMPL(name) \
::pybind11::detail::embedded_module PYBIND11_CONCAT(pybind11_module_, name) \
(PYBIND11_TOSTRING(name), \
PYBIND11_CONCAT(pybind11_init_impl_, name)); \
void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &variable)


PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
Expand Down
71 changes: 34 additions & 37 deletions include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -856,32 +856,30 @@ class cpp_function : public function {
}
};


#if PY_MAJOR_VERSION >= 3
class module_;

PYBIND11_NAMESPACE_BEGIN(detail)
#if PY_MAJOR_VERSION >= 3
inline module_ create_top_level_module(const char *name, const char *doc, PyModuleDef *def);
PYBIND11_NAMESPACE_END(detail)
#else
inline module_ create_top_level_module(const char *name, const char *doc);
#endif
PYBIND11_NAMESPACE_END(detail)

/// Wrapper for Python extension 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
explicit module_(const char *name, const char *doc = nullptr)
PYBIND11_DEPRECATED("Use PYBIND11_MODULE, module_::def_submodule, or module_::import instead")
explicit module_(const char *name, const char *doc = nullptr) {
#if PY_MAJOR_VERSION >= 3
: module_(name, doc, new PyModuleDef()) {}
*this = detail::create_top_level_module(name, doc, new PyModuleDef());
#else
{
m_ptr = Py_InitModule3(name, nullptr, options::show_user_defined_docstrings() ? doc : nullptr);
if (m_ptr == nullptr)
pybind11_fail("Internal error in module_::module_()");
inc_ref();
}
*this = detail::create_top_level_module(name, doc);
#endif
}

/** \rst
Create Python binding for a new function within the module scope. ``Func``
Expand Down Expand Up @@ -946,43 +944,42 @@ class module_ : public object {

PyModule_AddObject(ptr(), name, obj.inc_ref().ptr() /* steals a reference */);
}

private:
#if PY_MAJOR_VERSION >= 3
friend module_ detail::create_top_level_module(const char *, const char *, PyModuleDef *);

explicit module_(const char *name, const char *doc, PyModuleDef *def) {
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);
if (m_ptr == nullptr)
pybind11_fail("Internal error in module_::module_()");
inc_ref();
}
#endif
};

// When inside a namespace (or anywhere as long as it's not the first item on a line),
// C++20 allows "module" to be used. This is provided for backward compatibility, and for
// simplicity, if someone wants to use py::module for example, that is perfectly safe.
using module = module_;

#if PY_MAJOR_VERSION >= 3
PYBIND11_NAMESPACE_BEGIN(detail)
#if PY_MAJOR_VERSION >= 3
inline module_ create_top_level_module(const char *name, const char *doc, PyModuleDef *def) {
return module_(name, doc, def);
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
};
auto m = PyModule_Create(def);
if (m == nullptr)
pybind11_fail("Internal error in detail::create_top_level_module()");
// TODO: Should be reinterpret_steal, but Python also steals it again when returned from PyInit_...
return reinterpret_borrow<module_>(m);
}
#else
inline module_ create_top_level_module(const char *name, const char *doc) {
auto m = Py_InitModule3(name, nullptr, options::show_user_defined_docstrings() ? doc : nullptr);
if (m == nullptr)
pybind11_fail("Internal error in detail::create_top_level_module()");
return reinterpret_borrow<module_>(m);
}
PYBIND11_NAMESPACE_END(detail)
#endif
PYBIND11_NAMESPACE_END(detail)

/// \ingroup python_builtins
/// Return a dictionary representing the global variables in the current execution frame,
Expand Down
6 changes: 5 additions & 1 deletion tests/test_modules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ TEST_SUBMODULE(modules, m) {
class Dupe3 { };
class DupeException { };

auto dm = py::module_("dummy");
#if PY_MAJOR_VERSION >= 3
auto dm = py::detail::create_top_level_module("dummy", nullptr, new PyModuleDef);
#else
auto dm = py::detail::create_top_level_module("dummy", nullptr);
#endif
auto failures = py::list();

py::class_<Dupe1>(dm, "Dupe1");
Expand Down

0 comments on commit 19c3079

Please sign in to comment.