Rust bindings for the Python interpreter
Go to file
Daniel Grunwald 4cb29c14fa Remove hacks for compatibility with old rust versions. The new minimum required version is Rust 1.13.0.
This significantly reduces our #[cfg(feature="nightly")] usage.
2016-12-17 16:05:21 +01:00
examples Fix #10: Windows support. 2016-12-17 15:46:52 +01:00
extensions
python3-sys Fix #10: Windows support. 2016-12-17 15:46:52 +01:00
python27-sys Fix #10: Windows support. 2016-12-17 15:46:52 +01:00
src Remove hacks for compatibility with old rust versions. The new minimum required version is Rust 1.13.0. 2016-12-17 16:05:21 +01:00
tests
.gitignore
.travis.yml Fix #10: Windows support. 2016-12-17 15:46:52 +01:00
Cargo.toml
LICENSE
Makefile
README.md Fix #10: Windows support. 2016-12-17 15:46:52 +01:00
appveyor.yml Fix #10: Windows support. 2016-12-17 15:46:52 +01:00
build.rs

README.md

rust-cpython Build Status

Rust bindings for the python interpreter.


Copyright (c) 2015-2016 Daniel Grunwald. Rust-cpython is licensed under the MIT license. Python is licensed under the Python License.

Supported Python versions:

  • Python 2.7
  • Python 3.3
  • Python 3.4
  • Python 3.5

Supported Rust version:

  • Rust 1.13.0 or later
  • On Windows, we require rustc 1.15.0-nightly

Usage

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

[dependencies]
cpython = { git = "https://github.com/dgrunwald/rust-cpython.git" }

Example program displaying the value of sys.version:

extern crate cpython;

use cpython::{Python, PyDict, PyResult};

fn main() {
    let gil = Python::acquire_gil();
    hello(gil.python()).unwrap();
}

fn hello(py: Python) -> PyResult<()> {
    let sys = py.import("sys")?;
    let version: String = sys.get(py, "version")?.extract(py)?;

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

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

Example library with python bindings:

The following two files will build with cargo build, and will generate a python-compatible library. (On macOS, you will need to rename the output from *.dynlib to *.so)

Cargo.toml:

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

[dependencies]
cpython = { git = "https://github.com/dgrunwald/rust-cpython.git" }

src/lib.rs

#[macro_use] extern crate cpython;

use cpython::{PyResult, Python};

// add bindings to the generated python module
// N.B: names: "rust2py" must be the lib name in Cargo.toml
py_module_initializer!(librust2py, initlibrust2py, PyInit_librust2py, |py, m| {
    try!(m.add(py, "__doc__", "This module is implemented in Rust."));
    try!(m.add(py, "sum_as_string", py_fn!(py, sum_as_string_py(a: i64, b:i64))));
    Ok(())
});

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

// rust-cpython aware function. All of our python interface could be
// declared in a separate module. 
fn sum_as_string_py(_: Python, a:i64, b:i64) -> PyResult<String> {
    let out = sum_as_string(a, b);
    Ok(out)
}