Type Conversions

PyO3 provides some handy traits to convert between Python types and Rust types.

ToPyObject and IntoPyObject trait

ToPyObject trait is a conversion trait that allows various objects to be converted into PyObject. IntoPyObject serves the same purpose except it consumes self.

IntoPyTuple trait

IntoPyTuple trait is a conversion trait that allows various objects to be converted into PyTuple object.

For example, IntoPyTuple trait is implemented for () so that you can convert it into a empty PyTuple

extern crate pyo3;

use pyo3::{Python, IntoPyTuple};

fn main() {
    let gil = Python::acquire_gil();
    let py = gil.python();
    let py_tuple = ().into_tuple(py);
}

FromPyObject and RefFromPyObject trait

*args and **kwargs for python object call

There are several way how to pass positional and keyword arguments to python object call. ObjectProtocol trait provides two methods:

  • call - call callable python object.
  • call_method - call specific method on the object.

Both methods accept args and kwargs arguments. args argument is generate over IntoPyTuple trait. So args could be PyTuple instance or rust tuple with up to 10 elements. Or NoArgs object which represents empty tuple object.

extern crate pyo3;

use pyo3::prelude::*;

fn main() {
    let gil = Python::acquire_gil();
    let py = gil.python();
    
    let obj = SomeObject::new();
    
    // call object without empty arguments
    obj.call(NoArgs, NoArg);
    
    // call object with PyTuple
    let args = PyTuple::new(py, &[arg1, arg2, arg3]);
    obj.call(args, NoArg);

    // pass arguments as rust tuple
    let args = (arg1, arg2, arg3);
    obj.call(args, NoArg);
}

kwargs argument is generate over IntoPyDictPointer trait. HashMap or BTreeMap could be used as keyword arguments. rust tuple with up to 10 elements where each element is tuple with size 2 could be used as kwargs as well. Or NoArgs object can be used to indicate that no keywords arguments are provided.

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

fn main() {
    let gil = Python::acquire_gil();
    let py = gil.python();
    
    let obj = SomeObject::new();
    
    // call object with PyDict
    let kwargs = PyDict::new(py);
    kwargs.set_item(key, value);
    obj.call(NoArg, kwargs);

    // pass arguments as rust tuple
    let kwargs = ((key1, val1), (key2, val2), (key3, val3));
    obj.call(args, kwargs);

    // pass arguments as HashMap
    let mut kwargs = HashMap::<i32, i32>::new();
    kwargs.insert(1, 1);
    obj.call(args, kwargs);
}

TODO