@@ -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
2668Capturing standard output from ostream
0 commit comments