add as_ptr and into_ptr inherent methods

This commit is contained in:
David Hewitt 2023-07-30 21:58:21 +01:00
parent 1df7270e15
commit 64adab1a76
56 changed files with 199 additions and 94 deletions

View file

@ -351,7 +351,6 @@ that inherit native types. Even in such cases, you can unsafely get a base class
# #[cfg(not(Py_LIMITED_API))] { # #[cfg(not(Py_LIMITED_API))] {
# use pyo3::prelude::*; # use pyo3::prelude::*;
use pyo3::types::PyDict; use pyo3::types::PyDict;
use pyo3::AsPyPointer;
use std::collections::HashMap; use std::collections::HashMap;
#[pyclass(extends=PyDict)] #[pyclass(extends=PyDict)]

View file

@ -421,7 +421,6 @@ Let's create that helper function. The signature has to be `fn(&PyAny) -> PyResu
use std::os::raw::c_ulong; use std::os::raw::c_ulong;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::ffi; use pyo3::ffi;
use pyo3::conversion::AsPyPointer;
fn wrap(obj: &PyAny) -> Result<i32, PyErr> { fn wrap(obj: &PyAny) -> Result<i32, PyErr> {
let py: Python<'_> = obj.py(); let py: Python<'_> = obj.py();

View file

@ -0,0 +1 @@
Add `as_ptr` and `into_ptr` inherent methods for `Py`, `PyAny`, `PyRef`, and `PyRefMut`.

View file

@ -10,6 +10,6 @@ pub(crate) fn ok_wrap(obj: TokenStream) -> TokenStream {
pub(crate) fn map_result_into_ptr(result: TokenStream) -> TokenStream { pub(crate) fn map_result_into_ptr(result: TokenStream) -> TokenStream {
quote! { quote! {
#result.map(_pyo3::IntoPyPointer::into_ptr) #result.map(_pyo3::PyObject::into_ptr)
} }
} }

View file

@ -18,9 +18,7 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
//! `PyBuffer` implementation //! `PyBuffer` implementation
use crate::{ use crate::{err, exceptions::PyBufferError, ffi, FromPyObject, PyAny, PyResult, Python};
err, exceptions::PyBufferError, ffi, AsPyPointer, FromPyObject, PyAny, PyResult, Python,
};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::os::raw; use std::os::raw;
use std::pin::Pin; use std::pin::Pin;

View file

@ -3,7 +3,6 @@
use crate::err::{PyErr, PyResult}; use crate::err::{PyErr, PyResult};
use crate::exceptions::PyOverflowError; use crate::exceptions::PyOverflowError;
use crate::ffi::{self, Py_hash_t}; use crate::ffi::{self, Py_hash_t};
use crate::IntoPyPointer;
use crate::{IntoPy, PyObject, Python}; use crate::{IntoPy, PyObject, Python};
use std::isize; use std::isize;
use std::os::raw::c_int; use std::os::raw::c_int;

View file

@ -20,7 +20,6 @@ use std::ptr::NonNull;
/// ///
/// ```rust /// ```rust
/// use pyo3::prelude::*; /// use pyo3::prelude::*;
/// use pyo3::AsPyPointer;
/// use pyo3::types::PyString; /// use pyo3::types::PyString;
/// use pyo3::ffi; /// use pyo3::ffi;
/// ///
@ -40,7 +39,6 @@ use std::ptr::NonNull;
/// ///
/// ```rust,no_run /// ```rust,no_run
/// # use pyo3::prelude::*; /// # use pyo3::prelude::*;
/// # use pyo3::AsPyPointer;
/// # use pyo3::ffi; /// # use pyo3::ffi;
/// # /// #
/// Python::with_gil(|py| { /// Python::with_gil(|py| {
@ -632,7 +630,7 @@ mod test_no_clone {}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::types::{IntoPyDict, PyAny, PyDict, PyList}; use crate::types::{IntoPyDict, PyAny, PyDict, PyList};
use crate::{AsPyPointer, PyObject, Python, ToPyObject}; use crate::{PyObject, Python, ToPyObject};
use super::PyTryFrom; use super::PyTryFrom;
@ -676,6 +674,7 @@ mod tests {
#[test] #[test]
fn test_option_as_ptr() { fn test_option_as_ptr() {
Python::with_gil(|py| { Python::with_gil(|py| {
use crate::AsPyPointer;
let mut option: Option<PyObject> = None; let mut option: Option<PyObject> = None;
assert_eq!(option.as_ptr(), std::ptr::null_mut()); assert_eq!(option.as_ptr(), std::ptr::null_mut());

View file

@ -45,7 +45,7 @@ use crate::types::{
timezone_utc, PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, PyTime, PyTimeAccess, timezone_utc, PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, PyTime, PyTimeAccess,
PyTzInfo, PyTzInfoAccess, PyUnicode, PyTzInfo, PyTzInfoAccess, PyUnicode,
}; };
use crate::{AsPyPointer, FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject}; use crate::{FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject};
use chrono::offset::{FixedOffset, Utc}; use chrono::offset::{FixedOffset, Utc};
use chrono::{ use chrono::{
DateTime, Datelike, Duration, NaiveDate, NaiveDateTime, NaiveTime, Offset, TimeZone, Timelike, DateTime, Datelike, Duration, NaiveDate, NaiveDateTime, NaiveTime, Offset, TimeZone, Timelike,

View file

@ -48,8 +48,7 @@
//! ``` //! ```
use crate::{ use crate::{
ffi, types::*, AsPyPointer, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ffi, types::*, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject,
ToPyObject,
}; };
use num_bigint::{BigInt, BigUint}; use num_bigint::{BigInt, BigUint};

View file

@ -94,8 +94,7 @@
//! assert result == [complex(1,-1), complex(-2,0)] //! assert result == [complex(1,-1), complex(-2,0)]
//! ``` //! ```
use crate::{ use crate::{
ffi, types::PyComplex, AsPyPointer, FromPyObject, PyAny, PyErr, PyObject, PyResult, Python, ffi, types::PyComplex, FromPyObject, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
ToPyObject,
}; };
use num_complex::Complex; use num_complex::Complex;
use std::os::raw::c_double; use std::os::raw::c_double;

View file

@ -1,4 +1,3 @@
use crate::conversion::{AsPyPointer, IntoPyPointer};
use crate::types::PySequence; use crate::types::PySequence;
use crate::{exceptions, PyErr}; use crate::{exceptions, PyErr};
use crate::{ use crate::{

View file

@ -1,8 +1,7 @@
#[cfg(feature = "experimental-inspect")] #[cfg(feature = "experimental-inspect")]
use crate::inspect::types::TypeInfo; use crate::inspect::types::TypeInfo;
use crate::{ use crate::{
exceptions, ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, exceptions, ffi, FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
ToPyObject,
}; };
use std::convert::TryFrom; use std::convert::TryFrom;
use std::num::{ use std::num::{

View file

@ -1,7 +1,5 @@
use crate::types::PyString; use crate::types::PyString;
use crate::{ use crate::{ffi, FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject};
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject,
};
use std::borrow::Cow; use std::borrow::Cow;
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
#[cfg(not(windows))] #[cfg(not(windows))]

View file

@ -1,6 +1,5 @@
use crate::{ use crate::{
ffi, AsPyPointer, FromPyObject, FromPyPointer, IntoPy, PyAny, PyObject, PyResult, Python, ffi, FromPyObject, FromPyPointer, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject,
ToPyObject,
}; };
use std::borrow::Cow; use std::borrow::Cow;
use std::ffi::OsString; use std::ffi::OsString;

View file

@ -2,7 +2,7 @@ use crate::{
exceptions::{PyBaseException, PyTypeError}, exceptions::{PyBaseException, PyTypeError},
ffi, ffi,
types::{PyTraceback, PyType}, types::{PyTraceback, PyType},
AsPyPointer, IntoPy, IntoPyPointer, Py, PyAny, PyObject, PyTypeInfo, Python, IntoPy, Py, PyAny, PyObject, PyTypeInfo, Python,
}; };
#[derive(Clone)] #[derive(Clone)]
@ -118,12 +118,20 @@ impl PyErrState {
ptype, ptype,
pvalue, pvalue,
ptraceback, ptraceback,
} => (ptype.into_ptr(), pvalue.into_ptr(), ptraceback.into_ptr()), } => (
ptype.into_ptr(),
pvalue.map_or(std::ptr::null_mut(), Py::into_ptr),
ptraceback.map_or(std::ptr::null_mut(), Py::into_ptr),
),
PyErrState::Normalized(PyErrStateNormalized { PyErrState::Normalized(PyErrStateNormalized {
ptype, ptype,
pvalue, pvalue,
ptraceback, ptraceback,
}) => (ptype.into_ptr(), pvalue.into_ptr(), ptraceback.into_ptr()), }) => (
ptype.into_ptr(),
pvalue.into_ptr(),
ptraceback.map_or(std::ptr::null_mut(), Py::into_ptr),
),
} }
} }

View file

@ -5,7 +5,7 @@ use crate::{
exceptions::{self, PyBaseException}, exceptions::{self, PyBaseException},
ffi, ffi,
}; };
use crate::{AsPyPointer, IntoPy, IntoPyPointer, Py, PyAny, PyObject, Python, ToPyObject}; use crate::{IntoPy, Py, PyAny, PyObject, Python, ToPyObject};
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::UnsafeCell; use std::cell::UnsafeCell;
use std::ffi::CString; use std::ffi::CString;
@ -443,7 +443,7 @@ impl PyErr {
self.get_type(py).as_ptr(), self.get_type(py).as_ptr(),
self.value(py).as_ptr(), self.value(py).as_ptr(),
self.traceback(py) self.traceback(py)
.map_or(std::ptr::null_mut(), PyTraceback::as_ptr), .map_or(std::ptr::null_mut(), |traceback| traceback.as_ptr()),
) )
} }
} }
@ -642,7 +642,7 @@ impl PyErr {
// PyException_SetCause _steals_ a reference to cause, so must use .into_ptr() // PyException_SetCause _steals_ a reference to cause, so must use .into_ptr()
ffi::PyException_SetCause( ffi::PyException_SetCause(
value.as_ptr(), value.as_ptr(),
cause.map_or(std::ptr::null_mut(), IntoPyPointer::into_ptr), cause.map_or(std::ptr::null_mut(), Py::into_ptr),
); );
} }
} }

View file

@ -42,7 +42,6 @@ macro_rules! impl_exception_boilerplate {
impl ::std::error::Error for $name { impl ::std::error::Error for $name {
fn source(&self) -> ::std::option::Option<&(dyn ::std::error::Error + 'static)> { fn source(&self) -> ::std::option::Option<&(dyn ::std::error::Error + 'static)> {
unsafe { unsafe {
use $crate::AsPyPointer;
let cause: &$crate::exceptions::PyBaseException = self let cause: &$crate::exceptions::PyBaseException = self
.py() .py()
.from_owned_ptr_or_opt($crate::ffi::PyException_GetCause(self.as_ptr()))?; .from_owned_ptr_or_opt($crate::ffi::PyException_GetCause(self.as_ptr()))?;
@ -101,7 +100,6 @@ macro_rules! import_exception {
impl $name { impl $name {
fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject { fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject {
use $crate::sync::GILOnceCell; use $crate::sync::GILOnceCell;
use $crate::AsPyPointer;
static TYPE_OBJECT: GILOnceCell<$crate::Py<$crate::types::PyType>> = static TYPE_OBJECT: GILOnceCell<$crate::Py<$crate::types::PyType>> =
GILOnceCell::new(); GILOnceCell::new();
@ -240,7 +238,6 @@ macro_rules! create_exception_type_object {
impl $name { impl $name {
fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject { fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject {
use $crate::sync::GILOnceCell; use $crate::sync::GILOnceCell;
use $crate::AsPyPointer;
static TYPE_OBJECT: GILOnceCell<$crate::Py<$crate::types::PyType>> = static TYPE_OBJECT: GILOnceCell<$crate::Py<$crate::types::PyType>> =
GILOnceCell::new(); GILOnceCell::new();

View file

@ -1,5 +1,5 @@
use crate::ffi::*; use crate::ffi::*;
use crate::{AsPyPointer, Python}; use crate::Python;
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
use crate::{ use crate::{
@ -256,7 +256,7 @@ fn test_get_tzinfo() {
crate::Python::with_gil(|py| { crate::Python::with_gil(|py| {
use crate::types::{PyDateTime, PyTime}; use crate::types::{PyDateTime, PyTime};
use crate::{AsPyPointer, PyAny}; use crate::PyAny;
let utc = timezone_utc(py); let utc = timezone_utc(py);

View file

@ -507,7 +507,7 @@ fn decrement_gil_count() {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{gil_is_acquired, GILPool, GIL_COUNT, OWNED_OBJECTS, POOL}; use super::{gil_is_acquired, GILPool, GIL_COUNT, OWNED_OBJECTS, POOL};
use crate::{ffi, gil, AsPyPointer, IntoPyPointer, PyObject, Python, ToPyObject}; use crate::{ffi, gil, PyObject, Python, ToPyObject};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use parking_lot::{const_mutex, Condvar, Mutex}; use parking_lot::{const_mutex, Condvar, Mutex};
use std::ptr::NonNull; use std::ptr::NonNull;

View file

@ -697,7 +697,7 @@ fn push_parameter_list(msg: &mut String, parameter_names: &[&str]) {
mod tests { mod tests {
use crate::{ use crate::{
types::{IntoPyDict, PyTuple}, types::{IntoPyDict, PyTuple},
AsPyPointer, PyAny, Python, ToPyObject, PyAny, Python, ToPyObject,
}; };
use super::{push_parameter_list, FunctionDescription, NoVarargs, NoVarkeywords}; use super::{push_parameter_list, FunctionDescription, NoVarargs, NoVarkeywords};

View file

@ -12,7 +12,7 @@ use crate::{
pyclass::{create_type_object, PyClassTypeObject}, pyclass::{create_type_object, PyClassTypeObject},
sync::{GILOnceCell, GILProtected}, sync::{GILOnceCell, GILProtected},
types::PyType, types::PyType,
AsPyPointer, IntoPyPointer, PyClass, PyErr, PyMethodDefType, PyObject, PyResult, Python, PyClass, PyErr, PyMethodDefType, PyObject, PyResult, Python,
}; };
use super::PyClassItemsIter; use super::PyClassItemsIter;

View file

@ -11,7 +11,7 @@ use std::{
use crate::{ use crate::{
callback::PyCallbackOutput, ffi, impl_::panic::PanicTrap, methods::IPowModulo, callback::PyCallbackOutput, ffi, impl_::panic::PanicTrap, methods::IPowModulo,
panic::PanicException, types::PyModule, GILPool, IntoPyPointer, Py, PyResult, Python, panic::PanicException, types::PyModule, GILPool, Py, PyResult, Python,
}; };
#[inline] #[inline]

View file

@ -356,6 +356,34 @@ where
} }
} }
impl<T> Py<T> {
/// Returns the raw FFI pointer represented by self.
///
/// # Safety
///
/// Callers are responsible for ensuring that the pointer does not outlive self.
///
/// The reference is borrowed; callers should not decrease the reference count
/// when they are finished with the pointer.
#[inline]
pub fn as_ptr(&self) -> *mut ffi::PyObject {
self.0.as_ptr()
}
/// Returns an owned raw FFI pointer represented by self.
///
/// # Safety
///
/// The reference is owned; when finished the caller should either transfer ownership
/// of the pointer or decrease the reference count (e.g. with [`pyo3::ffi::Py_DecRef`](crate::ffi::Py_DecRef)).
#[inline]
pub fn into_ptr(self) -> *mut ffi::PyObject {
let ptr = self.0.as_ptr();
std::mem::forget(self);
ptr
}
}
impl<T> Py<T> impl<T> Py<T>
where where
T: PyClass, T: PyClass,
@ -897,7 +925,7 @@ impl<T> IntoPy<PyObject> for Py<T> {
} }
} }
impl<T> AsPyPointer for Py<T> { impl<T> crate::AsPyPointer for Py<T> {
/// Gets the underlying FFI pointer, returns a borrowed pointer. /// Gets the underlying FFI pointer, returns a borrowed pointer.
#[inline] #[inline]
fn as_ptr(&self) -> *mut ffi::PyObject { fn as_ptr(&self) -> *mut ffi::PyObject {

View file

@ -120,10 +120,7 @@ use crate::gil::{GILGuard, GILPool, SuspendGIL};
use crate::impl_::not_send::NotSend; use crate::impl_::not_send::NotSend;
use crate::types::{PyAny, PyDict, PyModule, PyString, PyType}; use crate::types::{PyAny, PyDict, PyModule, PyString, PyType};
use crate::version::PythonVersionInfo; use crate::version::PythonVersionInfo;
use crate::{ use crate::{ffi, FromPyPointer, IntoPy, Py, PyNativeType, PyObject, PyTryFrom, PyTypeInfo};
ffi, AsPyPointer, FromPyPointer, IntoPy, IntoPyPointer, Py, PyNativeType, PyObject, PyTryFrom,
PyTypeInfo,
};
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::os::raw::c_int; use std::os::raw::c_int;
@ -628,9 +625,9 @@ impl<'py> Python<'py> {
} }
let globals = globals let globals = globals
.map(AsPyPointer::as_ptr) .map(|dict| dict.as_ptr())
.unwrap_or_else(|| ffi::PyModule_GetDict(mptr)); .unwrap_or_else(|| ffi::PyModule_GetDict(mptr));
let locals = locals.map(AsPyPointer::as_ptr).unwrap_or(globals); let locals = locals.map(|dict| dict.as_ptr()).unwrap_or(globals);
let code_obj = ffi::Py_CompileString(code.as_ptr(), "<string>\0".as_ptr() as _, start); let code_obj = ffi::Py_CompileString(code.as_ptr(), "<string>\0".as_ptr() as _, start);
if code_obj.is_null() { if code_obj.is_null() {

View file

@ -603,7 +603,6 @@ impl<T: PyClass + fmt::Debug> fmt::Debug for PyCell<T> {
/// ///
/// fn format(slf: PyRef<'_, Self>) -> String { /// fn format(slf: PyRef<'_, Self>) -> String {
/// // We can get *mut ffi::PyObject from PyRef /// // We can get *mut ffi::PyObject from PyRef
/// use pyo3::AsPyPointer;
/// let refcnt = unsafe { pyo3::ffi::Py_REFCNT(slf.as_ptr()) }; /// let refcnt = unsafe { pyo3::ffi::Py_REFCNT(slf.as_ptr()) };
/// // We can get &Self::BaseType by as_ref /// // We can get &Self::BaseType by as_ref
/// let basename = slf.as_ref().basename; /// let basename = slf.as_ref().basename;
@ -638,6 +637,32 @@ where
} }
} }
impl<'p, T: PyClass> PyRef<'p, T> {
/// Returns the raw FFI pointer represented by self.
///
/// # Safety
///
/// Callers are responsible for ensuring that the pointer does not outlive self.
///
/// The reference is borrowed; callers should not decrease the reference count
/// when they are finished with the pointer.
#[inline]
pub fn as_ptr(&self) -> *mut ffi::PyObject {
self.inner.as_ptr()
}
/// Returns an owned raw FFI pointer represented by self.
///
/// # Safety
///
/// The reference is owned; when finished the caller should either transfer ownership
/// of the pointer or decrease the reference count (e.g. with [`pyo3::ffi::Py_DecRef`](crate::ffi::Py_DecRef)).
#[inline]
pub fn into_ptr(self) -> *mut ffi::PyObject {
self.inner.into_ptr()
}
}
impl<'p, T, U> PyRef<'p, T> impl<'p, T, U> PyRef<'p, T>
where where
T: PyClass<BaseType = U>, T: PyClass<BaseType = U>,
@ -771,6 +796,32 @@ where
} }
} }
impl<'p, T: PyClass<Frozen = False>> PyRefMut<'p, T> {
/// Returns the raw FFI pointer represented by self.
///
/// # Safety
///
/// Callers are responsible for ensuring that the pointer does not outlive self.
///
/// The reference is borrowed; callers should not decrease the reference count
/// when they are finished with the pointer.
#[inline]
pub fn as_ptr(&self) -> *mut ffi::PyObject {
self.inner.as_ptr()
}
/// Returns an owned raw FFI pointer represented by self.
///
/// # Safety
///
/// The reference is owned; when finished the caller should either transfer ownership
/// of the pointer or decrease the reference count (e.g. with [`pyo3::ffi::Py_DecRef`](crate::ffi::Py_DecRef)).
#[inline]
pub fn into_ptr(self) -> *mut ffi::PyObject {
self.inner.into_ptr()
}
}
impl<'p, T, U> PyRefMut<'p, T> impl<'p, T, U> PyRefMut<'p, T>
where where
T: PyClass<BaseType = U, Frozen = False>, T: PyClass<BaseType = U, Frozen = False>,
@ -1041,4 +1092,29 @@ mod tests {
cell.swap(cell2); cell.swap(cell2);
}) })
} }
#[test]
fn test_as_ptr() {
Python::with_gil(|py| {
let cell = PyCell::new(py, SomeClass(0)).unwrap();
let ptr = cell.as_ptr();
assert_eq!(cell.borrow().as_ptr(), ptr);
assert_eq!(cell.borrow_mut().as_ptr(), ptr);
})
}
#[test]
fn test_into_ptr() {
Python::with_gil(|py| {
let cell = PyCell::new(py, SomeClass(0)).unwrap();
let ptr = cell.as_ptr();
assert_eq!(cell.borrow().into_ptr(), ptr);
unsafe { ffi::Py_DECREF(ptr) };
assert_eq!(cell.borrow_mut().into_ptr(), ptr);
unsafe { ffi::Py_DECREF(ptr) };
})
}
} }

View file

@ -1,7 +1,7 @@
//! `PyClass` and related traits. //! `PyClass` and related traits.
use crate::{ use crate::{
callback::IntoPyCallbackOutput, ffi, impl_::pyclass::PyClassImpl, IntoPy, IntoPyPointer, callback::IntoPyCallbackOutput, ffi, impl_::pyclass::PyClassImpl, IntoPy, PyCell, PyObject,
PyCell, PyObject, PyResult, PyTypeInfo, Python, PyResult, PyTypeInfo, Python,
}; };
use std::{cmp::Ordering, os::raw::c_int}; use std::{cmp::Ordering, os::raw::c_int};

View file

@ -1,7 +1,7 @@
//! Contains initialization utilities for `#[pyclass]`. //! Contains initialization utilities for `#[pyclass]`.
use crate::callback::IntoPyCallbackOutput; use crate::callback::IntoPyCallbackOutput;
use crate::impl_::pyclass::{PyClassBaseType, PyClassDict, PyClassThreadChecker, PyClassWeakRef}; use crate::impl_::pyclass::{PyClassBaseType, PyClassDict, PyClassThreadChecker, PyClassWeakRef};
use crate::{ffi, IntoPyPointer, Py, PyCell, PyClass, PyErr, PyResult, Python}; use crate::{ffi, Py, PyCell, PyClass, PyErr, PyResult, Python};
use crate::{ use crate::{
ffi::PyTypeObject, ffi::PyTypeObject,
pycell::{ pycell::{

View file

@ -1,7 +1,7 @@
//! Python type object information //! Python type object information
use crate::types::{PyAny, PyType}; use crate::types::{PyAny, PyType};
use crate::{ffi, AsPyPointer, PyNativeType, Python}; use crate::{ffi, PyNativeType, Python};
/// `T: PyLayout<U>` represents that `T` is a concrete representation of `U` in the Python heap. /// `T: PyLayout<U>` represents that `T` is a concrete representation of `U` in the Python heap.
/// E.g., `PyCell` is a concrete representation of all `pyclass`es, and `ffi::PyObject` /// E.g., `PyCell` is a concrete representation of all `pyclass`es, and `ffi::PyObject`

View file

@ -1,5 +1,5 @@
use crate::class::basic::CompareOp; use crate::class::basic::CompareOp;
use crate::conversion::{AsPyPointer, FromPyObject, IntoPy, IntoPyPointer, PyTryFrom, ToPyObject}; use crate::conversion::{AsPyPointer, FromPyObject, IntoPy, PyTryFrom, ToPyObject};
use crate::err::{PyDowncastError, PyErr, PyResult}; use crate::err::{PyDowncastError, PyErr, PyResult};
use crate::exceptions::{PyAttributeError, PyTypeError}; use crate::exceptions::{PyAttributeError, PyTypeError};
use crate::type_object::PyTypeInfo; use crate::type_object::PyTypeInfo;
@ -36,7 +36,7 @@ use std::os::raw::c_int;
#[repr(transparent)] #[repr(transparent)]
pub struct PyAny(UnsafeCell<ffi::PyObject>); pub struct PyAny(UnsafeCell<ffi::PyObject>);
impl crate::AsPyPointer for PyAny { impl AsPyPointer for PyAny {
#[inline] #[inline]
fn as_ptr(&self) -> *mut ffi::PyObject { fn as_ptr(&self) -> *mut ffi::PyObject {
self.0.get() self.0.get()
@ -511,12 +511,11 @@ impl PyAny {
let py = self.py(); let py = self.py();
let args = args.into_py(py); let args = args.into_py(py);
let kwargs = kwargs.into_ptr(); let kwargs = kwargs.map_or(std::ptr::null_mut(), |kwargs| kwargs.as_ptr());
unsafe { unsafe {
let return_value = ffi::PyObject_Call(self.as_ptr(), args.as_ptr(), kwargs); let return_value = ffi::PyObject_Call(self.as_ptr(), args.as_ptr(), kwargs);
let ret = py.from_owned_ptr_or_err(return_value); let ret = py.from_owned_ptr_or_err(return_value);
ffi::Py_XDECREF(kwargs);
ret ret
} }
} }
@ -632,12 +631,11 @@ impl PyAny {
let callee = self.getattr(name)?; let callee = self.getattr(name)?;
let args: Py<PyTuple> = args.into_py(py); let args: Py<PyTuple> = args.into_py(py);
let kwargs = kwargs.into_ptr(); let kwargs = kwargs.map_or(std::ptr::null_mut(), |kwargs| kwargs.as_ptr());
unsafe { unsafe {
let result_ptr = ffi::PyObject_Call(callee.as_ptr(), args.as_ptr(), kwargs); let result_ptr = ffi::PyObject_Call(callee.as_ptr(), args.as_ptr(), kwargs);
let result = py.from_owned_ptr_or_err(result_ptr); let result = py.from_owned_ptr_or_err(result_ptr);
ffi::Py_XDECREF(kwargs);
result result
} }
} }
@ -1065,6 +1063,31 @@ impl PyAny {
PyNativeType::py(self) PyNativeType::py(self)
} }
/// Returns the raw FFI pointer represented by self.
///
/// # Safety
///
/// Callers are responsible for ensuring that the pointer does not outlive self.
///
/// The reference is borrowed; callers should not decrease the reference count
/// when they are finished with the pointer.
#[inline]
pub fn as_ptr(&self) -> *mut ffi::PyObject {
self as *const PyAny as *mut ffi::PyObject
}
/// Returns an owned raw FFI pointer represented by self.
///
/// # Safety
///
/// The reference is owned; when finished the caller should either transfer ownership
/// of the pointer or decrease the reference count (e.g. with [`pyo3::ffi::Py_DecRef`](crate::ffi::Py_DecRef)).
#[inline]
pub fn into_ptr(&self) -> *mut ffi::PyObject {
// Safety: self.as_ptr() returns a valid non-null pointer
unsafe { ffi::_Py_NewRef(self.as_ptr()) }
}
/// Return a proxy object that delegates method calls to a parent or sibling class of type. /// Return a proxy object that delegates method calls to a parent or sibling class of type.
/// ///
/// This is equivalent to the Python expression `super()` /// This is equivalent to the Python expression `super()`

View file

@ -1,8 +1,6 @@
#[cfg(feature = "experimental-inspect")] #[cfg(feature = "experimental-inspect")]
use crate::inspect::types::TypeInfo; use crate::inspect::types::TypeInfo;
use crate::{ use crate::{ffi, FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject};
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject,
};
/// Represents a Python `bool`. /// Represents a Python `bool`.
#[repr(transparent)] #[repr(transparent)]

View file

@ -1,4 +1,4 @@
use crate::{ffi, AsPyPointer, FromPyObject, IntoPy, Py, PyAny, PyResult, Python, ToPyObject}; use crate::{ffi, FromPyObject, IntoPy, Py, PyAny, PyResult, Python, ToPyObject};
use std::borrow::Cow; use std::borrow::Cow;
use std::ops::Index; use std::ops::Index;
use std::os::raw::c_char; use std::os::raw::c_char;

View file

@ -1,5 +1,5 @@
use crate::Python; use crate::Python;
use crate::{ffi, AsPyPointer, PyAny}; use crate::{ffi, PyAny};
use crate::{pyobject_native_type_core, PyErr, PyResult}; use crate::{pyobject_native_type_core, PyErr, PyResult};
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::os::raw::{c_char, c_int, c_void}; use std::os::raw::{c_char, c_int, c_void};

View file

@ -1,4 +1,4 @@
use crate::{ffi, AsPyPointer, PyAny, Python}; use crate::{ffi, PyAny, Python};
use std::os::raw::c_double; use std::os::raw::c_double;
/// Represents a Python [`complex`](https://docs.python.org/3/library/functions.html#complex) object. /// Represents a Python [`complex`](https://docs.python.org/3/library/functions.html#complex) object.

View file

@ -21,7 +21,7 @@ use crate::ffi::{
}; };
use crate::instance::PyNativeType; use crate::instance::PyNativeType;
use crate::types::PyTuple; use crate::types::PyTuple;
use crate::{AsPyPointer, IntoPy, Py, PyAny, Python}; use crate::{IntoPy, Py, PyAny, Python};
use std::os::raw::c_int; use std::os::raw::c_int;
fn ensure_datetime_api(_py: Python<'_>) -> &'static PyDateTime_CAPI { fn ensure_datetime_api(_py: Python<'_>) -> &'static PyDateTime_CAPI {

View file

@ -2,9 +2,7 @@ use super::PyMapping;
use crate::err::{self, PyErr, PyResult}; use crate::err::{self, PyErr, PyResult};
use crate::ffi::Py_ssize_t; use crate::ffi::Py_ssize_t;
use crate::types::{PyAny, PyList}; use crate::types::{PyAny, PyList};
#[cfg(not(PyPy))] use crate::{ffi, PyObject, Python, ToPyObject};
use crate::IntoPyPointer;
use crate::{ffi, AsPyPointer, PyObject, Python, ToPyObject};
/// Represents a Python `dict`. /// Represents a Python `dict`.
#[repr(transparent)] #[repr(transparent)]

View file

@ -1,8 +1,7 @@
#[cfg(feature = "experimental-inspect")] #[cfg(feature = "experimental-inspect")]
use crate::inspect::types::TypeInfo; use crate::inspect::types::TypeInfo;
use crate::{ use crate::{
ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyErr, PyNativeType, PyObject, PyResult, Python, ffi, FromPyObject, IntoPy, PyAny, PyErr, PyNativeType, PyObject, PyResult, Python, ToPyObject,
ToPyObject,
}; };
use std::os::raw::c_double; use std::os::raw::c_double;

View file

@ -4,7 +4,7 @@ use crate::{
err::{self, PyErr, PyResult}, err::{self, PyErr, PyResult},
Py, PyObject, Py, PyObject,
}; };
use crate::{ffi, AsPyPointer, PyAny, Python, ToPyObject}; use crate::{ffi, PyAny, Python, ToPyObject};
use std::ptr; use std::ptr;

View file

@ -5,7 +5,6 @@ use crate::{
ffi, ffi,
impl_::pymethods::{self, PyMethodDef}, impl_::pymethods::{self, PyMethodDef},
types::{PyCapsule, PyDict, PyTuple}, types::{PyCapsule, PyDict, PyTuple},
AsPyPointer,
}; };
use std::cell::UnsafeCell; use std::cell::UnsafeCell;
use std::ffi::CStr; use std::ffi::CStr;

View file

@ -1,4 +1,4 @@
use crate::{ffi, AsPyPointer, IntoPyPointer, Py, PyAny, PyErr, PyNativeType, PyResult, Python}; use crate::{ffi, AsPyPointer, Py, PyAny, PyErr, PyNativeType, PyResult, Python};
use crate::{PyDowncastError, PyTryFrom}; use crate::{PyDowncastError, PyTryFrom};
/// A Python iterator object. /// A Python iterator object.

View file

@ -5,7 +5,7 @@ use crate::err::{self, PyResult};
use crate::ffi::{self, Py_ssize_t}; use crate::ffi::{self, Py_ssize_t};
use crate::internal_tricks::get_ssize_index; use crate::internal_tricks::get_ssize_index;
use crate::types::{PySequence, PyTuple}; use crate::types::{PySequence, PyTuple};
use crate::{AsPyPointer, IntoPyPointer, Py, PyAny, PyObject, Python, ToPyObject}; use crate::{Py, PyAny, PyObject, Python, ToPyObject};
/// Represents a Python `list`. /// Represents a Python `list`.
#[repr(transparent)] #[repr(transparent)]

View file

@ -2,7 +2,7 @@ use crate::err::{PyDowncastError, PyResult};
use crate::sync::GILOnceCell; use crate::sync::GILOnceCell;
use crate::type_object::PyTypeInfo; use crate::type_object::PyTypeInfo;
use crate::types::{PyAny, PyDict, PySequence, PyType}; use crate::types::{PyAny, PyDict, PySequence, PyType};
use crate::{ffi, AsPyPointer, IntoPyPointer, Py, PyNativeType, PyTryFrom, Python, ToPyObject}; use crate::{ffi, Py, PyNativeType, PyTryFrom, Python, ToPyObject};
/// Represents a reference to a Python object supporting the mapping protocol. /// Represents a reference to a Python object supporting the mapping protocol.
#[repr(transparent)] #[repr(transparent)]

View file

@ -114,7 +114,6 @@ macro_rules! pyobject_native_type_base(
{ {
#[inline] #[inline]
fn to_object(&self, py: $crate::Python<'_>) -> $crate::PyObject { fn to_object(&self, py: $crate::Python<'_>) -> $crate::PyObject {
use $crate::AsPyPointer;
unsafe { $crate::PyObject::from_borrowed_ptr(py, self.as_ptr()) } unsafe { $crate::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
} }
} }
@ -156,7 +155,6 @@ macro_rules! pyobject_native_type_named (
impl<$($generics,)*> $crate::IntoPy<$crate::Py<$name>> for &'_ $name { impl<$($generics,)*> $crate::IntoPy<$crate::Py<$name>> for &'_ $name {
#[inline] #[inline]
fn into_py(self, py: $crate::Python<'_>) -> $crate::Py<$name> { fn into_py(self, py: $crate::Python<'_>) -> $crate::Py<$name> {
use $crate::AsPyPointer;
unsafe { $crate::Py::from_borrowed_ptr(py, self.as_ptr()) } unsafe { $crate::Py::from_borrowed_ptr(py, self.as_ptr()) }
} }
} }
@ -164,7 +162,6 @@ macro_rules! pyobject_native_type_named (
impl<$($generics,)*> ::std::convert::From<&'_ $name> for $crate::Py<$name> { impl<$($generics,)*> ::std::convert::From<&'_ $name> for $crate::Py<$name> {
#[inline] #[inline]
fn from(other: &$name) -> Self { fn from(other: &$name) -> Self {
use $crate::AsPyPointer;
use $crate::PyNativeType; use $crate::PyNativeType;
unsafe { $crate::Py::from_borrowed_ptr(other.py(), other.as_ptr()) } unsafe { $crate::Py::from_borrowed_ptr(other.py(), other.as_ptr()) }
} }
@ -205,7 +202,6 @@ macro_rules! pyobject_native_type_info(
$( $(
#[inline] #[inline]
fn is_type_of(ptr: &$crate::PyAny) -> bool { fn is_type_of(ptr: &$crate::PyAny) -> bool {
use $crate::AsPyPointer;
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
unsafe { $checkfunction(ptr.as_ptr()) > 0 } unsafe { $checkfunction(ptr.as_ptr()) > 0 }
} }

View file

@ -4,7 +4,7 @@ use crate::exceptions;
use crate::ffi; use crate::ffi;
use crate::pyclass::PyClass; use crate::pyclass::PyClass;
use crate::types::{PyAny, PyCFunction, PyDict, PyList, PyString}; use crate::types::{PyAny, PyCFunction, PyDict, PyList, PyString};
use crate::{AsPyPointer, IntoPy, Py, PyObject, Python}; use crate::{IntoPy, Py, PyObject, Python};
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::str; use std::str;

View file

@ -7,8 +7,8 @@ use crate::sync::GILOnceCell;
use crate::type_object::PyTypeInfo; use crate::type_object::PyTypeInfo;
use crate::types::{PyAny, PyList, PyString, PyTuple, PyType}; use crate::types::{PyAny, PyList, PyString, PyTuple, PyType};
use crate::{ffi, PyNativeType, PyObject, ToPyObject}; use crate::{ffi, PyNativeType, PyObject, ToPyObject};
use crate::{AsPyPointer, IntoPyPointer, Py, Python};
use crate::{FromPyObject, PyTryFrom}; use crate::{FromPyObject, PyTryFrom};
use crate::{Py, Python};
/// Represents a reference to a Python object supporting the sequence protocol. /// Represents a reference to a Python object supporting the sequence protocol.
#[repr(transparent)] #[repr(transparent)]
@ -388,7 +388,7 @@ impl Py<PySequence> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::types::{PyList, PySequence, PyTuple}; use crate::types::{PyList, PySequence, PyTuple};
use crate::{AsPyPointer, Py, PyObject, Python, ToPyObject}; use crate::{Py, PyObject, Python, ToPyObject};
fn get_object() -> PyObject { fn get_object() -> PyObject {
// Convenience function for getting a single unique object // Convenience function for getting a single unique object

View file

@ -4,7 +4,7 @@ use crate::{
err::{self, PyErr, PyResult}, err::{self, PyErr, PyResult},
Py, Py,
}; };
use crate::{ffi, AsPyPointer, PyAny, PyObject, Python, ToPyObject}; use crate::{ffi, PyAny, PyObject, Python, ToPyObject};
use std::ptr; use std::ptr;
/// Represents a Python `set` /// Represents a Python `set`

View file

@ -1,6 +1,6 @@
use crate::err::{PyErr, PyResult}; use crate::err::{PyErr, PyResult};
use crate::ffi::{self, Py_ssize_t}; use crate::ffi::{self, Py_ssize_t};
use crate::{AsPyPointer, PyAny, PyObject, Python, ToPyObject}; use crate::{PyAny, PyObject, Python, ToPyObject};
use std::os::raw::c_long; use std::os::raw::c_long;
/// Represents a Python `slice`. /// Represents a Python `slice`.

View file

@ -1,7 +1,7 @@
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
use crate::exceptions::PyUnicodeDecodeError; use crate::exceptions::PyUnicodeDecodeError;
use crate::types::PyBytes; use crate::types::PyBytes;
use crate::{ffi, AsPyPointer, PyAny, PyResult, Python}; use crate::{ffi, PyAny, PyResult, Python};
use std::borrow::Cow; use std::borrow::Cow;
use std::os::raw::c_char; use std::os::raw::c_char;
use std::str; use std::str;

View file

@ -1,7 +1,7 @@
use crate::err::{error_on_minusone, PyResult}; use crate::err::{error_on_minusone, PyResult};
use crate::ffi; use crate::ffi;
use crate::types::PyString; use crate::types::PyString;
use crate::{AsPyPointer, PyAny}; use crate::PyAny;
/// Represents a Python traceback. /// Represents a Python traceback.
#[repr(transparent)] #[repr(transparent)]

View file

@ -8,8 +8,7 @@ use crate::internal_tricks::get_ssize_index;
use crate::types::PyList; use crate::types::PyList;
use crate::types::PySequence; use crate::types::PySequence;
use crate::{ use crate::{
exceptions, AsPyPointer, FromPyObject, IntoPy, IntoPyPointer, Py, PyAny, PyErr, PyObject, exceptions, FromPyObject, IntoPy, Py, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
PyResult, Python, ToPyObject,
}; };
#[inline] #[inline]

View file

@ -1,5 +1,5 @@
use crate::err::{self, PyResult}; use crate::err::{self, PyResult};
use crate::{ffi, AsPyPointer, PyAny, PyTypeInfo, Python}; use crate::{ffi, PyAny, PyTypeInfo, Python};
/// Represents a reference to a Python `type object`. /// Represents a reference to a Python `type object`.
#[repr(transparent)] #[repr(transparent)]

View file

@ -1,7 +1,7 @@
#![cfg(feature = "macros")] #![cfg(feature = "macros")]
#![cfg(any(not(Py_LIMITED_API), Py_3_11))] #![cfg(any(not(Py_LIMITED_API), Py_3_11))]
use pyo3::{buffer::PyBuffer, exceptions::PyBufferError, ffi, prelude::*, AsPyPointer}; use pyo3::{buffer::PyBuffer, exceptions::PyBufferError, ffi, prelude::*};
use std::{ use std::{
ffi::CStr, ffi::CStr,
os::raw::{c_int, c_void}, os::raw::{c_int, c_void},

View file

@ -6,7 +6,6 @@ use pyo3::exceptions::PyBufferError;
use pyo3::ffi; use pyo3::ffi;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::IntoPyDict; use pyo3::types::IntoPyDict;
use pyo3::AsPyPointer;
use std::ffi::CString; use std::ffi::CString;
use std::os::raw::{c_int, c_void}; use std::os::raw::{c_int, c_void};
use std::ptr; use std::ptr;

View file

@ -36,7 +36,7 @@ fn _get_subclasses<'p>(
macro_rules! assert_check_exact { macro_rules! assert_check_exact {
($check_func:ident, $check_func_exact:ident, $obj: expr) => { ($check_func:ident, $check_func_exact:ident, $obj: expr) => {
unsafe { unsafe {
use pyo3::{ffi::*, AsPyPointer}; use pyo3::ffi::*;
assert!($check_func(($obj).as_ptr()) != 0); assert!($check_func(($obj).as_ptr()) != 0);
assert!($check_func_exact(($obj).as_ptr()) != 0); assert!($check_func_exact(($obj).as_ptr()) != 0);
} }
@ -46,7 +46,7 @@ macro_rules! assert_check_exact {
macro_rules! assert_check_only { macro_rules! assert_check_only {
($check_func:ident, $check_func_exact:ident, $obj: expr) => { ($check_func:ident, $check_func_exact:ident, $obj: expr) => {
unsafe { unsafe {
use pyo3::{ffi::*, AsPyPointer}; use pyo3::ffi::*;
assert!($check_func(($obj).as_ptr()) != 0); assert!($check_func(($obj).as_ptr()) != 0);
assert!($check_func_exact(($obj).as_ptr()) == 0); assert!($check_func_exact(($obj).as_ptr()) == 0);
} }

View file

@ -101,7 +101,7 @@ fn test_exception_nosegfault() {
#[cfg(Py_3_8)] #[cfg(Py_3_8)]
fn test_write_unraisable() { fn test_write_unraisable() {
use common::UnraisableCapture; use common::UnraisableCapture;
use pyo3::{exceptions::PyRuntimeError, ffi, AsPyPointer}; use pyo3::{exceptions::PyRuntimeError, ffi};
Python::with_gil(|py| { Python::with_gil(|py| {
let capture = UnraisableCapture::install(py); let capture = UnraisableCapture::install(py);

View file

@ -3,7 +3,7 @@
use pyo3::class::PyTraverseError; use pyo3::class::PyTraverseError;
use pyo3::class::PyVisit; use pyo3::class::PyVisit;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::{py_run, AsPyPointer, PyCell, PyTryInto}; use pyo3::{py_run, PyCell, PyTryInto};
use std::cell::Cell; use std::cell::Cell;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;

View file

@ -2,7 +2,7 @@
use pyo3::exceptions::{PyIndexError, PyValueError}; use pyo3::exceptions::{PyIndexError, PyValueError};
use pyo3::types::{IntoPyDict, PyList, PyMapping, PySequence}; use pyo3::types::{IntoPyDict, PyList, PyMapping, PySequence};
use pyo3::{ffi, prelude::*, AsPyPointer}; use pyo3::{ffi, prelude::*};
use pyo3::py_run; use pyo3::py_run;