[−][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 #[pymodinit]
. By default the function name will become the module name,
but you can override that with #[pymodinit(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.
m
: The module name.- name of function visible to Python code.
- 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. #[pymodinit] 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 |
|
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 |
Macros
import_exception | Defines rust type for exception defined in Python code. |
int_convert_bignum | |
int_fits_larger_int | |
py_exception | Defines a new exception type. |
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. |
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 |
Py | Safe wrapper around unsafe |
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 |
Traits
AsPyRef | Trait implements object reference extraction from python managed pointer. |
FromPyObject |
|
IntoPyObject | Conversion trait that allows various objects to be converted into |
IntoPyTuple | Conversion trait that allows various objects to be converted into |
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 |
PyTryFrom | Trait implemented by Python object types that allow a checked downcast.
This trait is similar to |
PyTryInto | Trait implemented by Python object types that allow a checked downcast.
This trait is similar to |
ReturnTypeIntoPyResult | This trait wraps a T: IntoPyObject into 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 |
Functions
prepare_freethreaded_python | Prepares the use of Python in a free-threaded context. |
Type Definitions
PyResult | Represents the result of a Python call. |