Skip to content

Commit

Permalink
set & frozenset bound constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Jan 16, 2024
1 parent bfabfb0 commit 220ee43
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 22 deletions.
46 changes: 34 additions & 12 deletions src/types/frozenset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use crate::ffi_ptr_ext::FfiPtrExt;
use crate::types::PyIterator;
use crate::{
err::{self, PyErr, PyResult},
ffi, Bound, Py, PyAny, PyNativeType, PyObject, Python, ToPyObject,
ffi,
py_result_ext::PyResultExt,
types::any::PyAnyMethods,
Bound, PyAny, PyNativeType, PyObject, Python, ToPyObject,
};
use std::ptr;

Expand Down Expand Up @@ -63,20 +66,37 @@ pyobject_native_type_core!(
);

impl PyFrozenSet {
/// Deprecated form of [`PyFrozenSet::new_bound`].
pub fn new<'a, 'p, T: ToPyObject + 'a>(
py: Python<'p>,
elements: impl IntoIterator<Item = &'a T>,
) -> PyResult<&'p PyFrozenSet> {
Self::new_bound(py, elements).map(Bound::into_gil_ref)
}

/// Creates a new frozenset.
///
/// May panic when running out of memory.
#[inline]
pub fn new<'a, 'p, T: ToPyObject + 'a>(
pub fn new_bound<'a, 'p, T: ToPyObject + 'a>(
py: Python<'p>,
elements: impl IntoIterator<Item = &'a T>,
) -> PyResult<&'p PyFrozenSet> {
new_from_iter(py, elements).map(|set| set.into_ref(py))
) -> PyResult<Bound<'p, PyFrozenSet>> {
new_from_iter(py, elements)
}

/// Deprecated form of [`PyFrozenSet::empty_bound`].
pub fn empty(py: Python<'_>) -> PyResult<&'_ PyFrozenSet> {
Self::empty_bound(py).map(Bound::into_gil_ref)
}

/// Creates a new empty frozen set
pub fn empty(py: Python<'_>) -> PyResult<&PyFrozenSet> {
unsafe { py.from_owned_ptr_or_err(ffi::PyFrozenSet_New(ptr::null_mut())) }
pub fn empty_bound(py: Python<'_>) -> PyResult<Bound<'_, PyFrozenSet>> {
unsafe {
ffi::PyFrozenSet_New(ptr::null_mut())
.assume_owned_or_err(py)
.downcast_into_unchecked()
}
}

/// Return the number of items in the set.
Expand Down Expand Up @@ -285,14 +305,16 @@ pub use impl_::*;
pub(crate) fn new_from_iter<T: ToPyObject>(
py: Python<'_>,
elements: impl IntoIterator<Item = T>,
) -> PyResult<Py<PyFrozenSet>> {
fn inner(
py: Python<'_>,
) -> PyResult<Bound<'_, PyFrozenSet>> {
fn inner<'py>(
py: Python<'py>,
elements: &mut dyn Iterator<Item = PyObject>,
) -> PyResult<Py<PyFrozenSet>> {
let set: Py<PyFrozenSet> = unsafe {
) -> PyResult<Bound<'py, PyFrozenSet>> {
let set = unsafe {
// We create the `Py` pointer because its Drop cleans up the set if user code panics.
Py::from_owned_ptr_or_err(py, ffi::PyFrozenSet_New(std::ptr::null_mut()))?
ffi::PyFrozenSet_New(std::ptr::null_mut())
.assume_owned_or_err(py)?
.downcast_into_unchecked()
};
let ptr = set.as_ptr();

Expand Down
45 changes: 35 additions & 10 deletions src/types/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use crate::{
err::{self, PyErr, PyResult},
ffi_ptr_ext::FfiPtrExt,
instance::Bound,
Py, PyNativeType,
py_result_ext::PyResultExt,
types::any::PyAnyMethods,
PyNativeType,
};
use crate::{ffi, PyAny, PyObject, Python, ToPyObject};
use std::ptr;
Expand All @@ -29,20 +31,38 @@ pyobject_native_type_core!(
);

impl PySet {
/// Deprecated form of [`PySet::new_bound`].
#[inline]
pub fn new<'a, 'p, T: ToPyObject + 'a>(
py: Python<'p>,
elements: impl IntoIterator<Item = &'a T>,
) -> PyResult<&'p PySet> {
Self::new_bound(py, elements).map(Bound::into_gil_ref)
}

/// Creates a new set with elements from the given slice.
///
/// Returns an error if some element is not hashable.
#[inline]
pub fn new<'a, 'p, T: ToPyObject + 'a>(
pub fn new_bound<'a, 'p, T: ToPyObject + 'a>(
py: Python<'p>,
elements: impl IntoIterator<Item = &'a T>,
) -> PyResult<&'p PySet> {
new_from_iter(py, elements).map(|set| set.into_ref(py))
) -> PyResult<Bound<'p, PySet>> {
new_from_iter(py, elements)
}

/// Deprecated form of [`PySet::empty_bound`].
pub fn empty(py: Python<'_>) -> PyResult<&'_ PySet> {
Self::empty_bound(py).map(Bound::into_gil_ref)
}

/// Creates a new empty set.
pub fn empty(py: Python<'_>) -> PyResult<&PySet> {
unsafe { py.from_owned_ptr_or_err(ffi::PySet_New(ptr::null_mut())) }
pub fn empty_bound(py: Python<'_>) -> PyResult<Bound<'_, PySet>> {
unsafe {
ffi::PySet_New(ptr::null_mut())
.assume_owned_or_err(py)
.downcast_into_unchecked()
}
}

/// Removes all elements from the set.
Expand Down Expand Up @@ -379,11 +399,16 @@ pub use impl_::*;
pub(crate) fn new_from_iter<T: ToPyObject>(
py: Python<'_>,
elements: impl IntoIterator<Item = T>,
) -> PyResult<Py<PySet>> {
fn inner(py: Python<'_>, elements: &mut dyn Iterator<Item = PyObject>) -> PyResult<Py<PySet>> {
let set: Py<PySet> = unsafe {
) -> PyResult<Bound<'_, PySet>> {
fn inner<'py>(
py: Python<'py>,
elements: &mut dyn Iterator<Item = PyObject>,
) -> PyResult<Bound<'py, PySet>> {
let set = unsafe {
// We create the `Py` pointer because its Drop cleans up the set if user code panics.
Py::from_owned_ptr_or_err(py, ffi::PySet_New(std::ptr::null_mut()))?
ffi::PySet_New(std::ptr::null_mut())
.assume_owned_or_err(py)?
.downcast_into_unchecked()
};
let ptr = set.as_ptr();

Expand Down

0 comments on commit 220ee43

Please sign in to comment.