Skip to content

Commit

Permalink
Add PyFrozenSet.add()
Browse files Browse the repository at this point in the history
  • Loading branch information
adriangb committed May 16, 2023
1 parent 8ab3f5f commit 2de6104
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
1 change: 1 addition & 0 deletions newsfragments/3156.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `PyFrozenSet.add()`, which is a valid operations at the C ABI level according to the [C API docs for sets](https://docs.python.org/3/c-api/set.html)
25 changes: 25 additions & 0 deletions src/types/frozenset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,22 @@ impl PyFrozenSet {
}
}

/// Adds an element to the set.
/// # Safety
///
/// This is marked as unsafe because mutating a frozenset, which is conceptually immutable,
/// could be dangerous, even if it is allowed at the Python C ABI level.
/// You should only use this function if you are sure there are no other references to this frozenset.
pub unsafe fn add<K>(&self, key: K) -> PyResult<()>
where
K: ToPyObject,
{
err::error_on_minusone(
self.py(),
ffi::PySet_Add(self.as_ptr(), key.to_object(self.py()).as_ptr()),
)
}

/// Returns an iterator of values in this frozen set.
pub fn iter(&self) -> PyFrozenSetIterator<'_> {
IntoIterator::into_iter(self)
Expand Down Expand Up @@ -222,6 +238,15 @@ mod tests {
});
}

#[test]
fn test_frozenset_add() {
Python::with_gil(|py| {
let set = PyFrozenSet::new(py, &[1, 2]).unwrap();
unsafe { set.add(1).unwrap() }; // Add a dupliated element
assert!(set.contains(1).unwrap());
});
}

#[test]
fn test_frozenset_iter() {
Python::with_gil(|py| {
Expand Down
16 changes: 8 additions & 8 deletions src/types/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,6 @@ impl PySet {
unsafe { py.from_owned_ptr_or_err(ffi::PySet_New(ptr::null_mut())) }
}

/// Removes all elements from the set.
#[inline]
pub fn clear(&self) {
unsafe {
ffi::PySet_Clear(self.as_ptr());
}
}

/// Returns the number of items in the set.
///
/// This is equivalent to the Python expression `len(self)`.
Expand Down Expand Up @@ -116,6 +108,14 @@ impl PySet {
}
}

/// Removes all elements from the set.
#[inline]
pub fn clear(&self) {
unsafe {
ffi::PySet_Clear(self.as_ptr());
}
}

/// Returns an iterator of values in this set.
///
/// # Panics
Expand Down

0 comments on commit 2de6104

Please sign in to comment.