Skip to content
 
 

Repository files navigation

PyO3

Build Status Build Status codecov crates.io Join the dev chat

Rust bindings for the Python interpreter. This includes running and interacting with python code from a rust binaries as well as writing native python modules.

A comparison with rust-cpython can be found in the guide.

Usage

Pyo3 supports python 2.7 as well as python 3.5 and up. The minimum required rust version is 1.27.0-nightly 2018-05-01.

From a rust binary

To use pyo3, add this to your Cargo.toml:

[dependencies]
pyo3 = "0.2"

Example program displaying the value of sys.version:

#![feature(proc_macro, specialization)]

extern crate pyo3;

use pyo3::prelude::*;

fn main() -> PyResult<()> {
    let gil = Python::acquire_gil();
    let py = gil.python();
    let sys = py.import("sys")?;
    let version: String = sys.get("version")?.extract()?;

    let locals = PyDict::new(py);
    locals.set_item("os", py.import("os")?)?;
    let user: String = py.eval("os.getenv('USER') or os.getenv('USERNAME')", None, Some(&locals))?.extract()?;

    println!("Hello {}, I'm Python {}", user, version);
    Ok(())
}

As native module

Pyo3 can be used to generate a python-compatible library.

Cargo.toml:

[package]
name = "rust2py"
version = "0.1.0"

[lib]
name = "rust2py"
crate-type = ["cdylib"]

[dependencies.pyo3]
version = "0.2"
features = ["extension-module"]

src/lib.rs

#![feature(proc_macro, specialization)]

extern crate pyo3;
use pyo3::prelude::*;

use pyo3::py::modinit;

// Add bindings to the generated python module
// N.B: names: "librust2py" must be the name of the `.so` or `.pyd` file
/// This module is implemented in Rust.
#[modinit(rust2py)]
fn init_mod(py: Python, m: &PyModule) -> PyResult<()> {

    #[pyfn(m, "sum_as_string")]
    // ``#[pyfn()]` converts the arguments from Python objects to Rust values
    // and the Rust return value back into a Python object.
    fn sum_as_string_py(a:i64, b:i64) -> PyResult<String> {
       let out = sum_as_string(a, b);
       Ok(out)
    }

    Ok(())
}

// The logic can be implemented as a normal rust function
fn sum_as_string(a:i64, b:i64) -> String {
    format!("{}", a + b).to_string()
}

To build: cargo rustc --release

On a Mac: cargo rustc --release -- -C link-arg=-undefined -C link-arg=dynamic_lookup

Also on macOS, you will need to rename the output from *.dylib to *.so. On Windows, you will need to rename the output from *.dll to *.pyd.

setuptools-rust can be used to generate a python package and includes the commands above by default. See examples/word-count and the associated setup.py.

License

PyO3 is licensed under the Apache-2.0 license. Python is licensed under the Python License.

About

Rust bindings for the Python interpreter

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages