mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-24 22:25:10 +00:00
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:
parent
b700c5d672
commit
443ab5946b
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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::
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
24
docs/faq.rst
24
docs/faq.rst
@ -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`:
|
||||||
|
@ -12,7 +12,7 @@ Reference
|
|||||||
Macros
|
Macros
|
||||||
======
|
======
|
||||||
|
|
||||||
.. doxygendefine:: PYBIND11_PLUGIN
|
.. doxygendefine:: PYBIND11_MODULE
|
||||||
|
|
||||||
.. _core_types:
|
.. _core_types:
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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()); }
|
||||||
|
|
||||||
|
@ -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();
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user