|
| 1 | +# Writing Python functions in Rust |
| 2 | + |
| 3 | +In RustPython, it's possible to write functions in Rust and import them into and call them from |
| 4 | +Python. Here's an example: |
| 5 | + |
| 6 | +```rust |
| 7 | +fn rustmod_funct( |
| 8 | + obj: PyObjectRef, |
| 9 | + s: PyStringRef, |
| 10 | + maybe_thing: OptionalArg<i32>, |
| 11 | + vm: &VirtualMachine, |
| 12 | +) -> PyResult<(String, Vec<u8>)> { ... } |
| 13 | +``` |
| 14 | + |
| 15 | +## Parameters |
| 16 | + |
| 17 | +You can use any type that implements [`FromArgs`] as a parameter to your function, which includes |
| 18 | +types that implements [`TryFromObject`]. In our example, we use a standard `PyObjectRef`, a |
| 19 | +`PyStringRef` (which is really just a `PyRef<PyString>`, and `PyRef` implements `TryFromObject`), |
| 20 | +and an `OptionalArg<i32>`, where [`OptionalArg<T>`] gets an optional positional argument. In |
| 21 | +addition, [`TryFromObject`] is implemented for every primitive number type, so you can use those as |
| 22 | +args too. |
| 23 | +[Here is a list of all of the types that implement `TryFromObject`](https://docs.rs/rustpython-vm/0.1.1/rustpython_vm/pyobject/trait.TryFromObject.html#foreign-impls). |
| 24 | + |
| 25 | +## VirtualMachine parameter |
| 26 | + |
| 27 | +You can optionally put a `vm: &VirtualMachine` parameter at the end of the parameter list in order to |
| 28 | +get access to the Python VM. If you're doing anything more than a very simple function, you'll likely |
| 29 | +want this, as it is necessary for creating exception objects; but, if it turns out you didn't use it |
| 30 | +in the function, always remember that you can just remove it. |
| 31 | + |
| 32 | +## Return type |
| 33 | + |
| 34 | +You can put any type that implements [`IntoPyObject`] as the return type of your function, which includes |
| 35 | +many simple Rust types that you'd expect to map cleanly to Python, e.g. `String` -> `str`, `Vec<u8>` -> `bytes`, |
| 36 | +integral primitives -> `int`, `f32,f64` -> float. If you need to return an error from the function, you can |
| 37 | +put any [`IntoPyObject`] type as the `T` in [`PyResult<T>`], and return an `Err(exc)`. (You can create the |
| 38 | +exception using one of the `new_*_error` methods on [`VirtualMachine`]) |
| 39 | + |
| 40 | +[`FromArgs`]: https://docs.rs/rustpython-vm/*/rustpython_vm/function/trait.FromArgs.html |
| 41 | +[`TryFromObject`]: https://docs.rs/rustpython-vm/*/rustpython_vm/pyobject/trait.TryFromObject.html |
| 42 | +[`OptionalArg<T>`]: https://docs.rs/rustpython-vm/*/rustpython_vm/function/enum.OptionalArg.html |
| 43 | +[`IntoPyObject`]: https://docs.rs/rustpython-vm/*/rustpython_vm/pyobject/trait.IntoPyObject.html |
| 44 | +[`PyResult<T>`]: https://docs.rs/rustpython-vm/*/rustpython_vm/pyobject/type.PyResult.html |
| 45 | +[`VirtualMachine`]: https://docs.rs/rustpython-vm/*/rustpython_vm/struct.VirtualMachine.html |
0 commit comments