Replace PYBIND11_PLUGIN with PYBIND11_MODULE

This commit also adds `doc()` to `object_api` as a shortcut for the
`attr("__doc__")` accessor.

The module macro changes from:
```c++
PYBIND11_PLUGIN(example) {
    pybind11::module m("example", "pybind11 example plugin");
    m.def("add", [](int a, int b) { return a + b; });
    return m.ptr();
}
```

to:

```c++
PYBIND11_MODULE(example, m) {
    m.doc() = "pybind11 example plugin";
    m.def("add", [](int a, int b) { return a + b; });
}
```

Using the old macro results in a deprecation warning. The warning
actually points to the `pybind11_init` function (since attributes
don't bind to macros), but the message should be quite clear:
"PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE".
This commit is contained in:
Dean Moldovan 2017-04-24 01:51:44 +02:00
parent b700c5d672
commit 443ab5946b
16 changed files with 93 additions and 95 deletions

View File

@ -56,14 +56,10 @@ trivial to generate binding code for all of these functions.
#include <pybind11/functional.h> #include <pybind11/functional.h>
PYBIND11_PLUGIN(example) { PYBIND11_MODULE(example, m) {
py::module m("example", "pybind11 example plugin");
m.def("func_arg", &func_arg); m.def("func_arg", &func_arg);
m.def("func_ret", &func_ret); m.def("func_ret", &func_ret);
m.def("func_cpp", &func_cpp); m.def("func_cpp", &func_cpp);
return m.ptr();
} }
The following interactive session shows how to call them from Python. The following interactive session shows how to call them from Python.

View File

@ -45,9 +45,7 @@ Normally, the binding code for these classes would look as follows:
.. code-block:: cpp .. code-block:: cpp
PYBIND11_PLUGIN(example) { PYBIND11_MODULE(example, m) {
py::module m("example", "pybind11 example plugin");
py::class_<Animal> animal(m, "Animal"); py::class_<Animal> animal(m, "Animal");
animal animal
.def("go", &Animal::go); .def("go", &Animal::go);
@ -56,8 +54,6 @@ Normally, the binding code for these classes would look as follows:
.def(py::init<>()); .def(py::init<>());
m.def("call_go", &call_go); m.def("call_go", &call_go);
return m.ptr();
} }
However, these bindings are impossible to extend: ``Animal`` is not However, these bindings are impossible to extend: ``Animal`` is not
@ -97,11 +93,9 @@ function have different names, e.g. ``operator()`` vs ``__call__``.
The binding code also needs a few minor adaptations (highlighted): The binding code also needs a few minor adaptations (highlighted):
.. code-block:: cpp .. code-block:: cpp
:emphasize-lines: 4,6,7 :emphasize-lines: 2,4,5
PYBIND11_PLUGIN(example) {
py::module m("example", "pybind11 example plugin");
PYBIND11_MODULE(example, m) {
py::class_<Animal, PyAnimal /* <--- trampoline*/> animal(m, "Animal"); py::class_<Animal, PyAnimal /* <--- trampoline*/> animal(m, "Animal");
animal animal
.def(py::init<>()) .def(py::init<>())
@ -111,8 +105,6 @@ The binding code also needs a few minor adaptations (highlighted):
.def(py::init<>()); .def(py::init<>());
m.def("call_go", &call_go); m.def("call_go", &call_go);
return m.ptr();
} }
Importantly, pybind11 is made aware of the trampoline helper class by Importantly, pybind11 is made aware of the trampoline helper class by
@ -491,9 +483,7 @@ to Python.
#include <pybind11/operators.h> #include <pybind11/operators.h>
PYBIND11_PLUGIN(example) { PYBIND11_MODULE(example, m) {
py::module m("example", "pybind11 example plugin");
py::class_<Vector2>(m, "Vector2") py::class_<Vector2>(m, "Vector2")
.def(py::init<float, float>()) .def(py::init<float, float>())
.def(py::self + py::self) .def(py::self + py::self)
@ -502,8 +492,6 @@ to Python.
.def(float() * py::self) .def(float() * py::self)
.def(py::self * float()) .def(py::self * float())
.def("__repr__", &Vector2::toString); .def("__repr__", &Vector2::toString);
return m.ptr();
} }
Note that a line like Note that a line like

View File

@ -28,7 +28,7 @@ multiple Python threads. Taking :ref:`overriding_virtuals` as an example, this
could be realized as follows (important changes highlighted): could be realized as follows (important changes highlighted):
.. code-block:: cpp .. code-block:: cpp
:emphasize-lines: 8,9,33,34 :emphasize-lines: 8,9,31,32
class PyAnimal : public Animal { class PyAnimal : public Animal {
public: public:
@ -49,9 +49,7 @@ could be realized as follows (important changes highlighted):
} }
}; };
PYBIND11_PLUGIN(example) { PYBIND11_MODULE(example, m) {
py::module m("example", "pybind11 example plugin");
py::class_<Animal, PyAnimal> animal(m, "Animal"); py::class_<Animal, PyAnimal> animal(m, "Animal");
animal animal
.def(py::init<>()) .def(py::init<>())
@ -65,8 +63,6 @@ could be realized as follows (important changes highlighted):
py::gil_scoped_release release; py::gil_scoped_release release;
return call_go(animal); return call_go(animal);
}); });
return m.ptr();
} }
The ``call_go`` wrapper can also be simplified using the `call_guard` policy The ``call_go`` wrapper can also be simplified using the `call_guard` policy
@ -233,15 +229,11 @@ The class ``options`` allows you to selectively suppress auto-generated signatur
.. code-block:: cpp .. code-block:: cpp
PYBIND11_PLUGIN(example) { PYBIND11_MODULE(example, m) {
py::module m("example", "pybind11 example plugin");
py::options options; py::options options;
options.disable_function_signatures(); options.disable_function_signatures();
m.def("add", [](int a, int b) { return a + b; }, "A function which adds two numbers"); m.def("add", [](int a, int b) { return a + b; }, "A function which adds two numbers");
return m.ptr();
} }
Note that changes to the settings affect only function bindings created during the Note that changes to the settings affect only function bindings created during the

View File

@ -190,7 +190,7 @@ expects the type followed by field names:
}; };
// ... // ...
PYBIND11_PLUGIN(test) { PYBIND11_MODULE(test, m) {
// ... // ...
PYBIND11_NUMPY_DTYPE(A, x, y); PYBIND11_NUMPY_DTYPE(A, x, y);
@ -284,10 +284,8 @@ simply using ``vectorize``).
return result; return result;
} }
PYBIND11_PLUGIN(test) { PYBIND11_MODULE(test, m) {
py::module m("test");
m.def("add_arrays", &add_arrays, "Add two NumPy arrays"); m.def("add_arrays", &add_arrays, "Add two NumPy arrays");
return m.ptr();
} }
.. seealso:: .. seealso::

View File

@ -63,16 +63,12 @@ code?
std::shared_ptr<Child> child; std::shared_ptr<Child> child;
}; };
PYBIND11_PLUGIN(example) { PYBIND11_MODULE(example, m) {
py::module m("example");
py::class_<Child, std::shared_ptr<Child>>(m, "Child"); py::class_<Child, std::shared_ptr<Child>>(m, "Child");
py::class_<Parent, std::shared_ptr<Parent>>(m, "Parent") py::class_<Parent, std::shared_ptr<Parent>>(m, "Parent")
.def(py::init<>()) .def(py::init<>())
.def("get_child", &Parent::get_child); .def("get_child", &Parent::get_child);
return m.ptr();
} }
The following Python code will cause undefined behavior (and likely a The following Python code will cause undefined behavior (and likely a

View File

@ -96,25 +96,21 @@ a file named :file:`example.cpp` with the following contents:
return i + j; return i + j;
} }
namespace py = pybind11; PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin"; // optional module docstring
PYBIND11_PLUGIN(example) {
py::module m("example", "pybind11 example plugin");
m.def("add", &add, "A function which adds two numbers"); m.def("add", &add, "A function which adds two numbers");
return m.ptr();
} }
.. [#f1] In practice, implementation and binding code will generally be located .. [#f1] In practice, implementation and binding code will generally be located
in separate files. in separate files.
The :func:`PYBIND11_PLUGIN` macro creates a function that will be called when an The :func:`PYBIND11_MODULE` macro creates a function that will be called when an
``import`` statement is issued from within Python. The next line creates a ``import`` statement is issued from within Python. The module name (``example``)
module named ``example`` (with the supplied docstring). The method is given as the fist macro argument (it should not be in quotes). The second
:func:`module::def` generates binding code that exposes the argument (``m``) defines a variable of type :class:`py::module <module>` which
``add()`` function to Python. The last line returns the internal Python object is the main interface for creating bindings. The method :func:`module::def`
associated with ``m`` to the Python interpreter. generates binding code that exposes the ``add()`` function to Python.
.. note:: .. note::
@ -261,12 +257,10 @@ converted using the function ``py::cast``.
.. code-block:: cpp .. code-block:: cpp
PYBIND11_PLUGIN(example) { PYBIND11_MODULE(example, m) {
py::module m("example", "pybind11 example plugin");
m.attr("the_answer") = 42; m.attr("the_answer") = 42;
py::object world = py::cast("World"); py::object world = py::cast("World");
m.attr("what") = world; m.attr("what") = world;
return m.ptr();
} }
These are then accessible from Python: These are then accessible from Python:

View File

@ -33,10 +33,8 @@ def generate_dummy_code_pybind11(nclasses=10):
result = "#include <pybind11/pybind11.h>\n\n" result = "#include <pybind11/pybind11.h>\n\n"
result += "namespace py = pybind11;\n\n" result += "namespace py = pybind11;\n\n"
result += decl + '\n' result += decl + '\n'
result += "PYBIND11_PLUGIN(example) {\n" result += "PYBIND11_MODULE(example, m) {\n"
result += " py::module m(\"example\");"
result += bindings result += bindings
result += " return m.ptr();"
result += "}" result += "}"
return result return result

View File

@ -31,8 +31,7 @@ Here is an example of the binding code for one class:
}; };
... ...
PYBIND11_PLUGIN(example) { PYBIND11_MODULE(example, m) {
py::module m("example");
... ...
py::class_<cl034>(m, "cl034") py::class_<cl034>(m, "cl034")
.def("fn_000", &cl034::fn_000) .def("fn_000", &cl034::fn_000)
@ -40,7 +39,6 @@ Here is an example of the binding code for one class:
.def("fn_002", &cl034::fn_002) .def("fn_002", &cl034::fn_002)
.def("fn_003", &cl034::fn_003) .def("fn_003", &cl034::fn_003)
... ...
return m.ptr();
} }
The Boost.Python version looks almost identical except that a return value The Boost.Python version looks almost identical except that a return value

View File

@ -27,15 +27,11 @@ The binding code for ``Pet`` looks as follows:
namespace py = pybind11; namespace py = pybind11;
PYBIND11_PLUGIN(example) { PYBIND11_MODULE(example, m) {
py::module m("example", "pybind11 example plugin");
py::class_<Pet>(m, "Pet") py::class_<Pet>(m, "Pet")
.def(py::init<const std::string &>()) .def(py::init<const std::string &>())
.def("setName", &Pet::setName) .def("setName", &Pet::setName)
.def("getName", &Pet::getName); .def("getName", &Pet::getName);
return m.ptr();
} }
:class:`class_` creates bindings for a C++ *class* or *struct*-style data :class:`class_` creates bindings for a C++ *class* or *struct*-style data

View File

@ -4,30 +4,24 @@ Frequently asked questions
"ImportError: dynamic module does not define init function" "ImportError: dynamic module does not define init function"
=========================================================== ===========================================================
1. Make sure that the name specified in ``pybind::module`` and You are likely using an incompatible version of Python (for instance, the
``PYBIND11_PLUGIN`` is consistent and identical to the filename of the extension library was compiled against Python 2, while the interpreter is
extension library. The latter should not contain any extra prefixes (e.g. running on top of some version of Python 3, or vice versa).
``test.so`` instead of ``libtest.so``).
2. If the above did not fix your issue, then you are likely using an
incompatible version of Python (for instance, the extension library was
compiled against Python 2, while the interpreter is running on top of some
version of Python 3, or vice versa)
"Symbol not found: ``__Py_ZeroStruct`` / ``_PyInstanceMethod_Type``" "Symbol not found: ``__Py_ZeroStruct`` / ``_PyInstanceMethod_Type``"
======================================================================== ========================================================================
See item 2 of the first answer. See the first answer.
"SystemError: dynamic module not initialized properly" "SystemError: dynamic module not initialized properly"
====================================================== ======================================================
See item 2 of the first answer. See the first answer.
The Python interpreter immediately crashes when importing my module The Python interpreter immediately crashes when importing my module
=================================================================== ===================================================================
See item 2 of the first answer. See the first answer.
CMake doesn't detect the right Python version CMake doesn't detect the right Python version
============================================= =============================================
@ -104,14 +98,10 @@ following example:
void init_ex2(py::module &); void init_ex2(py::module &);
/* ... */ /* ... */
PYBIND11_PLUGIN(example) { PYBIND11_MODULE(example, m) {
py::module m("example", "pybind example plugin");
init_ex1(m); init_ex1(m);
init_ex2(m); init_ex2(m);
/* ... */ /* ... */
return m.ptr();
} }
:file:`ex1.cpp`: :file:`ex1.cpp`:

View File

@ -12,7 +12,7 @@ Reference
Macros Macros
====== ======
.. doxygendefine:: PYBIND11_PLUGIN .. doxygendefine:: PYBIND11_MODULE
.. _core_types: .. _core_types:

View File

@ -194,6 +194,8 @@ extern "C" {
PYBIND11_TOSTRING(PYBIND11_VERSION_MAJOR) "_" PYBIND11_TOSTRING(PYBIND11_VERSION_MINOR) "__" PYBIND11_TOSTRING(PYBIND11_VERSION_MAJOR) "_" PYBIND11_TOSTRING(PYBIND11_VERSION_MINOR) "__"
/** \rst /** \rst
***Deprecated in favor of PYBIND11_MODULE***
This macro creates the entry point that will be invoked when the Python interpreter This macro creates the entry point that will be invoked when the Python interpreter
imports a plugin library. Please create a `module` in the function body and return imports a plugin library. Please create a `module` in the function body and return
the pointer to its underlying Python object at the end. the pointer to its underlying Python object at the end.
@ -207,6 +209,7 @@ extern "C" {
} }
\endrst */ \endrst */
#define PYBIND11_PLUGIN(name) \ #define PYBIND11_PLUGIN(name) \
PYBIND11_DEPRECATED("PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE") \
static PyObject *pybind11_init(); \ static PyObject *pybind11_init(); \
PYBIND11_PLUGIN_IMPL(name) { \ PYBIND11_PLUGIN_IMPL(name) { \
int major, minor; \ int major, minor; \
@ -234,6 +237,54 @@ extern "C" {
} \ } \
PyObject *pybind11_init() PyObject *pybind11_init()
/** \rst
This macro creates the entry point that will be invoked when the Python interpreter
imports an extension module. The module name is given as the fist argument and it
should not be in quotes. The second macro argument defines a variable of type
`py::module` which can be used to initialize the module.
.. code-block:: cpp
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example module";
// Add bindings here
m.def("foo", []() {
return "Hello, World!";
});
}
\endrst */
#define PYBIND11_MODULE(name, variable) \
static void pybind11_init_##name(pybind11::module &); \
PYBIND11_PLUGIN_IMPL(name) { \
int major, minor; \
if (sscanf(Py_GetVersion(), "%i.%i", &major, &minor) != 2) { \
PyErr_SetString(PyExc_ImportError, "Can't parse Python version."); \
return nullptr; \
} else if (major != PY_MAJOR_VERSION || minor != PY_MINOR_VERSION) { \
PyErr_Format(PyExc_ImportError, \
"Python version mismatch: module was compiled for " \
"version %i.%i, while the interpreter is running " \
"version %i.%i.", PY_MAJOR_VERSION, PY_MINOR_VERSION, \
major, minor); \
return nullptr; \
} \
auto m = pybind11::module(#name); \
try { \
pybind11_init_##name(m); \
return m.ptr(); \
} catch (pybind11::error_already_set &e) { \
e.clear(); \
PyErr_SetString(PyExc_ImportError, e.what()); \
return nullptr; \
} catch (const std::exception &e) { \
PyErr_SetString(PyExc_ImportError, e.what()); \
return nullptr; \
} \
} \
void pybind11_init_##name(pybind11::module &variable)
NAMESPACE_BEGIN(pybind11) NAMESPACE_BEGIN(pybind11)
using ssize_t = Py_ssize_t; using ssize_t = Py_ssize_t;

View File

@ -117,6 +117,9 @@ public:
PYBIND11_DEPRECATED("Use py::str(obj) instead") PYBIND11_DEPRECATED("Use py::str(obj) instead")
pybind11::str str() const; pybind11::str str() const;
/// Get or set the object's docstring, i.e. ``obj.__doc__``.
str_attr_accessor doc() const;
/// Return the object's current reference count /// Return the object's current reference count
int ref_count() const { return static_cast<int>(Py_REFCNT(derived().ptr())); } int ref_count() const { return static_cast<int>(Py_REFCNT(derived().ptr())); }
/// Return a handle to the Python type object underlying the instance /// Return a handle to the Python type object underlying the instance
@ -1248,6 +1251,9 @@ template <typename D> template <typename T> bool object_api<D>::contains(T &&ite
template <typename D> template <typename D>
pybind11::str object_api<D>::str() const { return pybind11::str(derived()); } pybind11::str object_api<D>::str() const { return pybind11::str(derived()); }
template <typename D>
str_attr_accessor object_api<D>::doc() const { return attr("__doc__"); }
template <typename D> template <typename D>
handle object_api<D>::get_type() const { return (PyObject *) Py_TYPE(derived().ptr()); } handle object_api<D>::get_type() const { return (PyObject *) Py_TYPE(derived().ptr()); }

View File

@ -52,8 +52,8 @@ void bind_ConstructorStats(py::module &m) {
; ;
} }
PYBIND11_PLUGIN(pybind11_tests) { PYBIND11_MODULE(pybind11_tests, m) {
py::module m("pybind11_tests", "pybind testing plugin"); m.doc() = "pybind11 test module";
bind_ConstructorStats(m); bind_ConstructorStats(m);
@ -61,6 +61,4 @@ PYBIND11_PLUGIN(pybind11_tests) {
initializer(m); initializer(m);
if (!py::hasattr(m, "have_eigen")) m.attr("have_eigen") = false; if (!py::hasattr(m, "have_eigen")) m.attr("have_eigen") = false;
return m.ptr();
} }

View File

@ -1,10 +1,6 @@
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
namespace py = pybind11; namespace py = pybind11;
PYBIND11_PLUGIN(test_cmake_build) { PYBIND11_MODULE(test_cmake_build, m) {
py::module m("test_cmake_build");
m.def("add", [](int i, int j) { return i + j; }); m.def("add", [](int i, int j) { return i + j; });
return m.ptr();
} }

View File

@ -59,4 +59,5 @@ def test_pydoc():
import pybind11_tests import pybind11_tests
import pydoc import pydoc
assert pybind11_tests.__doc__ == "pybind11 test module"
assert pydoc.text.docmodule(pybind11_tests) assert pydoc.text.docmodule(pybind11_tests)