From 5e75dfa9f77b323e13aaade34c50b3b6dd74352a Mon Sep 17 00:00:00 2001 From: mejrs Date: Tue, 27 Apr 2021 15:56:49 +0200 Subject: [PATCH 1/2] documentation for IntoPy --- src/conversion.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/src/conversion.rs b/src/conversion.rs index ae703213346..52eba8a3c48 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -134,10 +134,73 @@ where } } -/// Similar to [std::convert::Into], just that it requires a gil token. +/// Defines a conversion from a Rust type to a Python object. /// -/// `IntoPy` (aka `IntoPy>`) should be implemented to define a conversion from -/// Rust to Python which can be used by most of PyO3's methods. +/// It functions similarly to std's [`Into`](std::convert::Into) trait, +/// but requires a [GIL token](Python) 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]`](crate::prelude::pyclass). +/// +/// ```rust +/// 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. +/// ```rust +/// use pyo3::prelude::*; +/// +/// struct Number { +/// value: i32, +/// } +/// +/// impl IntoPy 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. +/// +/// ```rust +/// use pyo3::prelude::*; +/// +/// enum Value { +/// Integer(i32), +/// String(String), +/// None +/// } +/// +/// impl IntoPy 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. pub trait IntoPy: Sized { /// Performs the conversion. fn into_py(self, py: Python) -> T; From 3691bf29a59c697ac7ffe690c512f56ce1be2822 Mon Sep 17 00:00:00 2001 From: mejrs Date: Tue, 27 Apr 2021 21:16:39 +0200 Subject: [PATCH 2/2] fixed tabs in doc comment --- src/conversion.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/conversion.rs b/src/conversion.rs index 52eba8a3c48..5ec8a8e0edc 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -151,8 +151,8 @@ where /// /// #[pyclass] /// struct Number { -/// #[pyo3(get, set)] -/// value: i32, +/// #[pyo3(get, set)] +/// value: i32, /// } /// ``` /// Python code will see this as an instance of the `Number` class with a `value` attribute. @@ -177,7 +177,7 @@ where /// ``` /// Python code will see this as an `int` object. /// -/// ## Dynamic conversion into Python objects. +/// ## 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. /// @@ -189,7 +189,7 @@ where /// String(String), /// None /// } -/// +/// /// impl IntoPy for Value { /// fn into_py(self, py: Python) -> PyObject { /// match self {