Skip to content

Commit 97fd658

Browse files
authored
Add IntoPy<PyObject> for HashSet and BTreeSet (#865)
1 parent 5e285fd commit 97fd658

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1515

1616
### Added
1717
* `_PyDict_NewPresized`. [#849](https://github.com/PyO3/pyo3/pull/849)
18+
* `IntoPy<PyObject>` for `HashSet` and `BTreeSet`. [#864](https://github.com/PyO3/pyo3/pull/864)
1819

1920
### Fixed
2021
* `__radd__` and other `__r*__` methods now correctly work with operators. [#839](https://github.com/PyO3/pyo3/pull/839)

src/types/set.rs

+49-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
use crate::err::{self, PyErr, PyResult};
55
use crate::internal_tricks::Unsendable;
66
use crate::{
7-
ffi, AsPyPointer, FromPyObject, PyAny, PyNativeType, PyObject, Python, ToBorrowedObject,
8-
ToPyObject,
7+
ffi, AsPyPointer, FromPy, FromPyObject, IntoPy, PyAny, PyNativeType, PyObject, Python,
8+
ToBorrowedObject, ToPyObject,
99
};
1010
use std::cmp;
1111
use std::collections::{BTreeSet, HashSet};
@@ -184,6 +184,22 @@ where
184184
}
185185
}
186186

187+
impl<K, S> FromPy<HashSet<K, S>> for PyObject
188+
where
189+
K: IntoPy<PyObject> + Eq + hash::Hash,
190+
S: hash::BuildHasher + Default,
191+
{
192+
fn from_py(src: HashSet<K, S>, py: Python) -> Self {
193+
let set = PySet::empty(py).expect("Failed to construct empty set");
194+
{
195+
for val in src {
196+
set.add(val.into_py(py)).expect("Failed to add to set");
197+
}
198+
}
199+
set.into()
200+
}
201+
}
202+
187203
impl<'source, K, S> FromPyObject<'source> for HashSet<K, S>
188204
where
189205
K: FromPyObject<'source> + cmp::Eq + hash::Hash,
@@ -195,6 +211,21 @@ where
195211
}
196212
}
197213

214+
impl<K> FromPy<BTreeSet<K>> for PyObject
215+
where
216+
K: IntoPy<PyObject> + cmp::Ord + ToPyObject,
217+
{
218+
fn from_py(src: BTreeSet<K>, py: Python) -> Self {
219+
let set = PySet::empty(py).expect("Failed to construct empty set");
220+
{
221+
for val in src {
222+
set.add(val.into_py(py)).expect("Failed to add to set");
223+
}
224+
}
225+
set.into()
226+
}
227+
}
228+
198229
impl<'source, K> FromPyObject<'source> for BTreeSet<K>
199230
where
200231
K: FromPyObject<'source> + cmp::Ord,
@@ -271,7 +302,7 @@ impl<'a> std::iter::IntoIterator for &'a PyFrozenSet {
271302
#[cfg(test)]
272303
mod test {
273304
use super::{PyFrozenSet, PySet};
274-
use crate::{AsPyRef, ObjectProtocol, PyTryFrom, Python, ToPyObject};
305+
use crate::{AsPyRef, IntoPy, ObjectProtocol, PyObject, PyTryFrom, Python, ToPyObject};
275306
use std::collections::{BTreeSet, HashSet};
276307
use std::iter::FromIterator;
277308

@@ -451,4 +482,19 @@ mod test {
451482
BTreeSet::from_iter([1, 2, 3, 4, 5].iter().copied())
452483
);
453484
}
485+
486+
#[test]
487+
fn test_set_into_py() {
488+
let gil = Python::acquire_gil();
489+
let py = gil.python();
490+
491+
let bt: BTreeSet<u64> = [1, 2, 3, 4, 5].iter().cloned().collect();
492+
let hs: HashSet<u64> = [1, 2, 3, 4, 5].iter().cloned().collect();
493+
494+
let bto: PyObject = bt.clone().into_py(py);
495+
let hso: PyObject = hs.clone().into_py(py);
496+
497+
assert_eq!(bt, bto.extract(py).unwrap());
498+
assert_eq!(hs, hso.extract(py).unwrap());
499+
}
454500
}

0 commit comments

Comments
 (0)