#python #pyo3 #file #object #read-file #helper #file-path

pyo3-file

一个用于处理 Python 文件对象的小型辅助库

12 个版本 (6 个重大更新)

0.8.1 2024 年 6 月 11 日
0.7.0 2023 年 6 月 26 日
0.5.0 2022 年 4 月 16 日
0.4.0 2021 年 7 月 9 日
0.2.0 2019 年 5 月 20 日

#60FFI

Download history 1327/week @ 2024-04-27 570/week @ 2024-05-04 766/week @ 2024-05-11 896/week @ 2024-05-18 917/week @ 2024-05-25 500/week @ 2024-06-01 960/week @ 2024-06-08 437/week @ 2024-06-15 259/week @ 2024-06-22 570/week @ 2024-06-29 344/week @ 2024-07-06 391/week @ 2024-07-13 616/week @ 2024-07-20 1115/week @ 2024-07-27 1463/week @ 2024-08-03 570/week @ 2024-08-10

每月下载量 3,829

MIT/Apache

13KB
216

crates.io

PyO3-File

这是一个小型实用库,用于方便地在 Rust 中处理 Python 文件对象。

示例

此库的一个示例用途是在 Python 中打开文件,并将其传递给 Rust 库。

我们可以通过反射 PyObject 来支持这两种情况,并选择正确的行为。

我们希望它能够这样做

from path_or_file_like import accepts_path_or_file_like

def main():
    # should open `some_file.txt`.
    accepts_path_or_file_like("./some_file.txt")

    # should read from the python handle.
    f = open('./some_file.txt')
    accepts_path_or_file_like(f)

我们可以使用 pyo3_file 来扩展现有的 pyo3 模块。

use pyo3_file::PyFileLikeObject;
use pyo3::types::PyString;

use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
use std::io::Read;
use std::fs::File;

/// Represents either a path `File` or a file-like object `FileLike`
#[derive(Debug)]
enum FileOrFileLike {
    File(String),
    FileLike(PyFileLikeObject),
}

impl FileOrFileLike {
    pub fn from_pyobject(path_or_file_like: PyObject) -> PyResult<FileOrFileLike> {
        Python::with_gil(|py| {
            // is a path
            if let Ok(string_ref) = path_or_file_like.downcast::<PyString>(py) {
                return Ok(FileOrFileLike::File(
                    string_ref.to_string_lossy().to_string(),
                ));
            }

            // is a file-like
            match PyFileLikeObject::with_requirements(path_or_file_like, true, false, true, false) {
                Ok(f) => Ok(FileOrFileLike::FileLike(f)),
                Err(e) => Err(e)
            }
        })
    }
}

#[pyfunction]
/// Opens a file or file-like, and reads it to string.
fn accepts_path_or_file_like(
    path_or_file_like: PyObject,
) -> PyResult<String> {
    Python::with_gil(|py| {
        match FileOrFileLike::from_pyobject(path_or_file_like) {
            Ok(f) => match f {
                FileOrFileLike::File(s) => {
                    println!("It's a file! - path {}", s);
                    let mut f = File::open(s)?;
                    let mut string = String::new();

                    let read = f.read_to_string(&mut string);
                    Ok(string)
                }
                FileOrFileLike::FileLike(mut f) => {
                    println!("Its a file-like object");
                    let mut string = String::new();

                    let read = f.read_to_string(&mut string);
                    Ok(string)
                }
            },
            Err(e) => Err(e),
        }
    })
}

#[pymodule]
fn path_or_file_like(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_wrapped(wrap_pyfunction!(accepts_path_or_file_like))?;

    Ok(())
}


# fn main() {}

依赖关系

~3.5–9MB
~88K SLoC