Merge pull request #3632 from messense/extract-frozen-set
Add support for extracting Rust set types from `frozenset`
This commit is contained in:
commit
24d9113974
|
@ -0,0 +1 @@
|
||||||
|
Add support for extracting Rust set types from `frozenset`.
|
|
@ -18,7 +18,7 @@
|
||||||
//! The required hashbrown version may vary based on the version of PyO3.
|
//! The required hashbrown version may vary based on the version of PyO3.
|
||||||
use crate::{
|
use crate::{
|
||||||
types::set::new_from_iter,
|
types::set::new_from_iter,
|
||||||
types::{IntoPyDict, PyDict, PySet},
|
types::{IntoPyDict, PyDict, PyFrozenSet, PySet},
|
||||||
FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
|
FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
|
||||||
};
|
};
|
||||||
use std::{cmp, hash};
|
use std::{cmp, hash};
|
||||||
|
@ -93,8 +93,16 @@ where
|
||||||
S: hash::BuildHasher + Default,
|
S: hash::BuildHasher + Default,
|
||||||
{
|
{
|
||||||
fn extract(ob: &'source PyAny) -> PyResult<Self> {
|
fn extract(ob: &'source PyAny) -> PyResult<Self> {
|
||||||
let set: &PySet = ob.downcast()?;
|
match ob.downcast::<PySet>() {
|
||||||
set.iter().map(K::extract).collect()
|
Ok(set) => set.iter().map(K::extract).collect(),
|
||||||
|
Err(err) => {
|
||||||
|
if let Ok(frozen_set) = ob.downcast::<PyFrozenSet>() {
|
||||||
|
frozen_set.iter().map(K::extract).collect()
|
||||||
|
} else {
|
||||||
|
Err(PyErr::from(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +181,10 @@ mod tests {
|
||||||
let set = PySet::new(py, &[1, 2, 3, 4, 5]).unwrap();
|
let set = PySet::new(py, &[1, 2, 3, 4, 5]).unwrap();
|
||||||
let hash_set: hashbrown::HashSet<usize> = set.extract().unwrap();
|
let hash_set: hashbrown::HashSet<usize> = set.extract().unwrap();
|
||||||
assert_eq!(hash_set, [1, 2, 3, 4, 5].iter().copied().collect());
|
assert_eq!(hash_set, [1, 2, 3, 4, 5].iter().copied().collect());
|
||||||
|
|
||||||
|
let set = PyFrozenSet::new(py, &[1, 2, 3, 4, 5]).unwrap();
|
||||||
|
let hash_set: hashbrown::HashSet<usize> = set.extract().unwrap();
|
||||||
|
assert_eq!(hash_set, [1, 2, 3, 4, 5].iter().copied().collect());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,9 @@ use std::{cmp, collections, hash};
|
||||||
#[cfg(feature = "experimental-inspect")]
|
#[cfg(feature = "experimental-inspect")]
|
||||||
use crate::inspect::types::TypeInfo;
|
use crate::inspect::types::TypeInfo;
|
||||||
use crate::{
|
use crate::{
|
||||||
types::set::new_from_iter, types::PySet, FromPyObject, IntoPy, PyAny, PyObject, PyResult,
|
types::set::new_from_iter,
|
||||||
Python, ToPyObject,
|
types::{PyFrozenSet, PySet},
|
||||||
|
FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<T, S> ToPyObject for collections::HashSet<T, S>
|
impl<T, S> ToPyObject for collections::HashSet<T, S>
|
||||||
|
@ -53,8 +54,16 @@ where
|
||||||
S: hash::BuildHasher + Default,
|
S: hash::BuildHasher + Default,
|
||||||
{
|
{
|
||||||
fn extract(ob: &'source PyAny) -> PyResult<Self> {
|
fn extract(ob: &'source PyAny) -> PyResult<Self> {
|
||||||
let set: &PySet = ob.downcast()?;
|
match ob.downcast::<PySet>() {
|
||||||
set.iter().map(K::extract).collect()
|
Ok(set) => set.iter().map(K::extract).collect(),
|
||||||
|
Err(err) => {
|
||||||
|
if let Ok(frozen_set) = ob.downcast::<PyFrozenSet>() {
|
||||||
|
frozen_set.iter().map(K::extract).collect()
|
||||||
|
} else {
|
||||||
|
Err(PyErr::from(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "experimental-inspect")]
|
#[cfg(feature = "experimental-inspect")]
|
||||||
|
@ -84,8 +93,16 @@ where
|
||||||
K: FromPyObject<'source> + cmp::Ord,
|
K: FromPyObject<'source> + cmp::Ord,
|
||||||
{
|
{
|
||||||
fn extract(ob: &'source PyAny) -> PyResult<Self> {
|
fn extract(ob: &'source PyAny) -> PyResult<Self> {
|
||||||
let set: &PySet = ob.downcast()?;
|
match ob.downcast::<PySet>() {
|
||||||
set.iter().map(K::extract).collect()
|
Ok(set) => set.iter().map(K::extract).collect(),
|
||||||
|
Err(err) => {
|
||||||
|
if let Ok(frozen_set) = ob.downcast::<PyFrozenSet>() {
|
||||||
|
frozen_set.iter().map(K::extract).collect()
|
||||||
|
} else {
|
||||||
|
Err(PyErr::from(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "experimental-inspect")]
|
#[cfg(feature = "experimental-inspect")]
|
||||||
|
@ -96,7 +113,7 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::PySet;
|
use super::{PyFrozenSet, PySet};
|
||||||
use crate::{IntoPy, PyObject, Python, ToPyObject};
|
use crate::{IntoPy, PyObject, Python, ToPyObject};
|
||||||
use std::collections::{BTreeSet, HashSet};
|
use std::collections::{BTreeSet, HashSet};
|
||||||
|
|
||||||
|
@ -106,6 +123,10 @@ mod tests {
|
||||||
let set = PySet::new(py, &[1, 2, 3, 4, 5]).unwrap();
|
let set = PySet::new(py, &[1, 2, 3, 4, 5]).unwrap();
|
||||||
let hash_set: HashSet<usize> = set.extract().unwrap();
|
let hash_set: HashSet<usize> = set.extract().unwrap();
|
||||||
assert_eq!(hash_set, [1, 2, 3, 4, 5].iter().copied().collect());
|
assert_eq!(hash_set, [1, 2, 3, 4, 5].iter().copied().collect());
|
||||||
|
|
||||||
|
let set = PyFrozenSet::new(py, &[1, 2, 3, 4, 5]).unwrap();
|
||||||
|
let hash_set: HashSet<usize> = set.extract().unwrap();
|
||||||
|
assert_eq!(hash_set, [1, 2, 3, 4, 5].iter().copied().collect());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +136,10 @@ mod tests {
|
||||||
let set = PySet::new(py, &[1, 2, 3, 4, 5]).unwrap();
|
let set = PySet::new(py, &[1, 2, 3, 4, 5]).unwrap();
|
||||||
let hash_set: BTreeSet<usize> = set.extract().unwrap();
|
let hash_set: BTreeSet<usize> = set.extract().unwrap();
|
||||||
assert_eq!(hash_set, [1, 2, 3, 4, 5].iter().copied().collect());
|
assert_eq!(hash_set, [1, 2, 3, 4, 5].iter().copied().collect());
|
||||||
|
|
||||||
|
let set = PyFrozenSet::new(py, &[1, 2, 3, 4, 5]).unwrap();
|
||||||
|
let hash_set: BTreeSet<usize> = set.extract().unwrap();
|
||||||
|
assert_eq!(hash_set, [1, 2, 3, 4, 5].iter().copied().collect());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue