[][src]Crate pyo3

Rust bindings to the Python interpreter.

Ownership and Lifetimes

In Python, all objects are implicitly reference counted. In rust, we will use the PyObject type to represent a reference to a Python object.

Because all Python objects potentially have multiple owners, the concept of Rust mutability does not apply to Python objects. As a result, this API will allow mutating Python objects even if they are not stored in a mutable Rust variable.

The Python interpreter uses a global interpreter lock (GIL) to ensure thread-safety. This API uses a zero-sized struct Python<'p> as a token to indicate that a function can assume that the GIL is held.

You obtain a Python instance by acquiring the GIL, and have to pass it into all operations that call into the Python runtime.

Error Handling

The vast majority of operations in this library will return PyResult<...>. This is an alias for the type Result<..., PyErr>.

A PyErr represents a Python exception. Errors within the PyO3 library are also exposed as Python exceptions.

Example

#![feature(specialization)]

extern crate pyo3;

use pyo3::prelude::*;
use pyo3::types::PyDict;

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 code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
    let user: String = py.eval(code, None, Some(&locals))?.extract()?;

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

Python extension

To allow Python to load the rust code as a Python extension module, you need an initialization function with Fn(Python, &PyModule) -> PyResult<()> that is annotates with #[pymodule]. By default the function name will become the module name, but you can override that with #[pymodule(name)].

To creates a Python callable object that invokes a Rust function, specify rust function and decorate it with #[pyfn()] attribute. pyfn() accepts three parameters.

  1. m: The module name.
  2. name of function visible to Python code.
  3. comma separated arguments, i.e. param="None", "*", param3="55"

Example

#![feature(specialization)]

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

// 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.
#[pymodule]
fn rust2py(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()
}

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

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

On windows and linux, you can build normally with cargo build --release. On Mac Os, you need to set additional linker arguments. One option is to compile with cargo rustc --release -- -C link-arg=-undefined -C link-arg=dynamic_lookup, the other is to create a .cargo/config with the following content:

[target.x86_64-apple-darwin]
rustflags = [
  "-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.

Re-exports

pub use crate::class::*;
pub use crate::python::IntoPyPointer;
pub use crate::python::Python;
pub use crate::python::ToPyPointer;
pub use crate::typeob::PyObjectAlloc;
pub use crate::typeob::PyRawObject;
pub use crate::typeob::PyTypeInfo;
pub use crate::types::exceptions;

Modules

buffer

PyBuffer implementation

class

Python object protocols

ffi

Rust FFI declarations for Python

freelist

Free allocation list

prelude

A collection of items you most likely want to have in scope when working with pyo3

proc_macro

The proc macros, which are also part of the prelude

python
typeob

Python type object information

types

Various types defined by the python interpreter such as int, str and tuple

Macros

create_exception

Defines a new exception type.

create_exception_type_object

impl $crate::typeob::PyTypeObject for $name where $name is an exception newly defined in rust code.

impl_exception_boilerplate

The boilerplate to convert between a rust type and a python exception

import_exception

Defines rust type for exception defined in Python code.

import_exception_type_object

impl $crate::typeob::PyTypeObject for $name where $name is an exception defined in python code.

int_convert_bignum
int_fits_larger_int
pyobject_downcast

Implements a typesafe conversions throught FromPyObject, given a typecheck function as second parameter

pyobject_native_type
pyobject_native_type_convert
pyobject_native_type_named
wrap_function

Returns a function that takes a Python instance and returns a python function.

wrap_module

Returns a function that takes a Python instance and returns a python module.

Structs

GILGuard

RAII type that represents the Global Interpreter Lock acquisition.

NoArgs

An empty struct that represents the empty argument list. Corresponds to the empty tuple () in Python.

Py

Safe wrapper around unsafe *mut ffi::PyObject pointer with specified type information.

PyDowncastError

Marker type that indicates an error while downcasting

PyErr

Represents a Python exception that was raised.

PyObject

A python object

Enums

PyErrValue

Represents a PyErr value

Traits

AsPyRef

Trait implements object reference extraction from python managed pointer.

FromPyObject

FromPyObject is implemented by various types that can be extracted from a Python object reference.

IntoPyObject

Conversion trait that allows various objects to be converted into PyObject by consuming original object.

IntoPyTuple

Conversion trait that allows various objects to be converted into PyTuple object.

ObjectProtocol

Python object model helper methods

PyErrArguments

Helper conversion trait that allows to use custom arguments for exception constructor.

PyObjectWithGIL

Any instance that is managed Python can have access to gil.

PyTryFrom

Trait implemented by Python object types that allow a checked downcast. This trait is similar to std::convert::TryFrom

PyTryInto

Trait implemented by Python object types that allow a checked downcast. This trait is similar to std::convert::TryInto

ReturnTypeIntoPyResult

This trait wraps a T: IntoPyObject into PyResult while PyResult remains PyResult.

ToBorrowedObject

This trait has two implementations: The slow one is implemented for all ToPyObject and creates a new object using ToPyObject::to_object, while the fast one is only implemented for ToPyPointer (we know that every ToPyObject is also ToPyObject) and uses ToPyPointer::as_ptr()

ToPyObject

Conversion trait that allows various objects to be converted into PyObject

Functions

prepare_freethreaded_python

Prepares the use of Python in a free-threaded context.

Type Definitions

PyResult

Represents the result of a Python call.