diff --git a/newsfragments/4305.added.md b/newsfragments/4305.added.md new file mode 100644 index 00000000000..9a00b8fcfd1 --- /dev/null +++ b/newsfragments/4305.added.md @@ -0,0 +1 @@ +Implement `PartialEq` for `Bound<'py, PyBool>`. \ No newline at end of file diff --git a/src/types/boolobject.rs b/src/types/boolobject.rs index 04c1fd4c113..ee19797d66e 100644 --- a/src/types/boolobject.rs +++ b/src/types/boolobject.rs @@ -72,6 +72,86 @@ impl<'py> PyBoolMethods<'py> for Bound<'py, PyBool> { } } +/// Compare `Bound` with `bool`. +impl PartialEq for Bound<'_, PyBool> { + #[inline] + fn eq(&self, other: &bool) -> bool { + self.as_borrowed() == *other + } +} + +/// Compare `&Bound` with `bool`. +impl PartialEq for &'_ Bound<'_, PyBool> { + #[inline] + fn eq(&self, other: &bool) -> bool { + self.as_borrowed() == *other + } +} + +/// Compare `Bound` with `&bool`. +impl PartialEq<&'_ bool> for Bound<'_, PyBool> { + #[inline] + fn eq(&self, other: &&bool) -> bool { + self.as_borrowed() == **other + } +} + +/// Compare `bool` with `Bound` +impl PartialEq> for bool { + #[inline] + fn eq(&self, other: &Bound<'_, PyBool>) -> bool { + *self == other.as_borrowed() + } +} + +/// Compare `bool` with `&Bound` +impl PartialEq<&'_ Bound<'_, PyBool>> for bool { + #[inline] + fn eq(&self, other: &&'_ Bound<'_, PyBool>) -> bool { + *self == other.as_borrowed() + } +} + +/// Compare `&bool` with `Bound` +impl PartialEq> for &'_ bool { + #[inline] + fn eq(&self, other: &Bound<'_, PyBool>) -> bool { + **self == other.as_borrowed() + } +} + +/// Compare `Borrowed` with `bool` +impl PartialEq for Borrowed<'_, '_, PyBool> { + #[inline] + fn eq(&self, other: &bool) -> bool { + self.is_true() == *other + } +} + +/// Compare `Borrowed` with `&bool` +impl PartialEq<&bool> for Borrowed<'_, '_, PyBool> { + #[inline] + fn eq(&self, other: &&bool) -> bool { + self.is_true() == **other + } +} + +/// Compare `bool` with `Borrowed` +impl PartialEq> for bool { + #[inline] + fn eq(&self, other: &Borrowed<'_, '_, PyBool>) -> bool { + *self == other.is_true() + } +} + +/// Compare `&bool` with `Borrowed` +impl PartialEq> for &'_ bool { + #[inline] + fn eq(&self, other: &Borrowed<'_, '_, PyBool>) -> bool { + **self == other.is_true() + } +} + /// Converts a Rust `bool` to a Python `bool`. impl ToPyObject for bool { #[inline] @@ -191,4 +271,63 @@ mod tests { assert!(false.to_object(py).is(&*PyBool::new_bound(py, false))); }); } + + #[test] + fn test_pybool_comparisons() { + Python::with_gil(|py| { + let py_bool = PyBool::new_bound(py, true); + let py_bool_false = PyBool::new_bound(py, false); + let rust_bool = true; + + // Bound<'_, PyBool> == bool + assert_eq!(*py_bool, rust_bool); + assert_ne!(*py_bool_false, rust_bool); + + // Bound<'_, PyBool> == &bool + assert_eq!(*py_bool, &rust_bool); + assert_ne!(*py_bool_false, &rust_bool); + + // &Bound<'_, PyBool> == bool + assert_eq!(&*py_bool, rust_bool); + assert_ne!(&*py_bool_false, rust_bool); + + // &Bound<'_, PyBool> == &bool + assert_eq!(&*py_bool, &rust_bool); + assert_ne!(&*py_bool_false, &rust_bool); + + // bool == Bound<'_, PyBool> + assert_eq!(rust_bool, *py_bool); + assert_ne!(rust_bool, *py_bool_false); + + // bool == &Bound<'_, PyBool> + assert_eq!(rust_bool, &*py_bool); + assert_ne!(rust_bool, &*py_bool_false); + + // &bool == Bound<'_, PyBool> + assert_eq!(&rust_bool, *py_bool); + assert_ne!(&rust_bool, *py_bool_false); + + // &bool == &Bound<'_, PyBool> + assert_eq!(&rust_bool, &*py_bool); + assert_ne!(&rust_bool, &*py_bool_false); + + // Borrowed<'_, '_, PyBool> == bool + assert_eq!(py_bool, rust_bool); + assert_ne!(py_bool_false, rust_bool); + + // Borrowed<'_, '_, PyBool> == &bool + assert_eq!(py_bool, &rust_bool); + assert_ne!(py_bool_false, &rust_bool); + + // bool == Borrowed<'_, '_, PyBool> + assert_eq!(rust_bool, py_bool); + assert_ne!(rust_bool, py_bool_false); + + // &bool == Borrowed<'_, '_, PyBool> + assert_eq!(&rust_bool, py_bool); + assert_ne!(&rust_bool, py_bool_false); + assert_eq!(py_bool, rust_bool); + assert_ne!(py_bool_false, rust_bool); + }) + } }