diff --git a/src/conversion.rs b/src/conversion.rs index ad13adea..150bfbbe 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -12,10 +12,10 @@ pub trait FromPyObject<'p, 'a> { /// ToPyObject is implemented for types that can be converted into a python object. pub trait ToPyObject<'p> for Sized? { - //type PointerType : 'p + PythonPointer + Deref> = PyPtr<'p, PyObject<'p>>; + type PointerType : 'p + PythonPointer + std::ops::Deref; - //fn to_py_object(&self, py: Python<'p>) -> PyResult<'p, Self::PointerType>; - fn to_py_object(&self, py: Python<'p>) -> PyResult<'p, PyPtr<'p, PyObject<'p>>>; + fn to_py_object(&self, py: Python<'p>) -> PyResult<'p, Self::PointerType>; + //fn to_py_object(&self, py: Python<'p>) -> PyResult<'p, PyPtr<'p, PyObject<'p>>>; } /// BorrowAsPyObject is implemented for types that can be accessed as a borrowed python object @@ -31,6 +31,8 @@ trait BorrowAsPyObject<'p> for Sized? { // impl ToPyObject for BorrowAsPyObject impl <'p, T : BorrowAsPyObject<'p>> ToPyObject<'p> for T { + type PointerType = PyPtr<'p, PyObject<'p>>; + #[inline] fn to_py_object(&self, py: Python<'p>) -> PyResult<'p, PyPtr<'p, PyObject<'p>>> { Ok(PyPtr::new(self.as_py_object(py))) @@ -103,6 +105,8 @@ impl <'p, 'a> FromPyObject<'p, 'a> for bool { // When converting strings to/from python, we need to copy the string data. // This means we can implement ToPyObject for str, but FromPyObject only for String. impl <'p> ToPyObject<'p> for str { + type PointerType = PyPtr<'p, PyObject<'p>>; + fn to_py_object(&self, py : Python<'p>) -> PyResult<'p, PyPtr<'p, PyObject<'p>>> { let ptr : *const c_char = self.as_ptr() as *const _; let len : ffi::Py_ssize_t = std::num::from_uint(self.len()).unwrap(); diff --git a/src/err.rs b/src/err.rs index 99395ee9..6eff81b6 100644 --- a/src/err.rs +++ b/src/err.rs @@ -1,5 +1,5 @@ use std; -use {PyObject, PythonObject, PyTypeObject, Python, PyPtr}; +use {PyObject, PythonObject, PyType, Python, PyPtr}; use pyptr::PythonPointer; use ffi; use libc; @@ -48,7 +48,7 @@ impl <'p> PyErr<'p> { } #[allow(unused_variables)] - pub fn type_error(obj : &PyObject<'p>, expected_type : &PyTypeObject<'p>) -> PyErr<'p> { + pub fn type_error(obj : &PyObject<'p>, expected_type : &PyType<'p>) -> PyErr<'p> { let py = obj.python(); PyErr { ptype: Some(unsafe { PyPtr::from_borrowed_ptr(py, ffi::PyExc_TypeError) }), diff --git a/src/lib.rs b/src/lib.rs index b6ff8c1a..16217227 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,7 @@ pub use err::{PyErr, PyResult}; pub use python::Python; pub use pythonrun::PythonInterpreter; pub use object::{PythonObject, PyObject, ObjectProtocol}; -pub use typeobject::PyTypeObject; +pub use typeobject::PyType; pub use pyptr::PyPtr; pub use module::PyModule; pub use conversion::{FromPyObject, ToPyObject}; diff --git a/src/module.rs b/src/module.rs index 04bc6e40..16615471 100644 --- a/src/module.rs +++ b/src/module.rs @@ -1,8 +1,6 @@ use std; use ffi; -//use ffi::CStringAsPtr; -//use {PyResult, PyErr, FromPyObject, PyTypeObject, ToPyObject, PyObject, Python, PyPtr, PythonObject}; -use {Python, PyPtr, PyResult, PyObject, PythonObject, PyTypeObject}; +use {Python, PyPtr, PyResult, PyObject, PythonObject, PyType}; use err; pub struct PyModule<'p>(PyObject<'p>); @@ -22,7 +20,7 @@ impl <'p> PythonObject<'p> for PyModule<'p> { &self.0 } - fn type_object(_ : Option<&Self>) -> &'p PyTypeObject<'p> { + fn type_object(_ : Option<&Self>) -> &'p PyType<'p> { panic!() } } diff --git a/src/object.rs b/src/object.rs index 5d434d18..880015a8 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,10 +1,10 @@ -//use {PythonObject, PyPtr, PyResult, PyTypeObject, Python}; use std; use std::cmp::Ordering; use libc; use ffi; -use {Python, Py_ssize_t, PyResult, PyErr, PyPtr, ToPyObject}; -use typeobject::PyTypeObject; +use {Python, Py_ssize_t, PyResult, PyErr, ToPyObject}; +use typeobject::PyType; +use pyptr::{PyPtr, PythonPointer, as_ptr}; use err; /// Trait implemented by all python object types. @@ -23,7 +23,7 @@ pub trait PythonObject<'p> { /// Retrieves the type object for this python object type. /// unused_self is necessary until UFCS is implemented. - fn type_object(unused_self : Option<&Self>) -> &'p PyTypeObject<'p>; + fn type_object(unused_self : Option<&Self>) -> &'p PyType<'p>; /// Retrieve python instance from an existing python object. fn python(&self) -> Python<'p> { @@ -58,7 +58,7 @@ impl <'p> PythonObject<'p> for PyObject<'p> { self.py } - fn type_object(_ : Option<&Self>) -> &'p PyTypeObject<'p> { + fn type_object(_ : Option<&Self>) -> &'p PyType<'p> { panic!() } } @@ -82,8 +82,8 @@ impl <'p> PyObject<'p> { unsafe { ffi::Py_REFCNT(self.as_ptr()) } } - /*pub fn get_type(&self) -> &PyTypeObject { - unsafe { PyTypeObject::from_type_ptr(self.python(), ffi::Py_TYPE(self.as_ptr())) } + /*pub fn get_type(&self) -> &PyType { + unsafe { PyType::from_type_ptr(self.python(), ffi::Py_TYPE(self.as_ptr())) } }*/ /// Casts the PyObject to a concrete python object type. @@ -120,7 +120,7 @@ pub trait ObjectProtocol<'p> : PythonObject<'p> { let py = self.python(); let attr_name = try!(attr_name.to_py_object(py)); unsafe { - Ok(ffi::PyObject_HasAttr(self.as_ptr(), attr_name.as_ptr()) != 0) + Ok(ffi::PyObject_HasAttr(self.as_ptr(), as_ptr(&attr_name)) != 0) } } @@ -131,7 +131,8 @@ pub trait ObjectProtocol<'p> : PythonObject<'p> { let py = self.python(); let attr_name = try!(attr_name.to_py_object(py)); unsafe { - err::result_from_owned_ptr(py, ffi::PyObject_GetAttr(self.as_ptr(), attr_name.as_ptr())) + err::result_from_owned_ptr(py, + ffi::PyObject_GetAttr(self.as_ptr(), as_ptr(&attr_name))) } } @@ -145,7 +146,7 @@ pub trait ObjectProtocol<'p> : PythonObject<'p> { let value = try!(value.to_py_object(py)); unsafe { err::result_from_error_code(py, - ffi::PyObject_SetAttr(self.as_ptr(), attr_name.as_ptr(), value.as_ptr())) + ffi::PyObject_SetAttr(self.as_ptr(), as_ptr(&attr_name), as_ptr(&value))) } } @@ -157,13 +158,13 @@ pub trait ObjectProtocol<'p> : PythonObject<'p> { let attr_name = try!(attr_name.to_py_object(py)); unsafe { err::result_from_error_code(py, - ffi::PyObject_DelAttr(self.as_ptr(), attr_name.as_ptr())) + ffi::PyObject_DelAttr(self.as_ptr(), as_ptr(&attr_name))) } } /// Compares two python objects. /// This is equivalent to the python expression 'cmp(self, other)'. - fn compare(&self, other : &PyObject<'p>) -> PyResult<'p, Ordering> { + fn compare(&self, other: &PyObject<'p>) -> PyResult<'p, Ordering> { unsafe { let mut result : libc::c_int = std::mem::uninitialized(); try!(err::result_from_error_code(self.python(), diff --git a/src/pyptr.rs b/src/pyptr.rs index 84eafcfe..bdf23a52 100644 --- a/src/pyptr.rs +++ b/src/pyptr.rs @@ -79,6 +79,16 @@ pub trait PythonPointer { fn steal_ptr(self) -> *mut ffi::PyObject; } +/// Workaround because 'p.as_ptr()' doesn't work for associated types. +pub fn as_ptr(p: &P) -> *mut ffi::PyObject { + PythonPointer::as_ptr(p) +} + +/// Workaround because 'p.steal_ptr()' doesn't work for associated types. +pub fn steal_ptr(p: P) -> *mut ffi::PyObject { + PythonPointer::steal_ptr(p) +} + impl <'p, T : 'p + PythonObject<'p>> PythonPointer for PyPtr<'p, T> { #[inline] fn as_ptr(&self) -> *mut ffi::PyObject { diff --git a/src/typeobject.rs b/src/typeobject.rs index 2980e4ef..0a89c4b8 100644 --- a/src/typeobject.rs +++ b/src/typeobject.rs @@ -4,14 +4,14 @@ use ffi; use libc::c_char; use std; -pub struct PyTypeObject<'p> { +pub struct PyType<'p> { cell : std::cell::UnsafeCell, py : Python<'p> } -impl <'p> PythonObject<'p> for PyTypeObject<'p> { +impl <'p> PythonObject<'p> for PyType<'p> { #[inline] - fn from_object<'a>(obj : &'a PyObject<'p>) -> Option<&'a PyTypeObject<'p>> { + fn from_object<'a>(obj : &'a PyObject<'p>) -> Option<&'a PyType<'p>> { unsafe { if ffi::PyType_Check(obj.as_ptr()) { Some(std::mem::transmute(obj)) @@ -31,24 +31,24 @@ impl <'p> PythonObject<'p> for PyTypeObject<'p> { self.py } - fn type_object(_ : Option<&Self>) -> &'p PyTypeObject<'p> { + fn type_object(_ : Option<&Self>) -> &'p PyType<'p> { panic!() } } /* -impl PyTypeObject { +impl PyType { pub fn as_type_ptr(&self) -> *mut ffi::PyTypeObjectRaw { // safe because the PyObject is only accessed while holding the GIL (unsafe { self.cell.get() }) } - pub unsafe fn from_type_ptr(_ : &Python, p : *mut ffi::PyTypeObjectRaw) -> &PyTypeObject { + pub unsafe fn from_type_ptr(_ : &Python, p : *mut ffi::PyTypeObjectRaw) -> &PyType { debug_assert!(p.is_not_null()) - &*(p as *mut PyTypeObject) + &*(p as *mut PyType) } /// Return true if self is a subtype of b. - pub fn is_subtype_of(&self, b : &PyTypeObject) -> bool { + pub fn is_subtype_of(&self, b : &PyType) -> bool { unsafe { ffi::PyType_IsSubtype(self.as_type_ptr(), b.as_type_ptr()) != 0 } }