111986Sandreas.sandberg@arm.comUtilities
211986Sandreas.sandberg@arm.com#########
311986Sandreas.sandberg@arm.com
411986Sandreas.sandberg@arm.comUsing Python's print function in C++
511986Sandreas.sandberg@arm.com====================================
611986Sandreas.sandberg@arm.com
711986Sandreas.sandberg@arm.comThe usual way to write output in C++ is using ``std::cout`` while in Python one
811986Sandreas.sandberg@arm.comwould use ``print``. Since these methods use different buffers, mixing them can
911986Sandreas.sandberg@arm.comlead to output order issues. To resolve this, pybind11 modules can use the
1011986Sandreas.sandberg@arm.com:func:`py::print` function which writes to Python's ``sys.stdout`` for consistency.
1111986Sandreas.sandberg@arm.com
1211986Sandreas.sandberg@arm.comPython's ``print`` function is replicated in the C++ API including optional
1311986Sandreas.sandberg@arm.comkeyword arguments ``sep``, ``end``, ``file``, ``flush``. Everything works as
1411986Sandreas.sandberg@arm.comexpected in Python:
1511986Sandreas.sandberg@arm.com
1611986Sandreas.sandberg@arm.com.. code-block:: cpp
1711986Sandreas.sandberg@arm.com
1811986Sandreas.sandberg@arm.com    py::print(1, 2.0, "three"); // 1 2.0 three
1911986Sandreas.sandberg@arm.com    py::print(1, 2.0, "three", "sep"_a="-"); // 1-2.0-three
2011986Sandreas.sandberg@arm.com
2111986Sandreas.sandberg@arm.com    auto args = py::make_tuple("unpacked", true);
2211986Sandreas.sandberg@arm.com    py::print("->", *args, "end"_a="<-"); // -> unpacked True <-
2311986Sandreas.sandberg@arm.com
2412391Sjason@lowepower.com.. _ostream_redirect:
2512391Sjason@lowepower.com
2612391Sjason@lowepower.comCapturing standard output from ostream
2712391Sjason@lowepower.com======================================
2812391Sjason@lowepower.com
2912391Sjason@lowepower.comOften, a library will use the streams ``std::cout`` and ``std::cerr`` to print,
3012391Sjason@lowepower.combut this does not play well with Python's standard ``sys.stdout`` and ``sys.stderr``
3112391Sjason@lowepower.comredirection. Replacing a library's printing with `py::print <print>` may not
3212391Sjason@lowepower.combe feasible. This can be fixed using a guard around the library function that
3312391Sjason@lowepower.comredirects output to the corresponding Python streams:
3412391Sjason@lowepower.com
3512391Sjason@lowepower.com.. code-block:: cpp
3612391Sjason@lowepower.com
3712391Sjason@lowepower.com    #include <pybind11/iostream.h>
3812391Sjason@lowepower.com
3912391Sjason@lowepower.com    ...
4012391Sjason@lowepower.com
4112391Sjason@lowepower.com    // Add a scoped redirect for your noisy code
4212391Sjason@lowepower.com    m.def("noisy_func", []() {
4312391Sjason@lowepower.com        py::scoped_ostream_redirect stream(
4412391Sjason@lowepower.com            std::cout,                               // std::ostream&
4512391Sjason@lowepower.com            py::module::import("sys").attr("stdout") // Python output
4612391Sjason@lowepower.com        );
4712391Sjason@lowepower.com        call_noisy_func();
4812391Sjason@lowepower.com    });
4912391Sjason@lowepower.com
5012391Sjason@lowepower.comThis method respects flushes on the output streams and will flush if needed
5112391Sjason@lowepower.comwhen the scoped guard is destroyed. This allows the output to be redirected in
5212391Sjason@lowepower.comreal time, such as to a Jupyter notebook. The two arguments, the C++ stream and
5312391Sjason@lowepower.comthe Python output, are optional, and default to standard output if not given. An
5412391Sjason@lowepower.comextra type, `py::scoped_estream_redirect <scoped_estream_redirect>`, is identical
5512391Sjason@lowepower.comexcept for defaulting to ``std::cerr`` and ``sys.stderr``; this can be useful with
5612391Sjason@lowepower.com`py::call_guard`, which allows multiple items, but uses the default constructor:
5712391Sjason@lowepower.com
5812391Sjason@lowepower.com.. code-block:: py
5912391Sjason@lowepower.com
6012391Sjason@lowepower.com    // Alternative: Call single function using call guard
6112391Sjason@lowepower.com    m.def("noisy_func", &call_noisy_function,
6212391Sjason@lowepower.com          py::call_guard<py::scoped_ostream_redirect,
6312391Sjason@lowepower.com                         py::scoped_estream_redirect>());
6412391Sjason@lowepower.com
6512391Sjason@lowepower.comThe redirection can also be done in Python with the addition of a context
6612391Sjason@lowepower.commanager, using the `py::add_ostream_redirect() <add_ostream_redirect>` function:
6712391Sjason@lowepower.com
6812391Sjason@lowepower.com.. code-block:: cpp
6912391Sjason@lowepower.com
7012391Sjason@lowepower.com    py::add_ostream_redirect(m, "ostream_redirect");
7112391Sjason@lowepower.com
7212391Sjason@lowepower.comThe name in Python defaults to ``ostream_redirect`` if no name is passed.  This
7312391Sjason@lowepower.comcreates the following context manager in Python:
7412391Sjason@lowepower.com
7512391Sjason@lowepower.com.. code-block:: python
7612391Sjason@lowepower.com
7712391Sjason@lowepower.com    with ostream_redirect(stdout=True, stderr=True):
7812391Sjason@lowepower.com        noisy_function()
7912391Sjason@lowepower.com
8012391Sjason@lowepower.comIt defaults to redirecting both streams, though you can use the keyword
8112391Sjason@lowepower.comarguments to disable one of the streams if needed.
8212391Sjason@lowepower.com
8312391Sjason@lowepower.com.. note::
8412391Sjason@lowepower.com
8512391Sjason@lowepower.com    The above methods will not redirect C-level output to file descriptors, such
8612391Sjason@lowepower.com    as ``fprintf``. For those cases, you'll need to redirect the file
8712391Sjason@lowepower.com    descriptors either directly in C or with Python's ``os.dup2`` function
8812391Sjason@lowepower.com    in an operating-system dependent way.
8912391Sjason@lowepower.com
9012391Sjason@lowepower.com.. _eval:
9112391Sjason@lowepower.com
9211986Sandreas.sandberg@arm.comEvaluating Python expressions from strings and files
9311986Sandreas.sandberg@arm.com====================================================
9411986Sandreas.sandberg@arm.com
9512391Sjason@lowepower.compybind11 provides the `eval`, `exec` and `eval_file` functions to evaluate
9611986Sandreas.sandberg@arm.comPython expressions and statements. The following example illustrates how they
9711986Sandreas.sandberg@arm.comcan be used.
9811986Sandreas.sandberg@arm.com
9911986Sandreas.sandberg@arm.com.. code-block:: cpp
10011986Sandreas.sandberg@arm.com
10111986Sandreas.sandberg@arm.com    // At beginning of file
10211986Sandreas.sandberg@arm.com    #include <pybind11/eval.h>
10311986Sandreas.sandberg@arm.com
10411986Sandreas.sandberg@arm.com    ...
10511986Sandreas.sandberg@arm.com
10611986Sandreas.sandberg@arm.com    // Evaluate in scope of main module
10711986Sandreas.sandberg@arm.com    py::object scope = py::module::import("__main__").attr("__dict__");
10811986Sandreas.sandberg@arm.com
10911986Sandreas.sandberg@arm.com    // Evaluate an isolated expression
11011986Sandreas.sandberg@arm.com    int result = py::eval("my_variable + 10", scope).cast<int>();
11111986Sandreas.sandberg@arm.com
11211986Sandreas.sandberg@arm.com    // Evaluate a sequence of statements
11312391Sjason@lowepower.com    py::exec(
11411986Sandreas.sandberg@arm.com        "print('Hello')\n"
11511986Sandreas.sandberg@arm.com        "print('world!');",
11611986Sandreas.sandberg@arm.com        scope);
11711986Sandreas.sandberg@arm.com
11811986Sandreas.sandberg@arm.com    // Evaluate the statements in an separate Python file on disk
11911986Sandreas.sandberg@arm.com    py::eval_file("script.py", scope);
12012391Sjason@lowepower.com
12112391Sjason@lowepower.comC++11 raw string literals are also supported and quite handy for this purpose.
12212391Sjason@lowepower.comThe only requirement is that the first statement must be on a new line following
12312391Sjason@lowepower.comthe raw string delimiter ``R"(``, ensuring all lines have common leading indent:
12412391Sjason@lowepower.com
12512391Sjason@lowepower.com.. code-block:: cpp
12612391Sjason@lowepower.com
12712391Sjason@lowepower.com    py::exec(R"(
12812391Sjason@lowepower.com        x = get_answer()
12912391Sjason@lowepower.com        if x == 42:
13012391Sjason@lowepower.com            print('Hello World!')
13112391Sjason@lowepower.com        else:
13212391Sjason@lowepower.com            print('Bye!')
13312391Sjason@lowepower.com        )", scope
13412391Sjason@lowepower.com    );
13512391Sjason@lowepower.com
13612391Sjason@lowepower.com.. note::
13712391Sjason@lowepower.com
13812391Sjason@lowepower.com    `eval` and `eval_file` accept a template parameter that describes how the
13912391Sjason@lowepower.com    string/file should be interpreted. Possible choices include ``eval_expr``
14012391Sjason@lowepower.com    (isolated expression), ``eval_single_statement`` (a single statement, return
14112391Sjason@lowepower.com    value is always ``none``), and ``eval_statements`` (sequence of statements,
14212391Sjason@lowepower.com    return value is always ``none``). `eval` defaults to  ``eval_expr``,
14312391Sjason@lowepower.com    `eval_file` defaults to ``eval_statements`` and `exec` is just a shortcut
14412391Sjason@lowepower.com    for ``eval<eval_statements>``.
145