Pybind11: How can I filter print messages of python on a C++ apllication embeded with python?

Created on 21 Jul 2020  路  2Comments  路  Source: pybind/pybind11

Good afternoon,

First of all congratulation to the developers for the great work they are doing.

I am working on a C++ application and I have recently -- successfully -- embedded using this library. However, I am not able to filter the messages that come from my python script.

For instance, when I run the following program in c++

#include "pybind11/pybind11.h"
#include "pybind11/embed.h"
namespace py = pybind11;

int main()
{
    py::initialize_interpreter();
    {
        py::print("Hello world from python embedded!");
        py::exec("print(\'Hello again from python embedded!\')");
    }
    py::finalize_interpreter();
    return 0;
}

I get -- as expected -- this outuput:

Hello world from python embedded!
Hello again from python embedded!

But what I want to do is filter those print messages and treat them on a predefined funcion. For instance, I want that all print messages passes to the follow function:

void treatPythonPrintMessage(const char* message)
{
    // do something with 'message' here
}

So every time call

print(msg)

on my python script, the msg goes to the function treatPythonPrintMessage.

How can I do it?

Thanks in advance.

Most helpful comment

You should be able to redirect sys.stdout to accomplish your goal. Recommend googling/stack overflow for "python redirect sys.stdout". Just use py::exec to execute the python code that does this before your statements are executed.

All 2 comments

You should be able to redirect sys.stdout to accomplish your goal. Recommend googling/stack overflow for "python redirect sys.stdout". Just use py::exec to execute the python code that does this before your statements are executed.

This is not really anything pybind11-specific. You can intercept print in various ways, in Python: see e.g. https://stackoverflow.com/questions/17067560/intercept-pythons-print-statement-and-display-in-gui

Doing so in pybind11 should be straightforward through py::module::import("sys").attr("stdout") = ...;

EDIT: Ah, too late. Thanks, @virtuald! :-)

Was this page helpful?
0 / 5 - 0 ratings