A few words about Rust
Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.
Why write Python modules in Rust?
Python is undoubtedly one of the more powerful programming languages, but there are situations when a faster and more low-level tool is required. For example, calculations in which we care about the fastest possible code execution
Getting started
1. Install Rust and Cargo
On Linux and macOS systems, this is done as follows:
$ curl https://sh.rustup.rs -sSf | sh
On Windows, download and run rustup-init.exe. It will start the installation in a console and present the above message on success.
2. Create new project and edit Cargo.toml
$ cargo new pyrustlib --lib
To your Cargo.toml file you should add cpython dependency, this file should looks like
[package]
name = "pyrustlib"
version = "0.1.0"
edition = "2021"
[lib]
name = "pyrust"
crate-type = ["dylib"]
[dependencies.cpython]
version = "0.7"
features = ["extension-module"]
Let's talk to Python
Next, we’re going to open src/lib.rs and begin editing; this is where the actual code of our library lives.
#[macro_use]
extern crate cpython;
use cpython::{Python, PyResult, PyString};
fn hello_from_rust(_py: Python) -> PyResult<PyString> {
Ok(PyString::new(_py, "Hello from Rust!"))
}
py_module_initializer!(libpyrust, libpyrust, PyInit_libpyrust, |py, m | {
m.add(py, "__doc__", "This module is implemented in Rust")?;
m.add(py, "hello_world", py_fn!(py, hello_from_rust()))?;
Ok(())
});
py_module_initializer
is a macro defined by the cpython crate we imported at the top of our library. The first parameter (‘status’) is the name of our module, the second parameter is the Python2 naming for our module, while the third parameter is for Python3. The last segment of code on the first line (py, m) allows the modification of received module objects.
We then add a docstring and use the py_fn! macro to build the Python version of our function. That’s all there is to it! Save and exit.
Compile the code
Make sure you are in the root directory of the project (where the Cargo.toml file is).
Run the following command to compile the code:
cargo build --release
If the compilation went successfully you will see a new target
directory in the main project directory. You can find the library in target/release, it's named pyrustlib.so
.
Test in python interpreter
The name for import this module in python is name given in py_module_initializer
which in my case is libpyrust
As you can see, our module works properly.
Additional Information
For more advanced usage of cpython I recommend looking through the rust-cpython repo
Conclusion
I really hope you found this tutorial helpful in some way! If you notice any errors or inaccuracies, please drop me a message. I want to invite you to my github, maybe you found something interesting. Thanks for reading!
Top comments (1)
Nice ☺🙂