diff --git a/guide/src/migration.md b/guide/src/migration.md index fb212743702..75b102d1c40 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -45,23 +45,26 @@ let tup = PyTuple::new(py, [1, 2, 3]);
Click to expand -The `IntoPyDict::into_py_dict_bound` method has been renamed to `IntoPyDict::into_py_dict`. If you implemented `IntoPyDict` for your type, you should implement `into_py_dict` instead of `into_py_dict_bound`. The old name is still available but deprecated. +The `IntoPyDict::into_py_dict_bound` method has been renamed to `IntoPyDict::into_py_dict` and is now fallible. If you implemented `IntoPyDict` for your type, you should implement `into_py_dict` instead of `into_py_dict_bound`. The old name is still available but deprecated. Before: ```rust,ignore # use pyo3::prelude::*; # use pyo3::types::{PyDict, IntoPyDict}; -# use pyo3::types::dict::PyDictItem; -impl IntoPyDict for I +# use std::collections::HashMap; + +struct MyMap(HashMap); + +impl IntoPyDict for MyMap where - T: PyDictItem, - I: IntoIterator, + K: ToPyObject, + V: ToPyObject, { fn into_py_dict_bound(self, py: Python<'_>) -> Bound<'_, PyDict> { - let dict = PyDict::new(py); - for item in self { - dict.set_item(item.key(), item.value()) + let dict = PyDict::new_bound(py); + for (key, value) in self.0 { + dict.set_item(key, value) .expect("Failed to set_item on dict"); } dict @@ -71,22 +74,25 @@ where After: -```rust,ignore +```rust # use pyo3::prelude::*; # use pyo3::types::{PyDict, IntoPyDict}; -# use pyo3::types::dict::PyDictItem; -impl IntoPyDict for I +# use std::collections::HashMap; + +# #[allow(dead_code)] +# struct MyMap(HashMap); + +impl<'py, K, V> IntoPyDict<'py> for MyMap where - T: PyDictItem, - I: IntoIterator, + K: IntoPyObject<'py>, + V: IntoPyObject<'py>, { - fn into_py_dict(self, py: Python<'_>) -> Bound<'_, PyDict> { + fn into_py_dict(self, py: Python<'py>) -> PyResult> { let dict = PyDict::new(py); - for item in self { - dict.set_item(item.key(), item.value()) - .expect("Failed to set_item on dict"); + for (key, value) in self.0 { + dict.set_item(key, value)?; } - dict + Ok(dict) } } ``` diff --git a/newsfragments/4493.changed.md b/newsfragments/4493.changed.md new file mode 100644 index 00000000000..efff3b6fa6e --- /dev/null +++ b/newsfragments/4493.changed.md @@ -0,0 +1 @@ +`IntoPyDict::into_py_dict` is now fallible due to `IntoPyObject` migration. \ No newline at end of file diff --git a/src/types/dict.rs b/src/types/dict.rs index 7e6b5a1a1e1..c4de7bae46a 100644 --- a/src/types/dict.rs +++ b/src/types/dict.rs @@ -588,7 +588,7 @@ where } /// Represents a tuple which can be used as a PyDict item. -pub trait PyDictItem<'py> { +trait PyDictItem<'py> { type K: IntoPyObject<'py>; type V: IntoPyObject<'py>; fn unpack(self) -> (Self::K, Self::V);