Merge pull request #3793 from snuderl/PyNone-new-api

Implement new API for PyNone #3684
This commit is contained in:
David Hewitt 2024-02-04 14:20:32 +00:00 committed by GitHub
commit cd9c21f89f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 30 additions and 11 deletions

View file

@ -118,7 +118,7 @@ impl Coroutine {
} }
// if waker has been waken during future polling, this is roughly equivalent to // if waker has been waken during future polling, this is roughly equivalent to
// `await asyncio.sleep(0)`, so just yield `None`. // `await asyncio.sleep(0)`, so just yield `None`.
Ok(py.None().into()) Ok(py.None().into_py(py))
} }
} }

View file

@ -699,7 +699,7 @@ impl<'py> Python<'py> {
#[allow(non_snake_case)] // the Python keyword starts with uppercase #[allow(non_snake_case)] // the Python keyword starts with uppercase
#[inline] #[inline]
pub fn None(self) -> PyObject { pub fn None(self) -> PyObject {
PyNone::get(self).into() PyNone::get_bound(self).into_py(self)
} }
/// Gets the Python builtin value `Ellipsis`, or `...`. /// Gets the Python builtin value `Ellipsis`, or `...`.

View file

@ -1,4 +1,5 @@
use crate::{ffi, IntoPy, PyAny, PyObject, PyTypeInfo, Python, ToPyObject}; use crate::ffi_ptr_ext::FfiPtrExt;
use crate::{ffi, Borrowed, IntoPy, PyAny, PyObject, PyTypeInfo, Python, ToPyObject};
/// Represents the Python `None` object. /// Represents the Python `None` object.
#[repr(transparent)] #[repr(transparent)]
@ -9,10 +10,24 @@ pyobject_native_type_extract!(PyNone);
impl PyNone { impl PyNone {
/// Returns the `None` object. /// Returns the `None` object.
/// Deprecated form of [`PyNone::get_bound`]
#[cfg_attr(
not(feature = "gil-refs"),
deprecated(
since = "0.21.0",
note = "`PyNone::get` will be replaced by `PyBool::get_bound` in a future PyO3 version"
)
)]
#[inline] #[inline]
pub fn get(py: Python<'_>) -> &PyNone { pub fn get(py: Python<'_>) -> &PyNone {
unsafe { py.from_borrowed_ptr(ffi::Py_None()) } unsafe { py.from_borrowed_ptr(ffi::Py_None()) }
} }
/// Returns the `None` object.
#[inline]
pub fn get_bound(py: Python<'_>) -> Borrowed<'_, '_, PyNone> {
unsafe { ffi::Py_None().assume_borrowed(py).downcast_unchecked() }
}
} }
unsafe impl PyTypeInfo for PyNone { unsafe impl PyTypeInfo for PyNone {
@ -32,48 +47,52 @@ unsafe impl PyTypeInfo for PyNone {
#[inline] #[inline]
fn is_exact_type_of(object: &PyAny) -> bool { fn is_exact_type_of(object: &PyAny) -> bool {
object.is(Self::get(object.py())) let none = Self::get_bound(object.py());
object.is(none.as_ref())
} }
} }
/// `()` is converted to Python `None`. /// `()` is converted to Python `None`.
impl ToPyObject for () { impl ToPyObject for () {
fn to_object(&self, py: Python<'_>) -> PyObject { fn to_object(&self, py: Python<'_>) -> PyObject {
PyNone::get(py).into() PyNone::get_bound(py).into_py(py)
} }
} }
impl IntoPy<PyObject> for () { impl IntoPy<PyObject> for () {
#[inline] #[inline]
fn into_py(self, py: Python<'_>) -> PyObject { fn into_py(self, py: Python<'_>) -> PyObject {
PyNone::get(py).into() PyNone::get_bound(py).into_py(py)
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::types::any::PyAnyMethods;
use crate::types::{PyDict, PyNone}; use crate::types::{PyDict, PyNone};
use crate::{IntoPy, PyObject, PyTypeInfo, Python, ToPyObject}; use crate::{IntoPy, PyObject, PyTypeInfo, Python, ToPyObject};
#[test] #[test]
fn test_none_is_itself() { fn test_none_is_itself() {
Python::with_gil(|py| { Python::with_gil(|py| {
assert!(PyNone::get(py).is_instance_of::<PyNone>()); assert!(PyNone::get_bound(py).is_instance_of::<PyNone>());
assert!(PyNone::get(py).is_exact_instance_of::<PyNone>()); assert!(PyNone::get_bound(py).is_exact_instance_of::<PyNone>());
}) })
} }
#[test] #[test]
fn test_none_type_object_consistent() { fn test_none_type_object_consistent() {
Python::with_gil(|py| { Python::with_gil(|py| {
assert!(PyNone::get(py).get_type().is(PyNone::type_object(py))); assert!(PyNone::get_bound(py).get_type().is(PyNone::type_object(py)));
}) })
} }
#[test] #[test]
fn test_none_is_none() { fn test_none_is_none() {
Python::with_gil(|py| { Python::with_gil(|py| {
assert!(PyNone::get(py).downcast::<PyNone>().unwrap().is_none()); assert!(PyNone::get_bound(py)
.downcast::<PyNone>()
.unwrap()
.is_none());
}) })
} }