PyO3-File
This a small utility library to facilitate working with python file-like with rust.
Example
use pyo3_file::PyFileLikeObject;
use pyo3::types::PyString;
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
use std::io::Read;
#[derive(Debug)]
enum FileOrFileLike {
File(String),
FileLike(PyFileLikeObject),
}
impl FileOrFileLike {
pub fn from_pyobject(path_or_file_like: PyObject) -> PyResult<FileOrFileLike> {
let gil = Python::acquire_gil();
let py = gil.python();
if let Ok(string_ref) = path_or_file_like.cast_as::<PyString>(py) {
return Ok(FileOrFileLike::File(
string_ref.to_string_lossy().to_string(),
));
}
match PyFileLikeObject::new(path_or_file_like) {
Ok(f) => Ok(FileOrFileLike::FileLike(f)),
Err(e) => Err(e),
}
}
}
#[pyfunction]
fn accepts_path_or_file_like(path_or_file_like: PyObject) -> PyResult<usize> {
match FileOrFileLike::from_pyobject(path_or_file_like) {
Ok(f) => match f {
FileOrFileLike::File(s) => {
println!("It's a file! - path {}", s);
Ok(0)
},
FileOrFileLike::FileLike(mut f) => {
println!("Its a file-like object");
let mut buffer = vec![0; 4096];
Ok(f.read(&mut buffer)?)
}
},
Err(e) => Err(e)
}
}
#[pymodule]
fn example_module(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(accepts_path_or_file_like))?;
Ok(())
}
# fn main() {}
and use from python:
from example_module import accepts_path_or_file_like
def main():
accepts_path_or_file_like("./some_file.txt")
f = open('./some_file.txt')
accepts_path_or_file_like(f)