Skip to content

Commit 829102b

Browse files
committed
Added a description of py::with to the documentation
1 parent b5634e2 commit 829102b

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

docs/advanced/pycpp/utilities.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,48 @@ expected in Python:
2121
auto args = py::make_tuple("unpacked", true);
2222
py::print("->", *args, "end"_a="<-"); // -> unpacked True <-
2323
24+
Executing code in a Python `with` statement
25+
===========================================
26+
27+
Where in C++, the scope of local variables and their destructor is used to manage
28+
resources in the RAII idiom, Python has a `with` statement and context managers
29+
for such situations. At the start and end of the `with` statement, the context
30+
manager's `__enter__` and `__exit__` methods are called, respectively. To more
31+
easily use context managers in a C++ context, pybind11 provides a utility function
32+
``py::with``, that matches the semantics of a Python `with`-statement (see
33+
`PEP 343 <https://www.python.org/dev/peps/pep-0343/>`_):
34+
35+
.. code-block:: cpp
36+
37+
auto io = py::module::import("io");
38+
py::with(io.attr("open")("tmp.out", "w"), [](py::object &&f) {
39+
for (int i = 0; i < 10; ++i) {
40+
f.attr("write")(i);
41+
f.attr("write")("\n");
42+
}
43+
});
44+
45+
This code snippet corresponds to the following in Python:
46+
47+
.. code-block:: python
48+
49+
import io
50+
with io.open("tmp.out", "w") as f:
51+
for i in range(10):
52+
f.write(i)
53+
f.write("\n")
54+
55+
The `py::object` parameter of the lambda function can be omitted if the object resulting
56+
from the context manager (i.e., the `as VAR` part in the `with` statement) is not of use.
57+
58+
Optionally, an extra `py::with_exception_policy` argument can be passed to `py::with`.
59+
If the value `py::with_exception_policy::translate` is selected, pybind11 will try to
60+
translate any C++ exception inside the `with` statement and pass the Python exception
61+
as argument into the `__exit__` method of the context manager (cfr. PEP 343). If
62+
`py::with_exception_policy::translate` is passed and an exception gets thrown, pybind11
63+
will not try to translate it, `__exit__` will be called as if no exception was thrown,
64+
and the original exception will be cascaded down to the caller.
65+
2466
.. _ostream_redirect:
2567

2668
Capturing standard output from ostream

0 commit comments

Comments
 (0)