mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge pull request #4276 from Gelox/main
Add example for calling between rust and python
This commit is contained in:
14
examples/call_between_rust_and_python.py
Normal file
14
examples/call_between_rust_and_python.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from rust_py_module import RustStruct, rust_function
|
||||
|
||||
class PythonPerson:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def python_callback():
|
||||
python_person = PythonPerson("Peter Python")
|
||||
rust_object = rust_function(42, "This is a python string", python_person)
|
||||
print("Printing member 'numbers' from rust struct: ", rust_object.numbers)
|
||||
rust_object.print_in_rust_from_python()
|
||||
|
||||
def take_string(string):
|
||||
print("Calling python function from rust with string: " + string)
|
||||
94
examples/call_between_rust_and_python.rs
Normal file
94
examples/call_between_rust_and_python.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
use rustpython_vm::{
|
||||
pyclass, pymodule, PyObject, PyPayload, PyResult, TryFromBorrowedObject, VirtualMachine,
|
||||
};
|
||||
|
||||
pub(crate) use rust_py_module::make_module;
|
||||
|
||||
pub fn main() {
|
||||
let interp = rustpython_vm::Interpreter::with_init(Default::default(), |vm| {
|
||||
vm.add_native_modules(rustpython_stdlib::get_module_inits());
|
||||
vm.add_native_module("rust_py_module".to_owned(), Box::new(make_module));
|
||||
});
|
||||
|
||||
interp.enter(|vm| {
|
||||
vm.insert_sys_path(vm.new_pyobj("examples"))
|
||||
.expect("add path");
|
||||
|
||||
let module = vm.import("call_between_rust_and_python", None, 0).unwrap();
|
||||
let init_fn = module.get_attr("python_callback", vm).unwrap();
|
||||
vm.invoke(&init_fn, ()).unwrap();
|
||||
|
||||
let take_string_fn = module.get_attr("take_string", vm).unwrap();
|
||||
vm.invoke(
|
||||
&take_string_fn,
|
||||
(String::from("Rust string sent to python"),),
|
||||
)
|
||||
.unwrap();
|
||||
})
|
||||
}
|
||||
|
||||
#[pymodule]
|
||||
mod rust_py_module {
|
||||
use super::*;
|
||||
use rustpython_vm::{builtins::PyList, convert::ToPyObject, PyObjectRef};
|
||||
|
||||
#[pyfunction]
|
||||
fn rust_function(
|
||||
num: i32,
|
||||
s: String,
|
||||
python_person: PythonPerson,
|
||||
_vm: &VirtualMachine,
|
||||
) -> PyResult<RustStruct> {
|
||||
println!(
|
||||
"Calling standalone rust function from python passing args:
|
||||
num: {},
|
||||
string: {},
|
||||
python_person.name: {}",
|
||||
num, s, python_person.name
|
||||
);
|
||||
Ok(RustStruct {
|
||||
numbers: NumVec(vec![1, 2, 3, 4]),
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct NumVec(Vec<i32>);
|
||||
|
||||
impl ToPyObject for NumVec {
|
||||
fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
let list = self.0.into_iter().map(|e| vm.new_pyobj(e)).collect();
|
||||
PyList::new_ref(list, vm.as_ref()).to_pyobject(vm)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
#[pyclass(module = "rust_py_module", name = "RustStruct")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
struct RustStruct {
|
||||
numbers: NumVec,
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
impl RustStruct {
|
||||
#[pygetset]
|
||||
fn numbers(&self) -> NumVec {
|
||||
self.numbers.clone()
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn print_in_rust_from_python(&self) {
|
||||
println!("Calling a rust method from python");
|
||||
}
|
||||
}
|
||||
|
||||
struct PythonPerson {
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl TryFromBorrowedObject for PythonPerson {
|
||||
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
|
||||
let name = obj.get_attr("name", vm)?.try_into_value::<String>(vm)?;
|
||||
Ok(PythonPerson { name })
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user