Writing python extension with rust

To write a python extension in rust, the easiest way is to use maturin.

It supports

To install maturin

pip install maturin

The steps to create a python extension looks like

Now you have the boilerplate code. The src/main.rs looks like

  use pyo3::prelude::*;
  
  /// Formats the sum of two numbers as string.
  #[pyfunction]
  fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
      Ok((a + b).to_string())
  }
  
  /// A Python module implemented in Rust.
  #[pymodule]
  fn temp_(_py: Python, m: &PyModule) -> PyResult<()> {
      m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
      Ok(())
  }

and the Cargo.toml looks like

  [package]
  name = "maturin_ext"
  version = "0.1.0"
  edition = "2021"
  
  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
  [lib]
  name = "maturin_ext"
  crate-type = ["cdylib"]
  
  [dependencies]
  pyo3 = { version = "0.18.0", features = ["extension-module"] }
  cd maturin_ext
  maturin build

This module can be installed with pip

  pip install maturin_ext/target/wheels/maturin_ext-0.1.0-cp311-cp311-manylinux_2_34_x86_64.whl

This way we can use maturin to build and use the python extensions.

A few things to keep in mind. - dynamic linking:

  For portability reasons, native python modules on linux must only dynamically link a set of very few libraries which are installed basically everywhere.
  - source: https://github.com/PyO3/maturin#manylinux-and-auditwheel 

So if your python extension depends upon some other library, you need to make sure it is included in the package (i.e. the whl file).

Also, since python extensions make use of glibc, there could be issues running this package on alpine for python<=3.9.