delete pyptr

This commit is contained in:
Daniel Grunwald 2015-01-08 09:19:35 +01:00
parent b3be3d35de
commit fd2ae9ce60
4 changed files with 13 additions and 191 deletions

View File

@ -157,8 +157,10 @@ impl <'p> PyObject<'p> {
#[inline] #[inline]
pub fn get_type(&self) -> &PyType<'p> { pub fn get_type(&self) -> &PyType<'p> {
unimplemented!() unsafe {
//unsafe { PyType::from_type_ptr(self.python(), ffi::Py_TYPE(self.as_ptr())) } let t : &*mut ffi::PyTypeObject = &(*self.as_ptr()).ob_type;
transmute(t)
}
} }
/// Casts the PyObject to a concrete python object type. /// Casts the PyObject to a concrete python object type.
@ -222,6 +224,8 @@ impl <'p> Eq for PyObject<'p> { }
#[test] #[test]
fn test_sizeof() { fn test_sizeof() {
// should be a static_assert, but size_of is not a compile-time const // 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::<PyObject>(), size_of::<*mut ffi::PyObject>());
assert_eq!(size_of::<PyType>(), size_of::<*mut ffi::PyTypeObject>());
} }

View File

@ -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> { impl<'p> std::ops::Index<uint> for PyTuple<'p> {

View File

@ -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()))
}
}

View File

@ -52,12 +52,10 @@ pub struct PythonObjectDowncastError<'p>(pub Python<'p>);
/// Trait implemented by python object types that allow a checked downcast. /// Trait implemented by python object types that allow a checked downcast.
pub trait PythonObjectWithCheckedDowncast<'p> : PythonObject<'p> { pub trait PythonObjectWithCheckedDowncast<'p> : PythonObject<'p> {
/// Upcast from PyObject to a concrete python object type. /// Cast from PyObject to a concrete python object type.
/// Returns None if the python object is not of the specified type.
fn downcast_from(PyObject<'p>) -> Result<Self, PythonObjectDowncastError<'p>>; fn downcast_from(PyObject<'p>) -> Result<Self, PythonObjectDowncastError<'p>>;
/// Upcast from PyObject to a concrete python object type. /// Cast from PyObject to a concrete python object type.
/// Returns None if the python object is not of the specified type.
fn downcast_borrow_from<'a>(&'a PyObject<'p>) -> Result<&'a Self, PythonObjectDowncastError<'p>>; fn downcast_borrow_from<'a>(&'a PyObject<'p>) -> Result<&'a Self, PythonObjectDowncastError<'p>>;
} }