diff --git a/docs/advanced/cast/functional.rst b/docs/advanced/cast/functional.rst index 5d0a01d1..d9b46057 100644 --- a/docs/advanced/cast/functional.rst +++ b/docs/advanced/cast/functional.rst @@ -56,14 +56,10 @@ trivial to generate binding code for all of these functions. #include - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - + PYBIND11_MODULE(example, m) { m.def("func_arg", &func_arg); m.def("func_ret", &func_ret); m.def("func_cpp", &func_cpp); - - return m.ptr(); } The following interactive session shows how to call them from Python. diff --git a/docs/advanced/classes.rst b/docs/advanced/classes.rst index 8896441b..b6e0a2f4 100644 --- a/docs/advanced/classes.rst +++ b/docs/advanced/classes.rst @@ -45,9 +45,7 @@ Normally, the binding code for these classes would look as follows: .. code-block:: cpp - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - + PYBIND11_MODULE(example, m) { py::class_ animal(m, "Animal"); animal .def("go", &Animal::go); @@ -56,8 +54,6 @@ Normally, the binding code for these classes would look as follows: .def(py::init<>()); m.def("call_go", &call_go); - - return m.ptr(); } 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): .. code-block:: cpp - :emphasize-lines: 4,6,7 - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); + :emphasize-lines: 2,4,5 + PYBIND11_MODULE(example, m) { py::class_ animal(m, "Animal"); animal .def(py::init<>()) @@ -111,8 +105,6 @@ The binding code also needs a few minor adaptations (highlighted): .def(py::init<>()); m.def("call_go", &call_go); - - return m.ptr(); } Importantly, pybind11 is made aware of the trampoline helper class by @@ -491,9 +483,7 @@ to Python. #include - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - + PYBIND11_MODULE(example, m) { py::class_(m, "Vector2") .def(py::init()) .def(py::self + py::self) @@ -502,8 +492,6 @@ to Python. .def(float() * py::self) .def(py::self * float()) .def("__repr__", &Vector2::toString); - - return m.ptr(); } Note that a line like diff --git a/docs/advanced/misc.rst b/docs/advanced/misc.rst index 6ebc0c34..8751faf6 100644 --- a/docs/advanced/misc.rst +++ b/docs/advanced/misc.rst @@ -28,7 +28,7 @@ multiple Python threads. Taking :ref:`overriding_virtuals` as an example, this could be realized as follows (important changes highlighted): .. code-block:: cpp - :emphasize-lines: 8,9,33,34 + :emphasize-lines: 8,9,31,32 class PyAnimal : public Animal { public: @@ -49,9 +49,7 @@ could be realized as follows (important changes highlighted): } }; - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - + PYBIND11_MODULE(example, m) { py::class_ animal(m, "Animal"); animal .def(py::init<>()) @@ -65,8 +63,6 @@ could be realized as follows (important changes highlighted): py::gil_scoped_release release; return call_go(animal); }); - - return m.ptr(); } 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 - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - + PYBIND11_MODULE(example, m) { py::options options; options.disable_function_signatures(); - + 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 diff --git a/docs/advanced/pycpp/numpy.rst b/docs/advanced/pycpp/numpy.rst index 964b1827..98b0c25b 100644 --- a/docs/advanced/pycpp/numpy.rst +++ b/docs/advanced/pycpp/numpy.rst @@ -190,7 +190,7 @@ expects the type followed by field names: }; // ... - PYBIND11_PLUGIN(test) { + PYBIND11_MODULE(test, m) { // ... PYBIND11_NUMPY_DTYPE(A, x, y); @@ -284,10 +284,8 @@ simply using ``vectorize``). return result; } - PYBIND11_PLUGIN(test) { - py::module m("test"); + PYBIND11_MODULE(test, m) { m.def("add_arrays", &add_arrays, "Add two NumPy arrays"); - return m.ptr(); } .. seealso:: diff --git a/docs/advanced/smart_ptrs.rst b/docs/advanced/smart_ptrs.rst index e4a23860..da57748c 100644 --- a/docs/advanced/smart_ptrs.rst +++ b/docs/advanced/smart_ptrs.rst @@ -63,16 +63,12 @@ code? std::shared_ptr child; }; - PYBIND11_PLUGIN(example) { - py::module m("example"); - + PYBIND11_MODULE(example, m) { py::class_>(m, "Child"); py::class_>(m, "Parent") .def(py::init<>()) .def("get_child", &Parent::get_child); - - return m.ptr(); } The following Python code will cause undefined behavior (and likely a diff --git a/docs/basics.rst b/docs/basics.rst index 33c60049..aa986807 100644 --- a/docs/basics.rst +++ b/docs/basics.rst @@ -96,25 +96,21 @@ a file named :file:`example.cpp` with the following contents: return i + j; } - namespace py = pybind11; - - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); + PYBIND11_MODULE(example, m) { + m.doc() = "pybind11 example plugin"; // optional module docstring m.def("add", &add, "A function which adds two numbers"); - - return m.ptr(); } .. [#f1] In practice, implementation and binding code will generally be located in separate files. -The :func:`PYBIND11_PLUGIN` macro creates a function that will be called when an -``import`` statement is issued from within Python. The next line creates a -module named ``example`` (with the supplied docstring). The method -:func:`module::def` generates binding code that exposes the -``add()`` function to Python. The last line returns the internal Python object -associated with ``m`` to the Python interpreter. +The :func:`PYBIND11_MODULE` macro creates a function that will be called when an +``import`` statement is issued from within Python. The module name (``example``) +is given as the fist macro argument (it should not be in quotes). The second +argument (``m``) defines a variable of type :class:`py::module ` which +is the main interface for creating bindings. The method :func:`module::def` +generates binding code that exposes the ``add()`` function to Python. .. note:: @@ -261,12 +257,10 @@ converted using the function ``py::cast``. .. code-block:: cpp - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); + PYBIND11_MODULE(example, m) { m.attr("the_answer") = 42; py::object world = py::cast("World"); m.attr("what") = world; - return m.ptr(); } These are then accessible from Python: diff --git a/docs/benchmark.py b/docs/benchmark.py index 6f02e92f..6dc0604e 100644 --- a/docs/benchmark.py +++ b/docs/benchmark.py @@ -33,10 +33,8 @@ def generate_dummy_code_pybind11(nclasses=10): result = "#include \n\n" result += "namespace py = pybind11;\n\n" result += decl + '\n' - result += "PYBIND11_PLUGIN(example) {\n" - result += " py::module m(\"example\");" + result += "PYBIND11_MODULE(example, m) {\n" result += bindings - result += " return m.ptr();" result += "}" return result diff --git a/docs/benchmark.rst b/docs/benchmark.rst index 8babaa31..59d533df 100644 --- a/docs/benchmark.rst +++ b/docs/benchmark.rst @@ -31,8 +31,7 @@ Here is an example of the binding code for one class: }; ... - PYBIND11_PLUGIN(example) { - py::module m("example"); + PYBIND11_MODULE(example, m) { ... py::class_(m, "cl034") .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_003", &cl034::fn_003) ... - return m.ptr(); } The Boost.Python version looks almost identical except that a return value diff --git a/docs/classes.rst b/docs/classes.rst index 30fb2a2d..7696c609 100644 --- a/docs/classes.rst +++ b/docs/classes.rst @@ -27,15 +27,11 @@ The binding code for ``Pet`` looks as follows: namespace py = pybind11; - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind11 example plugin"); - + PYBIND11_MODULE(example, m) { py::class_(m, "Pet") .def(py::init()) .def("setName", &Pet::setName) .def("getName", &Pet::getName); - - return m.ptr(); } :class:`class_` creates bindings for a C++ *class* or *struct*-style data diff --git a/docs/faq.rst b/docs/faq.rst index 34002b42..072b1572 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -4,30 +4,24 @@ Frequently asked questions "ImportError: dynamic module does not define init function" =========================================================== -1. Make sure that the name specified in ``pybind::module`` and - ``PYBIND11_PLUGIN`` is consistent and identical to the filename of the - extension library. The latter should not contain any extra prefixes (e.g. - ``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) +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``" ======================================================================== -See item 2 of the first answer. +See the first answer. "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 =================================================================== -See item 2 of the first answer. +See the first answer. CMake doesn't detect the right Python version ============================================= @@ -104,14 +98,10 @@ following example: void init_ex2(py::module &); /* ... */ - PYBIND11_PLUGIN(example) { - py::module m("example", "pybind example plugin"); - + PYBIND11_MODULE(example, m) { init_ex1(m); init_ex2(m); /* ... */ - - return m.ptr(); } :file:`ex1.cpp`: diff --git a/docs/reference.rst b/docs/reference.rst index f375791c..d9dc961c 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -12,7 +12,7 @@ Reference Macros ====== -.. doxygendefine:: PYBIND11_PLUGIN +.. doxygendefine:: PYBIND11_MODULE .. _core_types: diff --git a/include/pybind11/common.h b/include/pybind11/common.h index 38730092..c1ce7876 100644 --- a/include/pybind11/common.h +++ b/include/pybind11/common.h @@ -194,6 +194,8 @@ extern "C" { PYBIND11_TOSTRING(PYBIND11_VERSION_MAJOR) "_" PYBIND11_TOSTRING(PYBIND11_VERSION_MINOR) "__" /** \rst + ***Deprecated in favor of PYBIND11_MODULE*** + 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 the pointer to its underlying Python object at the end. @@ -207,6 +209,7 @@ extern "C" { } \endrst */ #define PYBIND11_PLUGIN(name) \ + PYBIND11_DEPRECATED("PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE") \ static PyObject *pybind11_init(); \ PYBIND11_PLUGIN_IMPL(name) { \ int major, minor; \ @@ -234,6 +237,54 @@ extern "C" { } \ 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) using ssize_t = Py_ssize_t; diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index b186c0b3..e0ee4bc1 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -117,6 +117,9 @@ public: PYBIND11_DEPRECATED("Use py::str(obj) instead") 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 int ref_count() const { return static_cast(Py_REFCNT(derived().ptr())); } /// Return a handle to the Python type object underlying the instance @@ -1248,6 +1251,9 @@ template template bool object_api::contains(T &&ite template pybind11::str object_api::str() const { return pybind11::str(derived()); } +template +str_attr_accessor object_api::doc() const { return attr("__doc__"); } + template handle object_api::get_type() const { return (PyObject *) Py_TYPE(derived().ptr()); } diff --git a/tests/pybind11_tests.cpp b/tests/pybind11_tests.cpp index 17a00b00..1e243501 100644 --- a/tests/pybind11_tests.cpp +++ b/tests/pybind11_tests.cpp @@ -52,8 +52,8 @@ void bind_ConstructorStats(py::module &m) { ; } -PYBIND11_PLUGIN(pybind11_tests) { - py::module m("pybind11_tests", "pybind testing plugin"); +PYBIND11_MODULE(pybind11_tests, m) { + m.doc() = "pybind11 test module"; bind_ConstructorStats(m); @@ -61,6 +61,4 @@ PYBIND11_PLUGIN(pybind11_tests) { initializer(m); if (!py::hasattr(m, "have_eigen")) m.attr("have_eigen") = false; - - return m.ptr(); } diff --git a/tests/test_cmake_build/main.cpp b/tests/test_cmake_build/main.cpp index e0f5b69c..e30f2c4b 100644 --- a/tests/test_cmake_build/main.cpp +++ b/tests/test_cmake_build/main.cpp @@ -1,10 +1,6 @@ #include namespace py = pybind11; -PYBIND11_PLUGIN(test_cmake_build) { - py::module m("test_cmake_build"); - +PYBIND11_MODULE(test_cmake_build, m) { m.def("add", [](int i, int j) { return i + j; }); - - return m.ptr(); } diff --git a/tests/test_modules.py b/tests/test_modules.py index 69620949..2a2c7944 100644 --- a/tests/test_modules.py +++ b/tests/test_modules.py @@ -59,4 +59,5 @@ def test_pydoc(): import pybind11_tests import pydoc + assert pybind11_tests.__doc__ == "pybind11 test module" assert pydoc.text.docmodule(pybind11_tests)