diff --git a/newsfragments/3657.changed.md b/newsfragments/3657.changed.md new file mode 100644 index 00000000000..0a519b09d62 --- /dev/null +++ b/newsfragments/3657.changed.md @@ -0,0 +1 @@ +Changed `.is_true` to `.is_truthy` on `PyAny` and `Py` to clarify that the test is not based on identity with or equality to the True singleton. diff --git a/src/instance.rs b/src/instance.rs index 1c0fdbcb596..3ec2a3f807e 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -787,7 +787,15 @@ impl Py { /// Returns whether the object is considered to be true. /// /// This is equivalent to the Python expression `bool(self)`. + #[deprecated(since = "0.21.0", note = "use `.is_truthy()` instead")] pub fn is_true(&self, py: Python<'_>) -> PyResult { + self.is_truthy(py) + } + + /// Returns whether the object is considered to be true. + /// + /// This applies truth value testing equivalent to the Python expression `bool(self)`. + pub fn is_truthy(&self, py: Python<'_>) -> PyResult { let v = unsafe { ffi::PyObject_IsTrue(self.as_ptr()) }; err::error_on_minusone(py, v)?; Ok(v != 0) diff --git a/src/types/any.rs b/src/types/any.rs index 23548265c54..f6c5ef1414b 100644 --- a/src/types/any.rs +++ b/src/types/any.rs @@ -306,7 +306,7 @@ impl PyAny { /// Python::with_gil(|py| -> PyResult<()> { /// let a: &PyInt = 0_u8.into_py(py).into_ref(py).downcast()?; /// let b: &PyInt = 42_u8.into_py(py).into_ref(py).downcast()?; - /// assert!(a.rich_compare(b, CompareOp::Le)?.is_true()?); + /// assert!(a.rich_compare(b, CompareOp::Le)?.is_truthy()?); /// Ok(()) /// })?; /// # Ok(())} @@ -640,8 +640,16 @@ impl PyAny { /// Returns whether the object is considered to be true. /// /// This is equivalent to the Python expression `bool(self)`. + #[deprecated(since = "0.21.0", note = "use `.is_truthy()` instead")] pub fn is_true(&self) -> PyResult { - Py2::borrowed_from_gil_ref(&self).is_true() + self.is_truthy() + } + + /// Returns whether the object is considered to be true. + /// + /// This applies truth value testing equivalent to the Python expression `bool(self)`. + pub fn is_truthy(&self) -> PyResult { + Py2::borrowed_from_gil_ref(&self).is_truthy() } /// Returns whether the object is considered to be None. @@ -1165,7 +1173,7 @@ pub(crate) trait PyAnyMethods<'py> { /// Python::with_gil(|py| -> PyResult<()> { /// let a: &PyInt = 0_u8.into_py(py).into_ref(py).downcast()?; /// let b: &PyInt = 42_u8.into_py(py).into_ref(py).downcast()?; - /// assert!(a.rich_compare(b, CompareOp::Le)?.is_true()?); + /// assert!(a.rich_compare(b, CompareOp::Le)?.is_truthy()?); /// Ok(()) /// })?; /// # Ok(())} @@ -1452,7 +1460,7 @@ pub(crate) trait PyAnyMethods<'py> { /// Returns whether the object is considered to be true. /// /// This is equivalent to the Python expression `bool(self)`. - fn is_true(&self) -> PyResult; + fn is_truthy(&self) -> PyResult; /// Returns whether the object is considered to be None. /// @@ -1773,7 +1781,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { let do_compare = |other, op| unsafe { ffi::PyObject_RichCompare(any.as_ptr(), other, op) .assume_owned_or_err(any.py()) - .and_then(|obj| obj.is_true()) + .and_then(|obj| obj.is_truthy()) }; if do_compare(other, ffi::Py_EQ)? { Ok(Ordering::Equal) @@ -1816,7 +1824,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { O: ToPyObject, { self.rich_compare(other, CompareOp::Lt) - .and_then(|any| any.is_true()) + .and_then(|any| any.is_truthy()) } fn le(&self, other: O) -> PyResult @@ -1824,7 +1832,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { O: ToPyObject, { self.rich_compare(other, CompareOp::Le) - .and_then(|any| any.is_true()) + .and_then(|any| any.is_truthy()) } fn eq(&self, other: O) -> PyResult @@ -1832,7 +1840,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { O: ToPyObject, { self.rich_compare(other, CompareOp::Eq) - .and_then(|any| any.is_true()) + .and_then(|any| any.is_truthy()) } fn ne(&self, other: O) -> PyResult @@ -1840,7 +1848,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { O: ToPyObject, { self.rich_compare(other, CompareOp::Ne) - .and_then(|any| any.is_true()) + .and_then(|any| any.is_truthy()) } fn gt(&self, other: O) -> PyResult @@ -1848,7 +1856,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { O: ToPyObject, { self.rich_compare(other, CompareOp::Gt) - .and_then(|any| any.is_true()) + .and_then(|any| any.is_truthy()) } fn ge(&self, other: O) -> PyResult @@ -1856,7 +1864,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { O: ToPyObject, { self.rich_compare(other, CompareOp::Ge) - .and_then(|any| any.is_true()) + .and_then(|any| any.is_truthy()) } fn is_callable(&self) -> bool { @@ -1948,7 +1956,7 @@ impl<'py> PyAnyMethods<'py> for Py2<'py, PyAny> { self.call_method(name, args, None) } - fn is_true(&self) -> PyResult { + fn is_truthy(&self) -> PyResult { let v = unsafe { ffi::PyObject_IsTrue(self.as_ptr()) }; err::error_on_minusone(self.py(), v)?; Ok(v != 0) @@ -2554,7 +2562,7 @@ class SimpleClass: assert!(!py_int .rich_compare(py_str, CompareOp::Eq) .unwrap() - .is_true() + .is_truthy() .unwrap()); }) } diff --git a/tests/test_proto_methods.rs b/tests/test_proto_methods.rs index 6e6d499afa3..b35034513ac 100644 --- a/tests/test_proto_methods.rs +++ b/tests/test_proto_methods.rs @@ -159,9 +159,9 @@ fn test_hash() { fn test_bool() { Python::with_gil(|py| { let example_py = make_example(py); - assert!(example_py.is_true().unwrap()); + assert!(example_py.is_truthy().unwrap()); example_py.borrow_mut().value = 0; - assert!(!example_py.is_true().unwrap()); + assert!(!example_py.is_truthy().unwrap()); }) }