Back to home page

EIC code displayed by LXR

 
 

    


Warning, /jana2/src/python/externals/pybind11-2.10.3/docs/advanced/pycpp/utilities.rst is written in an unsupported language. File is not indexed.

0001 Utilities
0002 #########
0003 
0004 Using Python's print function in C++
0005 ====================================
0006 
0007 The usual way to write output in C++ is using ``std::cout`` while in Python one
0008 would use ``print``. Since these methods use different buffers, mixing them can
0009 lead to output order issues. To resolve this, pybind11 modules can use the
0010 :func:`py::print` function which writes to Python's ``sys.stdout`` for consistency.
0011 
0012 Python's ``print`` function is replicated in the C++ API including optional
0013 keyword arguments ``sep``, ``end``, ``file``, ``flush``. Everything works as
0014 expected in Python:
0015 
0016 .. code-block:: cpp
0017 
0018     py::print(1, 2.0, "three"); // 1 2.0 three
0019     py::print(1, 2.0, "three", "sep"_a="-"); // 1-2.0-three
0020 
0021     auto args = py::make_tuple("unpacked", true);
0022     py::print("->", *args, "end"_a="<-"); // -> unpacked True <-
0023 
0024 .. _ostream_redirect:
0025 
0026 Capturing standard output from ostream
0027 ======================================
0028 
0029 Often, a library will use the streams ``std::cout`` and ``std::cerr`` to print,
0030 but this does not play well with Python's standard ``sys.stdout`` and ``sys.stderr``
0031 redirection. Replacing a library's printing with ``py::print <print>`` may not
0032 be feasible. This can be fixed using a guard around the library function that
0033 redirects output to the corresponding Python streams:
0034 
0035 .. code-block:: cpp
0036 
0037     #include <pybind11/iostream.h>
0038 
0039     ...
0040 
0041     // Add a scoped redirect for your noisy code
0042     m.def("noisy_func", []() {
0043         py::scoped_ostream_redirect stream(
0044             std::cout,                               // std::ostream&
0045             py::module_::import("sys").attr("stdout") // Python output
0046         );
0047         call_noisy_func();
0048     });
0049 
0050 .. warning::
0051 
0052     The implementation in ``pybind11/iostream.h`` is NOT thread safe. Multiple
0053     threads writing to a redirected ostream concurrently cause data races
0054     and potentially buffer overflows. Therefore it is currently a requirement
0055     that all (possibly) concurrent redirected ostream writes are protected by
0056     a mutex. #HelpAppreciated: Work on iostream.h thread safety. For more
0057     background see the discussions under
0058     `PR #2982 <https://github.com/pybind/pybind11/pull/2982>`_ and
0059     `PR #2995 <https://github.com/pybind/pybind11/pull/2995>`_.
0060 
0061 This method respects flushes on the output streams and will flush if needed
0062 when the scoped guard is destroyed. This allows the output to be redirected in
0063 real time, such as to a Jupyter notebook. The two arguments, the C++ stream and
0064 the Python output, are optional, and default to standard output if not given. An
0065 extra type, ``py::scoped_estream_redirect <scoped_estream_redirect>``, is identical
0066 except for defaulting to ``std::cerr`` and ``sys.stderr``; this can be useful with
0067 ``py::call_guard``, which allows multiple items, but uses the default constructor:
0068 
0069 .. code-block:: cpp
0070 
0071     // Alternative: Call single function using call guard
0072     m.def("noisy_func", &call_noisy_function,
0073           py::call_guard<py::scoped_ostream_redirect,
0074                          py::scoped_estream_redirect>());
0075 
0076 The redirection can also be done in Python with the addition of a context
0077 manager, using the ``py::add_ostream_redirect() <add_ostream_redirect>`` function:
0078 
0079 .. code-block:: cpp
0080 
0081     py::add_ostream_redirect(m, "ostream_redirect");
0082 
0083 The name in Python defaults to ``ostream_redirect`` if no name is passed.  This
0084 creates the following context manager in Python:
0085 
0086 .. code-block:: python
0087 
0088     with ostream_redirect(stdout=True, stderr=True):
0089         noisy_function()
0090 
0091 It defaults to redirecting both streams, though you can use the keyword
0092 arguments to disable one of the streams if needed.
0093 
0094 .. note::
0095 
0096     The above methods will not redirect C-level output to file descriptors, such
0097     as ``fprintf``. For those cases, you'll need to redirect the file
0098     descriptors either directly in C or with Python's ``os.dup2`` function
0099     in an operating-system dependent way.
0100 
0101 .. _eval:
0102 
0103 Evaluating Python expressions from strings and files
0104 ====================================================
0105 
0106 pybind11 provides the ``eval``, ``exec`` and ``eval_file`` functions to evaluate
0107 Python expressions and statements. The following example illustrates how they
0108 can be used.
0109 
0110 .. code-block:: cpp
0111 
0112     // At beginning of file
0113     #include <pybind11/eval.h>
0114 
0115     ...
0116 
0117     // Evaluate in scope of main module
0118     py::object scope = py::module_::import("__main__").attr("__dict__");
0119 
0120     // Evaluate an isolated expression
0121     int result = py::eval("my_variable + 10", scope).cast<int>();
0122 
0123     // Evaluate a sequence of statements
0124     py::exec(
0125         "print('Hello')\n"
0126         "print('world!');",
0127         scope);
0128 
0129     // Evaluate the statements in an separate Python file on disk
0130     py::eval_file("script.py", scope);
0131 
0132 C++11 raw string literals are also supported and quite handy for this purpose.
0133 The only requirement is that the first statement must be on a new line following
0134 the raw string delimiter ``R"(``, ensuring all lines have common leading indent:
0135 
0136 .. code-block:: cpp
0137 
0138     py::exec(R"(
0139         x = get_answer()
0140         if x == 42:
0141             print('Hello World!')
0142         else:
0143             print('Bye!')
0144         )", scope
0145     );
0146 
0147 .. note::
0148 
0149     `eval` and `eval_file` accept a template parameter that describes how the
0150     string/file should be interpreted. Possible choices include ``eval_expr``
0151     (isolated expression), ``eval_single_statement`` (a single statement, return
0152     value is always ``none``), and ``eval_statements`` (sequence of statements,
0153     return value is always ``none``). `eval` defaults to  ``eval_expr``,
0154     `eval_file` defaults to ``eval_statements`` and `exec` is just a shortcut
0155     for ``eval<eval_statements>``.