Implement new API for PyNone #3684
This commit is contained in:
parent
8f8d4d33fa
commit
5e9d97d1c6
|
@ -108,7 +108,7 @@ After:
|
|||
# use pyo3::prelude::*;
|
||||
Python::with_gil(|py| {
|
||||
// For uses needing a PyObject, add `.into()`
|
||||
let a: PyObject = py.None().into();
|
||||
let a: PyObject = py.None().into_py(py);
|
||||
|
||||
// For uses needing &PyAny, remove `.as_ref(py)`
|
||||
let b: &PyAny = py.None();
|
||||
|
|
|
@ -8,7 +8,7 @@ fn bench_clean_acquire_gil(b: &mut Bencher<'_>) {
|
|||
}
|
||||
|
||||
fn bench_dirty_acquire_gil(b: &mut Bencher<'_>) {
|
||||
let obj: PyObject = Python::with_gil(|py| py.None().into());
|
||||
let obj: PyObject = Python::with_gil(|py| py.None().into_py(py));
|
||||
b.iter_batched(
|
||||
|| {
|
||||
// Clone and drop an object so that the GILPool has work to do.
|
||||
|
|
|
@ -37,7 +37,7 @@ impl IterAwaitable {
|
|||
Ok(v) => Err(PyStopIteration::new_err(v)),
|
||||
Err(err) => Err(err),
|
||||
},
|
||||
_ => Ok(py.None().into()),
|
||||
_ => Ok(py.None().into_py(py)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ pub trait ToPyObject {
|
|||
/// match self {
|
||||
/// Self::Integer(val) => val.into_py(py),
|
||||
/// Self::String(val) => val.into_py(py),
|
||||
/// Self::None => py.None().into(),
|
||||
/// Self::None => py.None().into_py(py),
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
|
@ -266,7 +266,7 @@ where
|
|||
{
|
||||
fn to_object(&self, py: Python<'_>) -> PyObject {
|
||||
self.as_ref()
|
||||
.map_or_else(|| py.None().into(), |val| val.to_object(py))
|
||||
.map_or_else(|| py.None().into_py(py), |val| val.to_object(py))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,7 @@ where
|
|||
T: IntoPy<PyObject>,
|
||||
{
|
||||
fn into_py(self, py: Python<'_>) -> PyObject {
|
||||
self.map_or_else(|| py.None().into(), |val| val.into_py(py))
|
||||
self.map_or_else(|| py.None().into_py(py), |val| val.into_py(py))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -593,6 +593,8 @@ mod test_no_clone {}
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::conversion::IntoPy;
|
||||
use crate::prelude::PyAnyMethods;
|
||||
use crate::{PyObject, Python};
|
||||
|
||||
#[allow(deprecated)]
|
||||
|
@ -629,14 +631,14 @@ mod tests {
|
|||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_from_unchecked() {
|
||||
Python::with_gil(|py| {
|
||||
let list = PyList::new(py, [1, 2, 3]);
|
||||
let val = unsafe { <PyList as PyTryFrom>::try_from_unchecked(list.as_ref()) };
|
||||
assert!(list.is(val));
|
||||
});
|
||||
}
|
||||
// #[test]
|
||||
// fn test_try_from_unchecked() {
|
||||
// Python::with_gil(|py| {
|
||||
// let list = PyList::new(py, [1, 2, 3]);
|
||||
// let val = unsafe { <PyList as PyTryFrom>::try_from_unchecked(list.as_ref()) };
|
||||
// assert!(list.is(val));
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -647,13 +649,13 @@ mod tests {
|
|||
assert_eq!(option.as_ptr(), std::ptr::null_mut());
|
||||
|
||||
let none = py.None();
|
||||
option = Some(none.into());
|
||||
option = Some(none.into_py(py));
|
||||
|
||||
let ref_cnt = none.get_refcnt();
|
||||
let ref_cnt = none.into_py(py).get_refcnt(py);
|
||||
assert_eq!(option.as_ptr(), none.as_ptr());
|
||||
|
||||
// Ensure ref count not changed by as_ptr call
|
||||
assert_eq!(none.get_refcnt(), ref_cnt);
|
||||
assert_eq!(none.into_py(py).get_refcnt(py), ref_cnt);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ impl Coroutine {
|
|||
}
|
||||
// if waker has been waken during future polling, this is roughly equivalent to
|
||||
// `await asyncio.sleep(0)`, so just yield `None`.
|
||||
Ok(py.None().into())
|
||||
Ok(py.None().into_py(py))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ use crate::types::{
|
|||
PyAny, PyDict, PyEllipsis, PyModule, PyNone, PyNotImplemented, PyString, PyType,
|
||||
};
|
||||
use crate::version::PythonVersionInfo;
|
||||
use crate::{ffi, FromPyPointer, IntoPy, Py, PyObject, PyTypeCheck, PyTypeInfo};
|
||||
use crate::{ffi, Borrowed, FromPyPointer, IntoPy, Py, PyObject, PyTypeCheck, PyTypeInfo};
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::marker::PhantomData;
|
||||
use std::os::raw::c_int;
|
||||
|
@ -698,7 +698,7 @@ impl<'py> Python<'py> {
|
|||
/// Gets the Python builtin value `None`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn None(self) -> &'py PyNone {
|
||||
pub fn None(self) -> Borrowed<'py, 'py, PyNone> {
|
||||
PyNone::get(self)
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
#[repr(transparent)]
|
||||
|
@ -10,8 +11,11 @@ pyobject_native_type_extract!(PyNone);
|
|||
impl PyNone {
|
||||
/// Returns the `None` object.
|
||||
#[inline]
|
||||
pub fn get(py: Python<'_>) -> &PyNone {
|
||||
unsafe { py.from_borrowed_ptr(ffi::Py_None()) }
|
||||
pub fn get<'py>(py: Python<'py>) -> Borrowed<'py, 'py, PyNone> {
|
||||
unsafe {
|
||||
let bound = ffi::Py_None().assume_borrowed(py);
|
||||
std::mem::transmute(bound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,29 +36,30 @@ unsafe impl PyTypeInfo for PyNone {
|
|||
|
||||
#[inline]
|
||||
fn is_exact_type_of(object: &PyAny) -> bool {
|
||||
object.is(Self::get(object.py()))
|
||||
let none = Self::get(object.py());
|
||||
object.is(none.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
/// `()` is converted to Python `None`.
|
||||
impl ToPyObject for () {
|
||||
fn to_object(&self, py: Python<'_>) -> PyObject {
|
||||
PyNone::get(py).into()
|
||||
PyNone::get(py).into_py(py)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPy<PyObject> for () {
|
||||
#[inline]
|
||||
fn into_py(self, py: Python<'_>) -> PyObject {
|
||||
PyNone::get(py).into()
|
||||
PyNone::get(py).into_py(py)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::types::any::PyAnyMethods;
|
||||
use crate::types::{PyDict, PyNone};
|
||||
use crate::{IntoPy, PyObject, PyTypeInfo, Python, ToPyObject};
|
||||
|
||||
#[test]
|
||||
fn test_none_is_itself() {
|
||||
Python::with_gil(|py| {
|
||||
|
|
|
@ -556,7 +556,7 @@ mod return_not_implemented {
|
|||
}
|
||||
|
||||
fn __richcmp__(&self, other: PyRef<'_, Self>, _op: CompareOp) -> PyObject {
|
||||
other.py().None().into()
|
||||
other.py().None().into_py(other.py())
|
||||
}
|
||||
|
||||
fn __add__<'p>(slf: PyRef<'p, Self>, _other: PyRef<'p, Self>) -> PyRef<'p, Self> {
|
||||
|
|
|
@ -119,7 +119,7 @@ fn test_polymorphic_container_does_not_accept_other_types() {
|
|||
let setattr = |value: PyObject| p.as_ref(py).setattr("inner", value);
|
||||
|
||||
assert!(setattr(1i32.into_py(py)).is_err());
|
||||
assert!(setattr(py.None().into()).is_err());
|
||||
assert!(setattr(py.None().into_py(py)).is_err());
|
||||
assert!(setattr((1i32, 2i32).into_py(py)).is_err());
|
||||
});
|
||||
}
|
||||
|
|
|
@ -352,7 +352,7 @@ fn test_enum() {
|
|||
_ => panic!("Expected extracting Foo::TransparentTuple, got {:?}", f),
|
||||
}
|
||||
let none = py.None();
|
||||
let f = Foo::extract(none).expect("Failed to extract Foo from int");
|
||||
let f = Foo::extract_bound(none.as_ref()).expect("Failed to extract Foo from int");
|
||||
match f {
|
||||
Foo::TransparentStructVar { a } => assert!(a.is_none()),
|
||||
_ => panic!("Expected extracting Foo::TransparentStructVar, got {:?}", f),
|
||||
|
|
|
@ -89,7 +89,7 @@ impl GcIntegration {
|
|||
|
||||
fn __clear__(&mut self) {
|
||||
Python::with_gil(|py| {
|
||||
self.self_ref = py.None().into();
|
||||
self.self_ref = py.None().into_py(py);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ fn gc_integration() {
|
|||
let inst = PyCell::new(
|
||||
py,
|
||||
GcIntegration {
|
||||
self_ref: py.None().into(),
|
||||
self_ref: py.None().into_py(py),
|
||||
dropped: TestDropCall {
|
||||
drop_called: Arc::clone(&drop_called),
|
||||
},
|
||||
|
@ -287,7 +287,7 @@ struct PartialTraverse {
|
|||
impl PartialTraverse {
|
||||
fn new(py: Python<'_>) -> Self {
|
||||
Self {
|
||||
member: py.None().into(),
|
||||
member: py.None().into_py(py),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ struct PanickyTraverse {
|
|||
impl PanickyTraverse {
|
||||
fn new(py: Python<'_>) -> Self {
|
||||
Self {
|
||||
member: py.None().into(),
|
||||
member: py.None().into_py(py),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
|
||||
#![cfg(feature = "macros")]
|
||||
|
||||
use pyo3::IntoPy;
|
||||
|
||||
#[pyo3::pyfunction]
|
||||
#[pyo3(name = "identity", signature = (x = None))]
|
||||
fn basic_function(py: pyo3::Python<'_>, x: Option<pyo3::PyObject>) -> pyo3::PyObject {
|
||||
x.unwrap_or_else(|| py.None().into())
|
||||
x.unwrap_or_else(|| py.None().into_py(py))
|
||||
}
|
||||
|
||||
#[pyo3::pymodule]
|
||||
|
|
Loading…
Reference in New Issue