Merge pull request #2115 from aganders3/pyany-contains

Add 'contains' method to PyAny
This commit is contained in:
David Hewitt 2022-01-20 23:07:40 +00:00 committed by GitHub
commit a0cf823d68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 0 deletions

View File

@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Accept paths in `wrap_pyfunction` and `wrap_pymodule`. [#2081](https://github.com/PyO3/pyo3/pull/2081)
- Add check for correct number of arguments on magic methods. [#2083](https://github.com/PyO3/pyo3/pull/2083)
- `wrap_pyfunction!` can now wrap a `#[pyfunction]` which is implemented in a different Rust module or crate. [#2091](https://github.com/PyO3/pyo3/pull/2091)
- Add `PyAny::contains` method (`in` operator for `PyAny`). [#2115](https://github.com/PyO3/pyo3/pull/2115)
### Changed

View File

@ -682,6 +682,24 @@ impl PyAny {
self.is_instance(T::type_object(self.py()))
}
/// Determines if self contains `value`.
///
/// This is equivalent to the Python expression `value in self`.
#[inline]
pub fn contains<V>(&self, value: V) -> PyResult<bool>
where
V: ToBorrowedObject,
{
let r = value.with_borrowed_ptr(self.py(), |ptr| unsafe {
ffi::PySequence_Contains(self.as_ptr(), ptr)
});
match r {
0 => Ok(false),
1 => Ok(true),
_ => Err(PyErr::fetch(self.py())),
}
}
/// Returns a GIL marker constrained to the lifetime of this type.
#[inline]
pub fn py(&self) -> Python<'_> {
@ -797,4 +815,26 @@ class SimpleClass:
assert!(l.is_instance(PyList::type_object(py)).unwrap());
});
}
#[test]
fn test_any_contains() {
Python::with_gil(|py| {
let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
let ob = v.to_object(py).into_ref(py);
let bad_needle = 7i32.to_object(py);
assert!(!ob.contains(&bad_needle).unwrap());
let good_needle = 8i32.to_object(py);
assert!(ob.contains(&good_needle).unwrap());
let type_coerced_needle = 8f32.to_object(py);
assert!(ob.contains(&type_coerced_needle).unwrap());
let n: u32 = 42;
let bad_haystack = n.to_object(py).into_ref(py);
let irrelevant_needle = 0i32.to_object(py);
assert!(bad_haystack.contains(&irrelevant_needle).is_err());
});
}
}