delete pyptr
This commit is contained in:
parent
b3be3d35de
commit
fd2ae9ce60
|
@ -157,8 +157,10 @@ impl <'p> PyObject<'p> {
|
|||
|
||||
#[inline]
|
||||
pub fn get_type(&self) -> &PyType<'p> {
|
||||
unimplemented!()
|
||||
//unsafe { PyType::from_type_ptr(self.python(), ffi::Py_TYPE(self.as_ptr())) }
|
||||
unsafe {
|
||||
let t : &*mut ffi::PyTypeObject = &(*self.as_ptr()).ob_type;
|
||||
transmute(t)
|
||||
}
|
||||
}
|
||||
|
||||
/// Casts the PyObject to a concrete python object type.
|
||||
|
@ -222,6 +224,8 @@ impl <'p> Eq for PyObject<'p> { }
|
|||
#[test]
|
||||
fn test_sizeof() {
|
||||
// should be a static_assert, but size_of is not a compile-time const
|
||||
// these are necessary for the transmutes in this module
|
||||
assert_eq!(size_of::<PyObject>(), size_of::<*mut ffi::PyObject>());
|
||||
assert_eq!(size_of::<PyType>(), size_of::<*mut ffi::PyTypeObject>());
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,11 @@ impl <'p> PyTuple<'p> {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn iter<'a>(&'a self) -> std::slice::Iter<'a, PyObject<'p>> {
|
||||
self.as_slice().iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> std::ops::Index<uint> for PyTuple<'p> {
|
||||
|
|
185
src/pyptr.rs
185
src/pyptr.rs
|
@ -1,185 +0,0 @@
|
|||
use std;
|
||||
use std::ops::Deref;
|
||||
use ffi;
|
||||
use python::{Python, PythonObject, PythonObjectWithCheckedDowncast};
|
||||
use objects::PyObject;
|
||||
use err::{PyResult, PyErr};
|
||||
//use conversion::{FromPyObject, ToPyObject};
|
||||
//use PyResult;
|
||||
|
||||
|
||||
/// Owned pointer to python object.
|
||||
/// The PyPtr<T> owns one reference to a python object.
|
||||
/// Python objects are reference-counted, so it is possible to have
|
||||
/// multiple PyPtr<T> objects pointing to the same object, like Rc<T>.
|
||||
#[derive(Hash, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub struct PyPtr<'p, T : PythonObject<'p>>(&'p T);
|
||||
|
||||
// impl PyPtr
|
||||
impl<'p, T : PythonObject<'p>> PyPtr<'p, T> {
|
||||
/// Creates a new PyPtr instance from a borrowed reference.
|
||||
/// This increments the reference count.
|
||||
#[inline]
|
||||
pub fn new(obj : &T) -> PyPtr<'p, T> {
|
||||
debug_assert!(obj.as_object().get_refcnt() > 0);
|
||||
let obj_extended_life : &T = unsafe {
|
||||
ffi::Py_INCREF(obj.as_ptr());
|
||||
// transmuting from &T to &'p T is safe because we just incremented the reference count,
|
||||
// and the &'p T is used only within the PyPtr -- the reference returned by Deref has
|
||||
// the lifetime restricted to the PyPtr's lifetime.
|
||||
std::mem::transmute(obj)
|
||||
};
|
||||
PyPtr(obj_extended_life)
|
||||
}
|
||||
}
|
||||
|
||||
// impl Deref for PyPtr
|
||||
impl <'p, T : PythonObject<'p>> Deref for PyPtr<'p, T> {
|
||||
type Target = T;
|
||||
|
||||
#[inline]
|
||||
fn deref<'a>(&'a self) -> &'a T {
|
||||
debug_assert!(self.0.as_object().get_refcnt() > 0);
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
// impl Drop for PyPtr
|
||||
#[unsafe_destructor]
|
||||
impl<'p, T : PythonObject<'p>> Drop for PyPtr<'p, T> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
debug_assert!(self.0.as_object().get_refcnt() > 0);
|
||||
unsafe { ffi::Py_DECREF(self.as_ptr()) }
|
||||
}
|
||||
}
|
||||
|
||||
// impl Clone for PyPtr
|
||||
impl<'p, T : PythonObject<'p>> Clone for PyPtr<'p, T> {
|
||||
#[inline]
|
||||
fn clone(&self) -> PyPtr<'p, T> {
|
||||
unsafe { ffi::Py_INCREF(self.as_ptr()) };
|
||||
PyPtr(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
// impl Show for PyPtr
|
||||
impl<'p, T : PythonObject<'p> + std::fmt::Show> std::fmt::Show for PyPtr<'p, T> {
|
||||
#[inline]
|
||||
fn fmt(&self, f : &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
self.deref().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
// impl BorrowFrom<PyPtr>
|
||||
impl<'p, T : PythonObject<'p>> std::borrow::BorrowFrom<PyPtr<'p, T>> for T {
|
||||
fn borrow_from<'a>(owned: &'a PyPtr<'p, T>) -> &'a T {
|
||||
&**owned
|
||||
}
|
||||
}
|
||||
|
||||
// impl ToOwned<PyPtr>
|
||||
impl<'p, T : PythonObject<'p>> std::borrow::ToOwned<PyPtr<'p, T>> for T {
|
||||
fn to_owned(&self) -> PyPtr<'p, T> {
|
||||
PyPtr::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// The PythonPointer trait allows extracting an FFI pointer.
|
||||
pub trait PythonPointer {
|
||||
/// Gets the FFI pointer (borrowed reference).
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject;
|
||||
/// Gets the FFI pointer (owned reference).
|
||||
/// If the implementation of this trait is an owned pointer, this steals the reference.
|
||||
/// If the implementation of this trait is a borrowed pointer, this increments the reference count.
|
||||
fn steal_ptr(self) -> *mut ffi::PyObject;
|
||||
}
|
||||
|
||||
impl <'p, T : PythonObject<'p>> PythonPointer for PyPtr<'p, T> {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
self.deref().as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn steal_ptr(self) -> *mut ffi::PyObject {
|
||||
// Destruct the PyPtr without decrementing the reference count
|
||||
let p = self.deref().as_ptr();
|
||||
unsafe { std::mem::forget(self) };
|
||||
p
|
||||
}
|
||||
}
|
||||
|
||||
// &PyObject (etc.) is also a PythonPointer
|
||||
// (but steal_ptr increases the reference count)
|
||||
impl <'p, 'a, T : PythonObject<'p>> PythonPointer for &'a T {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
self.deref().as_ptr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn steal_ptr(self) -> *mut ffi::PyObject {
|
||||
PyPtr::new(self).steal_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
// Option<PythonPointer> can be used to extract a nullable FFI pointer.
|
||||
impl <T : PythonPointer> PythonPointer for Option<T> {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
match *self {
|
||||
Some(ref p) => p.as_ptr(),
|
||||
None => std::ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn steal_ptr(self) -> *mut ffi::PyObject {
|
||||
match self {
|
||||
Some(p) => p.steal_ptr(),
|
||||
None => std::ptr::null_mut()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// impl PyPtr<PyObject>
|
||||
impl<'p> PyPtr<'p, PyObject<'p>> {
|
||||
#[inline]
|
||||
pub unsafe fn from_owned_ptr(py : Python<'p>, p : *mut ffi::PyObject) -> PyPtr<'p, PyObject<'p>> {
|
||||
debug_assert!(!p.is_null() && ffi::Py_REFCNT(p) > 0);
|
||||
PyPtr(PyObject::from_ptr(py, p))
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn from_borrowed_ptr(py : Python<'p>, p : *mut ffi::PyObject) -> PyPtr<'p, PyObject<'p>> {
|
||||
debug_assert!(!p.is_null() && ffi::Py_REFCNT(p) > 0);
|
||||
ffi::Py_INCREF(p);
|
||||
PyPtr(PyObject::from_ptr(py, p))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn from_owned_ptr_opt(py : Python<'p>, p : *mut ffi::PyObject) -> Option<PyPtr<'p, PyObject<'p>>> {
|
||||
if p.is_null() { None } else { Some(PyPtr::from_owned_ptr(py, p)) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn from_borrowed_ptr_opt(py : Python<'p>, p : *mut ffi::PyObject) -> Option<PyPtr<'p, PyObject<'p>>> {
|
||||
if p.is_null() { None } else { Some(PyPtr::from_borrowed_ptr(py, p)) }
|
||||
}
|
||||
|
||||
/// Casts the PyPtr<PyObject> to a PyPtr of a concrete python object type.
|
||||
/// Returns a python TypeError if the object is not of the expected type.
|
||||
#[inline]
|
||||
pub fn downcast_into<T>(self) -> PyResult<'p, PyPtr<'p, T>> where T: PythonObjectWithCheckedDowncast<'p> {
|
||||
// TODO: avoid unnecessary IncRef/DefRef
|
||||
self.deref().downcast().map(PyPtr::new)
|
||||
}
|
||||
|
||||
pub unsafe fn unchecked_downcast_into<T>(self) -> PyPtr<'p, T> where T: PythonObject<'p> {
|
||||
// TODO: avoid unnecessary IncRef/DefRef
|
||||
PyPtr::new(PythonObject::unchecked_downcast_from(self.deref()))
|
||||
}
|
||||
}
|
||||
|
|
@ -52,12 +52,10 @@ pub struct PythonObjectDowncastError<'p>(pub Python<'p>);
|
|||
|
||||
/// Trait implemented by python object types that allow a checked downcast.
|
||||
pub trait PythonObjectWithCheckedDowncast<'p> : PythonObject<'p> {
|
||||
/// Upcast from PyObject to a concrete python object type.
|
||||
/// Returns None if the python object is not of the specified type.
|
||||
/// Cast from PyObject to a concrete python object type.
|
||||
fn downcast_from(PyObject<'p>) -> Result<Self, PythonObjectDowncastError<'p>>;
|
||||
|
||||
/// Upcast from PyObject to a concrete python object type.
|
||||
/// Returns None if the python object is not of the specified type.
|
||||
/// Cast from PyObject to a concrete python object type.
|
||||
fn downcast_borrow_from<'a>(&'a PyObject<'p>) -> Result<&'a Self, PythonObjectDowncastError<'p>>;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue