-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Redirecting python output with embedded interpreter #1622
Comments
You can replace In this code, I replace them with
This class can be used as follows:
|
@madebr Thanks for answering. We can close the issue. |
I realize this is an older issue, but when using pybind11 embedded, this would probably be a FAQ. Should it be added to the docs? Maybe in the Utilities section with the other i/o issues? |
Except that we're not really providing a utility class/function to do this :-/ This is a nice class and useful implementation, but to some degree, it's basically the same as you would need to do in pure Python to capture output (e.g. https://stackoverflow.com/a/1218951 or https://stackoverflow.com/a/16571630) So I'm a bit hesitant to add it to the pybind11 docs (and in particular to that page, as I'm not sure it will be noticed?). |
Which one might be aware of or understand if you're a Python person trying to integrate some C++, but if you're a C++ person trying to embed Python it's not at all obvious (in my (recent) experience 😄 ).
I mentioned that page because I went looking everywhere for it and that was the page I landed on - I guess because it kind of describes the "opposite" - Capturing standard output from ostream. Maybe just a comment about it with a pointer to the things you mention? |
Well, yes, but that doesn't mean pybind11 should become the tutorial for C++ users learning Python (OK, that's a bit too harsh and unfair, I realize that, but you get my point, I hope ;-) )
I guess that could work. Something short, like this, then? ..note:
Doing the reverse and capturing Python's `stdout` and `stderr` in C++, can be done in the same way as in pure Python, by (temporarily) replacing `sys.stdout` and `sys.stderr` with an `io.StringIO` object. |
Not even remotely what I was suggesting. That simple note would have helped a lot and saved a bunch of time, yes. |
I know, that's not what I was claiming either. But so, we need to be careful not to put "normal Python stuff" here, for things that should actually be read in the Python docs ;-) |
My implementation is as follows The principle is to implement a module to replace #include <iostream>
#include <pybind11/embed.h>
PYBIND11_EMBEDDED_MODULE(my_sys, m) {
struct my_stdout {
my_stdout() = default;
my_stdout(const my_stdout &) = default;
my_stdout(my_stdout &&) = default;
};
py::class_<my_stdout> my_stdout(m, "my_stdout");
my_stdout.def_static("write", [](py::object buffer) {
std::cout << buffer.cast<std::string>();
});
my_stdout.def_static("flush", []() {
std::cout << std::flush;
});
m.def("hook_stdout", []() {
auto py_sys = py::module::import("sys");
auto my_sys = py::module::import("my_sys");
py_sys.attr("stdout") = my_sys.attr("my_stdout");
});
}
auto main(int argc, char **argv) -> int {
py::scoped_interpreter python;
#if 0
py_stdout.attr("write") = py::cpp_function([](py::object info) {
std::cout << "info" << std::endl;
});
#else
py::module::import("my_sys").attr("hook_stdout")();
#endif
py::print("Hello, World!\n")
return 0;
} |
I'm using pybind11 to execute python scripts inside a C++ dll with custom embedded modules, which is working perfectly, but I can't figure out how to redirect the python output globally.
Ideally I would like any output from python to be redirected as a string into a function.
Is this at all possible?
The text was updated successfully, but these errors were encountered: