-
I'm currently migrating a Python library to PyO3 and I'm hitting a bit of a roadblock. Consider the following Python signature: def write_to_stream(stream: TextIO | None, message: str) -> None I want to write a similar function in Rust, ideally something that accepts a type along the lines of struct FileHandle(Option<Arc<Mutex<File>>>);
impl FromPyObject<'_> for FileHandle {
fn extract_bound(ob: &pyo3::Bound<'_, pyo3::PyAny>) -> PyResult<Self> {
let raw_fd = match ob.extract()? {
Some(raw_fd) => raw_fd,
None => return Ok(Self(None)),
};
// SAFETY: This function is only safe when accessed via a Python interface.
// The consuming Python script should manage the file descriptor handed
// here, and it is up to said script to ensure the existence of the raw FD.
let handle = unsafe { File::from_raw_fd(raw_fd) };
Ok(Self(Some(Arc::new(Mutex::new(handle)))))
}
}
#[pyfunction]
fn write_to_stream(stream: &mut FileHandle, message: String) This still fails though as it assumes that it'll be handed a
I think I could overcome this by preprocessing the stream on the Python side, sending the raw FD instead of the entire stream object. I really don't like this solution in the first place though, so I'd rather uproot it entirely than try to implement that. Any suggestions? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
An option would be to not convert the IO object to Rust and instead store the Python object directly impl FileHandle {
fn write(&self, py: Python<'_>, msg: &str) -> PyResult<()> {
self.0.call_method(intern!("write"), (msg,), None)?;
Ok(())
}
} and use them in #[pyfunction]
fn write_to_stream(py: Python<'_>, stream: &FileHandle, message: String) -> PyResult<()> {
stream.write(py, &message)
} |
Beta Was this translation helpful? Give feedback.
An option would be to not convert the IO object to Rust and instead store the Python object directly
struct FileHandle(Option<Py<PyAny>>)
. You could do some validation inFromPyObject
that the object has the required attributes (write
,read
, ...). Then define some helpers likeand use them in
write_to_stream