1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
#![feature(specialization, proc_macro, try_from, fn_must_use)] #![feature(const_fn, const_unsafe_cell_new, const_size_of, const_ptr_null, const_ptr_null_mut)] //! 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 //! //! ```rust //! extern crate pyo3; //! //! use pyo3::{Python, PyDict, PyResult, ObjectProtocol}; //! //! 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("version")?.extract()?; //! //! let locals = PyDict::new(py); //! locals.set_item("os", py.import("os")?)?; //! let user: String = py.eval("os.getenv('USER') or os.getenv('USERNAME')", 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 provide initialization function and annotate it with `#[py::modinit(name)]`. //! `py::modinit` expands to an `extern "C"` function. //! //! Macro syntax: `#[py::modinit(name)]` //! //! 1. `name`: The module name as a Rust identifier //! 2. Decorate init function `Fn(Python, &PyModule) -> PyResult<()>`. //! This function will be called when the module is imported, and is responsible //! for adding the module's members. //! //! 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 //! //! ```rust //! #![feature(proc_macro, specialization)] //! //! extern crate pyo3; //! use pyo3::{py, Python, PyResult, PyModule, PyString}; //! //! // add bindings to the generated python module //! // N.B: names: "libhello" must be the name of the `.so` or `.pyd` file //! //! /// Module documentation string //! #[py::modinit(hello)] //! fn init_module(py: Python, m: &PyModule) -> PyResult<()> { //! //! // pyo3 aware function. All of our python interface could be declared //! // in a separate module. //! // Note that the `#[pyfn()]` annotation automatically converts the arguments from //! // Python objects to Rust values; and the Rust return value back into a Python object. //! #[pyfn(m, "run_rust_func")] //! fn run(name: &PyString) -> PyResult<()> { //! println!("Rust says: Hello {} of Python!", name); //! Ok(()) //! } //! //! Ok(()) //! } //! //! # fn main() {} //! ``` //! //! In your `Cargo.toml`, use the `extension-module` feature for the `pyo3` dependency: //! //! ```cargo //! [dependencies.pyo3] //! version = "*" //! features = ["extension-module"] //! ``` //! //! The full example project can be found at: //! <https://github.com/PyO3/setuptools-rust/tree/master/example/> //! //! 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: //! //! ```bash //! cp ./target/debug/libhello.so ./hello.so //! ``` //! (Note: on macOS you will have to rename `libhello.dynlib` to `libhello.so`) //! //! The extension module can then be imported into Python: //! //! ```python //! >>> import hello //! >>> hello.run_rust_func("test") //! Rust says: Hello Python! //! ``` extern crate libc; extern crate spin; extern crate pyo3cls; #[macro_use] extern crate log; #[cfg(not(Py_3))] mod ffi2; #[cfg(Py_3)] mod ffi3; /// Rust FFI declarations for Python pub mod ffi { #[cfg(not(Py_3))] pub use ffi2::*; #[cfg(Py_3)] pub use ffi3::*; } pub use err::{PyErr, PyErrValue, PyResult, PyDowncastError, PyErrArguments}; pub use objects::*; pub use objectprotocol::ObjectProtocol; pub use object::PyObject; pub use noargs::NoArgs; pub use typeob::{PyTypeInfo, PyRawObject, PyObjectAlloc}; pub use python::{Python, ToPyPointer, IntoPyPointer, IntoPyDictPointer}; pub use pythonrun::{GILGuard, GILPool, prepare_freethreaded_python, prepare_pyo3_library}; pub use instance::{PyToken, PyObjectWithToken, AsPyRef, Py, PyNativeType}; pub use conversion::{FromPyObject, RefFromPyObject, PyTryFrom, PyTryInto, ToPyObject, ToBorrowedObject, IntoPyObject, IntoPyTuple}; pub mod class; pub use class::*; /// Procedural macros pub mod py { pub use pyo3cls::{proto, class, methods}; #[cfg(Py_3)] pub use pyo3cls::mod3init as modinit; #[cfg(not(Py_3))] pub use pyo3cls::mod2init as modinit; } /// Constructs a `&'static CStr` literal. macro_rules! cstr( ($s: tt) => ( // TODO: verify that $s is a string literal without nuls unsafe { ::std::ffi::CStr::from_ptr(concat!($s, "\0").as_ptr() as *const _) } ); ); mod python; mod err; mod conversion; mod instance; mod object; mod objects; mod objectprotocol; mod noargs; mod pythonrun; #[doc(hidden)] pub mod callback; pub mod typeob; #[doc(hidden)] pub mod argparse; pub mod buffer; pub mod freelist; pub mod prelude; // re-export for simplicity #[doc(hidden)] pub use std::os::raw::*;