如何在构建和安装到Python之前测试被pyo3包装的Rust函数?
我有一些用Rust写的功能,现在我通过pyo3把它们暴露给Python使用。我想测试一下这些Python函数是否正确地被暴露出来,并且能正确处理Python的数据类型。
我已经有一些测试来验证实际的功能实现(在Rust中)和整体的集成测试(在Python中)。
那么,我该如何在Rust中测试这些pyo3的Python函数呢?
1 个回答
0
这部分内容在pyo3的文档中有介绍,具体可以查看3.4 执行现有的Python代码 - 想在Rust中嵌入Python并使用额外模块?,不过文档里没有完整的示例。
在包含#[pymodule]
和#[pyfunction]
的lib.rs
文件中,你可以添加以下内容:
#[cfg(test)]
mod tests {
use pyo3::exceptions::PyTypeError;
use super::*;
#[test]
fn test_fizzbuzz() {
pyo3::append_to_inittab!(py_fizzbuzzo3);
pyo3::prepare_freethreaded_python();
Python::with_gil(|py| {
let fizzbuzzo3 = py
.import_bound("fizzbuzzo3")
.expect("Failed to import fizzbuzzo3");
let fizzbuzz = fizzbuzzo3
.getattr("fizzbuzz")
.expect("Failed to get fizzbuzz function");
let result: PyResult<String> = match fizzbuzz.call1((1i32,)) {
Ok(r) => r.extract(),
Err(e) => Err(e),
};
let result = result.unwrap();
let expected_result = "1";
assert_eq!(result, expected_result);
});
}
}
pyo3::append_to_inittab!(py_fizzbuzzo3);
这行代码会让同一个文件中的Python模块可用,并且必须在初始化Python解释器之前调用它。let fizzbuzzo3 = py.import_bound("fizzbuzzo3").expect("Failed to import fizzbuzzo3");
这行代码用来导入模块。let fizzbuzz = fizzbuzzo3.getattr("fizzbuzz").expect("Failed to get fizzbuzz function");
这行代码把Python中的函数赋值给一个变量,这样:fizzbuzz.call1((1i32,))
就可以用来调用这个函数了。