Skip to content
Rust binding of NumPy C-API
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
tests bump to 0.6.0 (broken) Mar 30, 2019
appveyor.yml Allow *mut ffi::PyObject as an element of PyArray (#91) Dec 22, 2018


Build Status Build status Crate

Rust bindings for the NumPy C-API

API documentation


Note Starting from 0.3, rust-numpy migrated from rust-cpython to pyo3. If you want to use rust-cpython, use version 0.2.1 from

Supported Python version

Currently 3.5, 3.6, 3.7 are supported.

Python2 Support

Version 0.5.0 is the last version that supports Python2.

If you want to compile this library with Python2, please use 0.5.0 from

In addition, you have to add a feature flag in Cargo.toml like

version = "0.5.0"
features = ["python2"]


You can also automatically specify python version in, using setuptools-rust.


Execute a Python program from Rust and get results

name = "numpy-test"

pyo3 = "0.6.0"
numpy = "0.5.0"
extern crate numpy;
extern crate pyo3;
use numpy::{PyArray1, get_array_module};
use pyo3::prelude::{ObjectProtocol, PyResult, Python};
use pyo3::types::PyDict;

fn main() -> Result<(), ()> {
    let gil = Python::acquire_gil();
    main_(gil.python()).map_err(|e| {
        eprintln!("error! :{:?}", e);
        // we can't display python error type via ::std::fmt::Display
        // so print error here manually

fn main_<'py>(py: Python<'py>) -> PyResult<()> {
    let np = py.import("numpy")?;
    let dict = PyDict::new(py);
    dict.set_item("np", np)?;
    let pyarray: &PyArray1<i32> = py
        .eval("np.absolute(np.array([-1, -2, -3], dtype='int32'))", Some(&dict), None)?
    let slice = pyarray.as_slice();
    assert_eq!(slice, &[1, 2, 3]);

Write a Python module in Rust

Please see the example directory for a complete example

name = "rust_ext"
crate-type = ["cdylib"]

numpy = "0.5.0"
ndarray = "0.12"

version = "0.6.0"
features = ["extension-module"]
extern crate ndarray;
extern crate numpy;
extern crate pyo3;

use ndarray::{ArrayD, ArrayViewD, ArrayViewMutD};
use numpy::{IntoPyArray, PyArrayDyn};
use pyo3::prelude::{pymodule, Py, PyModule, PyResult, Python};

fn rust_ext(_py: Python, m: &PyModule) -> PyResult<()> {
    // immutable example
    fn axpy(a: f64, x: ArrayViewD<f64>, y: ArrayViewD<f64>) -> ArrayD<f64> {
        a * &x + &y

    // mutable example (no return)
    fn mult(a: f64, mut x: ArrayViewMutD<f64>) {
        x *= a;

    // wrapper of `axpy`
    #[pyfn(m, "axpy")]
    fn axpy_py(
        py: Python,
        a: f64,
        x: &PyArrayDyn<f64>,
        y: &PyArrayDyn<f64>,
    ) -> Py<PyArrayDyn<f64>> {
        let x = x.as_array();
        let y = y.as_array();
        axpy(a, x, y).into_pyarray(py).to_owned()

    // wrapper of `mult`
    #[pyfn(m, "mult")]
    fn mult_py(_py: Python, a: f64, x: &PyArrayDyn<f64>) -> PyResult<()> {
        let x = x.as_array_mut();
        mult(a, x);



We need your feedback.

Don't hesitate to open issues!


  • v0.5.0

    • Update PyO3 to 0.6
  • v0.4.0

    • Duplicate PyArrayModule and import Numpy API automatically
    • Fix memory leak of IntoPyArray and add ToPyArray crate
    • PyArray has dimension as type parameter. Now it looks like PyArray<T, D>
    • Use ndarray::IntoDimension to specify dimension
    • Python2 support
  • v0.3.1, v0.3.2

    • Just update dependencies
  • v0.3.0

  • v0.2.1

    • NEW: trait IntoPyErr, IntoPyResult for error translation
  • v0.2.0

    • NEW: traits IntoPyArray, ToPyArray
    • MOD: Interface of PyArray creation functions are changed
  • v0.1.1

    • Update documents
  • v0.1.0

    • First Release
    • Expose unsafe interface of Array and UFunc API
You can’t perform that action at this time.