Skip to content

Commit 67b52d8

Browse files
committed
Reorganize documentation
1 parent 3eb569f commit 67b52d8

19 files changed

+2468
-2353
lines changed

docs/advanced.rst

Lines changed: 0 additions & 2276 deletions
This file was deleted.

docs/advanced/cast/chrono.rst

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
Chrono
2+
======
3+
4+
When including the additional header file :file:`pybind11/chrono.h` conversions
5+
from C++11 chrono datatypes to python datetime objects are automatically enabled.
6+
This header also enables conversions of python floats (often from sources such
7+
as `time.monotonic()`, `time.perf_counter()` and `time.process_time()`) into
8+
durations.
9+
10+
An overview of clocks in C++11
11+
------------------------------
12+
13+
A point of confusion when using these conversions is the differences between
14+
clocks provided in C++11. There are three clock types defined by the C++11
15+
standard and users can define their own if needed. Each of these clocks have
16+
different properties and when converting to and from python will give different
17+
results.
18+
19+
The first clock defined by the standard is ``std::chrono::system_clock``. This
20+
clock measures the current date and time. However, this clock changes with to
21+
updates to the operating system time. For example, if your time is synchronised
22+
with a time server this clock will change. This makes this clock a poor choice
23+
for timing purposes but good for measuring the wall time.
24+
25+
The second clock defined in the standard is ``std::chrono::steady_clock``.
26+
This clock ticks at a steady rate and is never adjusted. This makes it excellent
27+
for timing purposes, however the value in this clock does not correspond to the
28+
current date and time. Often this clock will be the amount of time your system
29+
has been on, although it does not have to be. This clock will never be the same
30+
clock as the system clock as the system clock can change but steady clocks
31+
cannot.
32+
33+
The third clock defined in the standard is ``std::chrono::high_resolution_clock``.
34+
This clock is the clock that has the highest resolution out of the clocks in the
35+
system. It is normally a typedef to either the system clock or the steady clock
36+
but can be its own independent clock. This is important as when using these
37+
conversions as the types you get in python for this clock might be different
38+
depending on the system.
39+
If it is a typedef of the system clock, python will get datetime objects, but if
40+
it is a different clock they will be timedelta objects.
41+
42+
Conversions Provided
43+
--------------------
44+
45+
.. rubric:: C++ to Python
46+
47+
- ``std::chrono::system_clock::time_point`` → ``datetime.datetime``
48+
System clock times are converted to python datetime instances. They are
49+
in the local timezone, but do not have any timezone information attached
50+
to them (they are naive datetime objects).
51+
52+
- ``std::chrono::duration`` → ``datetime.timedelta``
53+
Durations are converted to timedeltas, any precision in the duration
54+
greater than microseconds is lost by rounding towards zero.
55+
56+
- ``std::chrono::[other_clocks]::time_point`` → ``datetime.timedelta``
57+
Any clock time that is not the system clock is converted to a time delta.
58+
This timedelta measures the time from the clocks epoch to now.
59+
60+
.. rubric:: Python to C++
61+
62+
- ``datetime.datetime`` → ``std::chrono::system_clock::time_point``
63+
Date/time objects are converted into system clock timepoints. Any
64+
timezone information is ignored and the type is treated as a naive
65+
object.
66+
67+
- ``datetime.timedelta`` → ``std::chrono::duration``
68+
Time delta are converted into durations with microsecond precision.
69+
70+
- ``datetime.timedelta`` → ``std::chrono::[other_clocks]::time_point``
71+
Time deltas that are converted into clock timepoints are treated as
72+
the amount of time from the start of the clocks epoch.
73+
74+
- ``float`` → ``std::chrono::duration``
75+
Floats that are passed to C++ as durations be interpreted as a number of
76+
seconds. These will be converted to the duration using ``duration_cast``
77+
from the float.
78+
79+
- ``float`` → ``std::chrono::[other_clocks]::time_point``
80+
Floats that are passed to C++ as time points will be interpreted as the
81+
number of seconds from the start of the clocks epoch.

docs/advanced/cast/custom.rst

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
Custom type casters
2+
===================
3+
4+
In very rare cases, applications may require custom type casters that cannot be
5+
expressed using the abstractions provided by pybind11, thus requiring raw
6+
Python C API calls. This is fairly advanced usage and should only be pursued by
7+
experts who are familiar with the intricacies of Python reference counting.
8+
9+
The following snippets demonstrate how this works for a very simple ``inty``
10+
type that that should be convertible from Python types that provide a
11+
``__int__(self)`` method.
12+
13+
.. code-block:: cpp
14+
15+
struct inty { long long_value; };
16+
17+
void print(inty s) {
18+
std::cout << s.long_value << std::endl;
19+
}
20+
21+
The following Python snippet demonstrates the intended usage from the Python side:
22+
23+
.. code-block:: python
24+
25+
class A:
26+
def __int__(self):
27+
return 123
28+
29+
from example import print
30+
print(A())
31+
32+
To register the necessary conversion routines, it is necessary to add
33+
a partial overload to the ``pybind11::detail::type_caster<T>`` template.
34+
Although this is an implementation detail, adding partial overloads to this
35+
type is explicitly allowed.
36+
37+
.. code-block:: cpp
38+
39+
namespace pybind11 { namespace detail {
40+
template <> struct type_caster<inty> {
41+
public:
42+
/**
43+
* This macro establishes the name 'inty' in
44+
* function signatures and declares a local variable
45+
* 'value' of type inty
46+
*/
47+
PYBIND11_TYPE_CASTER(inty, _("inty"));
48+
49+
/**
50+
* Conversion part 1 (Python->C++): convert a PyObject into a inty
51+
* instance or return false upon failure. The second argument
52+
* indicates whether implicit conversions should be applied.
53+
*/
54+
bool load(handle src, bool) {
55+
/* Extract PyObject from handle */
56+
PyObject *source = src.ptr();
57+
/* Try converting into a Python integer value */
58+
PyObject *tmp = PyNumber_Long(source);
59+
if (!tmp)
60+
return false;
61+
/* Now try to convert into a C++ int */
62+
value.long_value = PyLong_AsLong(tmp);
63+
Py_DECREF(tmp);
64+
/* Ensure return code was OK (to avoid out-of-range errors etc) */
65+
return !(value.long_value == -1 && !PyErr_Occurred());
66+
}
67+
68+
/**
69+
* Conversion part 2 (C++ -> Python): convert an inty instance into
70+
* a Python object. The second and third arguments are used to
71+
* indicate the return value policy and parent object (for
72+
* ``return_value_policy::reference_internal``) and are generally
73+
* ignored by implicit casters.
74+
*/
75+
static handle cast(inty src, return_value_policy /* policy */, handle /* parent */) {
76+
return PyLong_FromLong(src.long_value);
77+
}
78+
};
79+
}} // namespace pybind11::detail

docs/advanced/cast/eigen.rst

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
Eigen
2+
=====
3+
4+
`Eigen <http://eigen.tuxfamily.org>`_ is C++ header-based library for dense and
5+
sparse linear algebra. Due to its popularity and widespread adoption, pybind11
6+
provides transparent conversion support between Eigen and Scientific Python linear
7+
algebra data types.
8+
9+
Specifically, when including the optional header file :file:`pybind11/eigen.h`,
10+
pybind11 will automatically and transparently convert
11+
12+
1. Static and dynamic Eigen dense vectors and matrices to instances of
13+
``numpy.ndarray`` (and vice versa).
14+
15+
2. Returned matrix expressions such as blocks (including columns or rows) and
16+
diagonals will be converted to ``numpy.ndarray`` of the expression
17+
values.
18+
19+
3. Returned matrix-like objects such as Eigen::DiagonalMatrix or
20+
Eigen::SelfAdjointView will be converted to ``numpy.ndarray`` containing the
21+
expressed value.
22+
23+
4. Eigen sparse vectors and matrices to instances of
24+
``scipy.sparse.csr_matrix``/``scipy.sparse.csc_matrix`` (and vice versa).
25+
26+
This makes it possible to bind most kinds of functions that rely on these types.
27+
One major caveat are functions that take Eigen matrices *by reference* and modify
28+
them somehow, in which case the information won't be propagated to the caller.
29+
30+
.. code-block:: cpp
31+
32+
/* The Python bindings of these functions won't replicate
33+
the intended effect of modifying the function arguments */
34+
void scale_by_2(Eigen::Vector3f &v) {
35+
v *= 2;
36+
}
37+
void scale_by_2(Eigen::Ref<Eigen::MatrixXd> &v) {
38+
v *= 2;
39+
}
40+
41+
To see why this is, refer to the section on :ref:`opaque` (although that
42+
section specifically covers STL data types, the underlying issue is the same).
43+
The :ref:`numpy` sections discuss an efficient alternative for exposing the
44+
underlying native Eigen types as opaque objects in a way that still integrates
45+
with NumPy and SciPy.
46+
47+
.. seealso::
48+
49+
The file :file:`tests/test_eigen.cpp` contains a complete example that
50+
shows how to pass Eigen sparse and dense data types in more detail.

docs/advanced/cast/functional.rst

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
Functional
2+
##########
3+
4+
The following features must be enabled by including :file:`pybind11/functional.h`.
5+
6+
7+
Callbacks and passing anonymous functions
8+
=========================================
9+
10+
The C++11 standard brought lambda functions and the generic polymorphic
11+
function wrapper ``std::function<>`` to the C++ programming language, which
12+
enable powerful new ways of working with functions. Lambda functions come in
13+
two flavors: stateless lambda function resemble classic function pointers that
14+
link to an anonymous piece of code, while stateful lambda functions
15+
additionally depend on captured variables that are stored in an anonymous
16+
*lambda closure object*.
17+
18+
Here is a simple example of a C++ function that takes an arbitrary function
19+
(stateful or stateless) with signature ``int -> int`` as an argument and runs
20+
it with the value 10.
21+
22+
.. code-block:: cpp
23+
24+
int func_arg(const std::function<int(int)> &f) {
25+
return f(10);
26+
}
27+
28+
The example below is more involved: it takes a function of signature ``int -> int``
29+
and returns another function of the same kind. The return value is a stateful
30+
lambda function, which stores the value ``f`` in the capture object and adds 1 to
31+
its return value upon execution.
32+
33+
.. code-block:: cpp
34+
35+
std::function<int(int)> func_ret(const std::function<int(int)> &f) {
36+
return [f](int i) {
37+
return f(i) + 1;
38+
};
39+
}
40+
41+
This example demonstrates using python named parameters in C++ callbacks which
42+
requires using ``py::cpp_function`` as a wrapper. Usage is similar to defining
43+
methods of classes:
44+
45+
.. code-block:: cpp
46+
47+
py::cpp_function func_cpp() {
48+
return py::cpp_function([](int i) { return i+1; },
49+
py::arg("number"));
50+
}
51+
52+
After including the extra header file :file:`pybind11/functional.h`, it is almost
53+
trivial to generate binding code for all of these functions.
54+
55+
.. code-block:: cpp
56+
57+
#include <pybind11/functional.h>
58+
59+
PYBIND11_PLUGIN(example) {
60+
py::module m("example", "pybind11 example plugin");
61+
62+
m.def("func_arg", &func_arg);
63+
m.def("func_ret", &func_ret);
64+
m.def("func_cpp", &func_cpp);
65+
66+
return m.ptr();
67+
}
68+
69+
The following interactive session shows how to call them from Python.
70+
71+
.. code-block:: pycon
72+
73+
$ python
74+
>>> import example
75+
>>> def square(i):
76+
... return i * i
77+
...
78+
>>> example.func_arg(square)
79+
100L
80+
>>> square_plus_1 = example.func_ret(square)
81+
>>> square_plus_1(4)
82+
17L
83+
>>> plus_1 = func_cpp()
84+
>>> plus_1(number=43)
85+
44L
86+
87+
.. warning::
88+
89+
Keep in mind that passing a function from C++ to Python (or vice versa)
90+
will instantiate a piece of wrapper code that translates function
91+
invocations between the two languages. Naturally, this translation
92+
increases the computational cost of each function call somewhat. A
93+
problematic situation can arise when a function is copied back and forth
94+
between Python and C++ many times in a row, in which case the underlying
95+
wrappers will accumulate correspondingly. The resulting long sequence of
96+
C++ -> Python -> C++ -> ... roundtrips can significantly decrease
97+
performance.
98+
99+
There is one exception: pybind11 detects case where a stateless function
100+
(i.e. a function pointer or a lambda function without captured variables)
101+
is passed as an argument to another C++ function exposed in Python. In this
102+
case, there is no overhead. Pybind11 will extract the underlying C++
103+
function pointer from the wrapped function to sidestep a potential C++ ->
104+
Python -> C++ roundtrip. This is demonstrated in :file:`tests/test_callbacks.cpp`.
105+
106+
.. note::
107+
108+
This functionality is very useful when generating bindings for callbacks in
109+
C++ libraries (e.g. GUI libraries, asynchronous networking libraries, etc.).
110+
111+
The file :file:`tests/test_callbacks.cpp` contains a complete example
112+
that demonstrates how to work with callbacks and anonymous functions in
113+
more detail.

0 commit comments

Comments
 (0)