Wrap a Python io object in an ostream
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
I claim that it would be worthwhile to allow Python io objects to be wrapped into std::ostreams. Currently, one has to use scoped_ostream_redirect like so:
m.def("foo", [](pybind11::object io) {
std::ostringstream out;
pybind11::scoped_ostream_redirect redirect{out, file};
// rest of code, using `out` as the std::ostream&
});
However, std::ostream can be constructed by a std::streambuf. scoped_ostream_redirect uses a streambuf implementation. Thus, it's possible to directly create a std::ostream from the object:
pybind11::detail::pythonbuf buffer{io};
std::ostream out{&buffer};
What I'm leading up to is this (currently doesn't work):
m.def("foo", [](std::ostream& out) {
// using `out` as before
});
Which could be used in Python as if it were a regular Python io object:
import io
out = io.StringIO()
m.foo(out)
print(out.getvalue())
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the scoped_ostream_redirect and detail::pythonbuf implementations mentioned in the issue, then trace how std::ostream& arguments are handled. Done means a Python io.StringIO can be passed to m.foo as std::ostream& and its output is available through getvalue(); no specific files or tests are named.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- api, backend-api-design
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100