From fd2ae9ce60370659ee49af2b616bb0c2347e2c6a Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 8 Jan 2015 09:19:35 +0100 Subject: [PATCH] delete pyptr --- src/objects/object.rs | 8 +- src/objects/tuple.rs | 5 ++ src/pyptr.rs | 185 ------------------------------------------ src/python.rs | 6 +- 4 files changed, 13 insertions(+), 191 deletions(-) delete mode 100644 src/pyptr.rs diff --git a/src/objects/object.rs b/src/objects/object.rs index 05505431..848d0c46 100644 --- a/src/objects/object.rs +++ b/src/objects/object.rs @@ -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::(), size_of::<*mut ffi::PyObject>()); + assert_eq!(size_of::(), size_of::<*mut ffi::PyTypeObject>()); } diff --git a/src/objects/tuple.rs b/src/objects/tuple.rs index 18f818b7..55568d4f 100644 --- a/src/objects/tuple.rs +++ b/src/objects/tuple.rs @@ -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 for PyTuple<'p> { diff --git a/src/pyptr.rs b/src/pyptr.rs deleted file mode 100644 index 619f5cef..00000000 --- a/src/pyptr.rs +++ /dev/null @@ -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 owns one reference to a python object. -/// Python objects are reference-counted, so it is possible to have -/// multiple PyPtr objects pointing to the same object, like Rc. -#[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 -impl<'p, T : PythonObject<'p>> std::borrow::BorrowFrom> for T { - fn borrow_from<'a>(owned: &'a PyPtr<'p, T>) -> &'a T { - &**owned - } -} - -// impl ToOwned -impl<'p, T : PythonObject<'p>> std::borrow::ToOwned> 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 can be used to extract a nullable FFI pointer. -impl PythonPointer for Option { - #[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 -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>> { - 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>> { - if p.is_null() { None } else { Some(PyPtr::from_borrowed_ptr(py, p)) } - } - - /// Casts the PyPtr 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(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(self) -> PyPtr<'p, T> where T: PythonObject<'p> { - // TODO: avoid unnecessary IncRef/DefRef - PyPtr::new(PythonObject::unchecked_downcast_from(self.deref())) - } -} - diff --git a/src/python.rs b/src/python.rs index 794a4fbc..c0cb87fb 100644 --- a/src/python.rs +++ b/src/python.rs @@ -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>; - /// 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>>; }