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.


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()))?;

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

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

version = "*"
features = ["extension-module"]

The full example project can be found at:

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

cp ./target/debug/ ./

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

The extension module can then be imported into Python:

>>> import hello
Rust says: Hello Python!