Skip to content

Conversation

mejrs
Copy link
Member

@mejrs mejrs commented Apr 27, 2021

Added some documentation for IntoPy, but not the redirect I was planning on, I'll do that after #1128 lands.

Rendered

Defines a conversion from a Rust type to a Python object.

It functions similarly to std's Into trait,
but requires a GIL token as an argument.
Many functions and traits internal to PyO3 require this trait as a bound,
so a lack of this trait can manifest itself in different error messages.

Examples

With #[pyclass]

The easiest way to implement IntoPy is by exposing a struct as a native Python object
by annotating it with #[pyclass].

use pyo3::prelude::*;

#[pyclass]
struct Number {
	  #[pyo3(get, set)]
  value: i32,
}

Python code will see this as an instance of the Number class with a value attribute.

Conversion to a Python object

However, it may not be desirable to expose the existence of Number to Python code.
IntoPy allows us to define a conversion to an appropriate Python object.

use pyo3::prelude::*;

struct Number {
  value: i32,
}

impl IntoPy<PyObject> for Number {
    fn into_py(self, py: Python) -> PyObject {
        // delegates to i32's IntoPy implementation.
        self.value.into_py(py)
   }
}

Python code will see this as an int object.

Dynamic conversion into Python objects.

It is also possible to return a different Python object depending on some condition.
This is useful for types like enums that can carry different types.

use pyo3::prelude::*;

enum Value {
    Integer(i32),
    String(String),
    None
}

impl IntoPy<PyObject> for Value {
    fn into_py(self, py: Python) -> PyObject {
        match self {
            Self::Integer(val) => val.into_py(py),
            Self::String(val) => val.into_py(py),
            Self::None => py.None()
        }
   }
}

Python code will see this as any of the int, string or None objects.

Copy link
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️ 🚀 This is absolutely brilliant! Thank you so much for writing this!

No nits at all; it's just great 🚀

@davidhewitt davidhewitt merged commit fc6a20f into PyO3:main Apr 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants