Macro cpython::py_module_initializer[][src]

macro_rules! py_module_initializer {
    ($name: ident, $( $_py2: ident, $_py3: ident, )? |$py_id: ident, $m_id: ident| $body: tt) => { ... };
}

Expands to an extern "C" function that allows Python to load the rust code as a Python extension module.

Macro syntax: py_module_initializer!($name, |$py, $m| $body)

  1. name: The module name as a Rust identifier.
  2. A lambda of type Fn(Python, &PyModule) -> PyResult<()>. This function will be called when the module is imported, and is responsible for adding the module's members.

For backwards compatibilty with older versions of rust-cpython, two additional name identifiers (for py2 and py3 initializer names) can be provided, but they will be ignored.

Example

use cpython::{Python, PyResult, PyObject, py_module_initializer, py_fn};

py_module_initializer!(hello, |py, m| {
    m.add(py, "__doc__", "Module documentation string")?;
    m.add(py, "run", py_fn!(py, run()))?;
    Ok(())
});

fn run(py: Python) -> PyResult<PyObject> {
    println!("Rust says: Hello Python!");
    Ok(py.None())
}

In your Cargo.toml, use the extension-module feature for the cpython dependency:

[dependencies.cpython]
version = "*"
features = ["extension-module"]

The full example project can be found at: https://github.com/dgrunwald/rust-cpython/tree/master/extensions/hello

Rust will compile the code into a file named libhello.so, but we have to rename the file in order to use it with Python:

cp ./target/debug/libhello.so ./hello.so

(Note: on Mac OS you will have to rename libhello.dynlib to libhello.so)

The extension module can then be imported into Python:

>>> import hello
>>> hello.run()
Rust says: Hello Python!