utilities.rst revision 12391
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