Expand description
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.
The method clone_ref()
(from trait PyClone
) can be used to create additional
references to the same 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.
Python 2.7
The library will use the python3 bindings by default. To use the python2 bindings
you must specific the python27
feature explicitly in your Cargo.toml
.
[dependencies.cpython]
version = "*"
default-features = false
features = ["python27-sys"]
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 rust-cpython library are
also exposed as Python exceptions.
Example
use cpython::{Python, PyDict, PyResult};
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(py, "version")?.extract(py)?;
let locals = PyDict::new(py);
locals.set_item(py, "os", py.import("os")?)?;
let user: String = py.eval("os.getenv('USER') or os.getenv('USERNAME')", None, Some(&locals))?.extract(py)?;
println!("Hello {}, I'm Python {}", user, version);
Ok(())
}
Re-exports
pub use crate::py_class::CompareOp;
Modules
py_argparse!
, py_fn!
and py_method!
.Macros
py_class!
macro invocation generates code that declares a new Python class.
Additionally, it generates a Rust struct of the same name, which allows accessing
instances of that Python class from Rust.Structs
()
in Python.bool
.str
in Python 2, and bytes
in Python 3.dict
.float
object.long
object.
In Python 3.x, represents a Python int
object.
Both PyInt
and PyLong
refer to the same type on Python 3.x.list
.long
object.
In Python 3.x, represents a Python int
object.
Both PyInt
and PyLong
refer to the same type on Python 3.x.None
in Python.set
.PySharedRefCell
owned by a Python object.basestring
in Python 2, and str
in Python 3.basestring
in Python 2, and str
in Python 3.PySharedRefCell
value, not bound to lifetime.