Rename PyTypeObject and use associated type for ToPyObject.

This commit is contained in:
Daniel Grunwald 2015-01-04 01:34:13 +01:00
parent 7ccf5c88f1
commit d247b138c5
7 changed files with 43 additions and 30 deletions

View File

@ -12,10 +12,10 @@ pub trait FromPyObject<'p, 'a> {
/// ToPyObject is implemented for types that can be converted into a python object. /// ToPyObject is implemented for types that can be converted into a python object.
pub trait ToPyObject<'p> for Sized? { pub trait ToPyObject<'p> for Sized? {
//type PointerType : 'p + PythonPointer + Deref<PyObject<'p>> = 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, 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, PyPtr<'p, PyObject<'p>>>;
} }
/// BorrowAsPyObject is implemented for types that can be accessed as a borrowed python object /// 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 ToPyObject for BorrowAsPyObject
impl <'p, T : BorrowAsPyObject<'p>> ToPyObject<'p> for T { impl <'p, T : BorrowAsPyObject<'p>> ToPyObject<'p> for T {
type PointerType = PyPtr<'p, PyObject<'p>>;
#[inline] #[inline]
fn to_py_object(&self, py: Python<'p>) -> PyResult<'p, PyPtr<'p, PyObject<'p>>> { fn to_py_object(&self, py: Python<'p>) -> PyResult<'p, PyPtr<'p, PyObject<'p>>> {
Ok(PyPtr::new(self.as_py_object(py))) 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. // 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. // This means we can implement ToPyObject for str, but FromPyObject only for String.
impl <'p> ToPyObject<'p> for str { 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>>> { 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 ptr : *const c_char = self.as_ptr() as *const _;
let len : ffi::Py_ssize_t = std::num::from_uint(self.len()).unwrap(); let len : ffi::Py_ssize_t = std::num::from_uint(self.len()).unwrap();

View File

@ -1,5 +1,5 @@
use std; use std;
use {PyObject, PythonObject, PyTypeObject, Python, PyPtr}; use {PyObject, PythonObject, PyType, Python, PyPtr};
use pyptr::PythonPointer; use pyptr::PythonPointer;
use ffi; use ffi;
use libc; use libc;
@ -48,7 +48,7 @@ impl <'p> PyErr<'p> {
} }
#[allow(unused_variables)] #[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(); let py = obj.python();
PyErr { PyErr {
ptype: Some(unsafe { PyPtr::from_borrowed_ptr(py, ffi::PyExc_TypeError) }), ptype: Some(unsafe { PyPtr::from_borrowed_ptr(py, ffi::PyExc_TypeError) }),

View File

@ -9,7 +9,7 @@ pub use err::{PyErr, PyResult};
pub use python::Python; pub use python::Python;
pub use pythonrun::PythonInterpreter; pub use pythonrun::PythonInterpreter;
pub use object::{PythonObject, PyObject, ObjectProtocol}; pub use object::{PythonObject, PyObject, ObjectProtocol};
pub use typeobject::PyTypeObject; pub use typeobject::PyType;
pub use pyptr::PyPtr; pub use pyptr::PyPtr;
pub use module::PyModule; pub use module::PyModule;
pub use conversion::{FromPyObject, ToPyObject}; pub use conversion::{FromPyObject, ToPyObject};

View File

@ -1,8 +1,6 @@
use std; use std;
use ffi; use ffi;
//use ffi::CStringAsPtr; use {Python, PyPtr, PyResult, PyObject, PythonObject, PyType};
//use {PyResult, PyErr, FromPyObject, PyTypeObject, ToPyObject, PyObject, Python, PyPtr, PythonObject};
use {Python, PyPtr, PyResult, PyObject, PythonObject, PyTypeObject};
use err; use err;
pub struct PyModule<'p>(PyObject<'p>); pub struct PyModule<'p>(PyObject<'p>);
@ -22,7 +20,7 @@ impl <'p> PythonObject<'p> for PyModule<'p> {
&self.0 &self.0
} }
fn type_object(_ : Option<&Self>) -> &'p PyTypeObject<'p> { fn type_object(_ : Option<&Self>) -> &'p PyType<'p> {
panic!() panic!()
} }
} }

View File

@ -1,10 +1,10 @@
//use {PythonObject, PyPtr, PyResult, PyTypeObject, Python};
use std; use std;
use std::cmp::Ordering; use std::cmp::Ordering;
use libc; use libc;
use ffi; use ffi;
use {Python, Py_ssize_t, PyResult, PyErr, PyPtr, ToPyObject}; use {Python, Py_ssize_t, PyResult, PyErr, ToPyObject};
use typeobject::PyTypeObject; use typeobject::PyType;
use pyptr::{PyPtr, PythonPointer, as_ptr};
use err; use err;
/// Trait implemented by all python object types. /// Trait implemented by all python object types.
@ -23,7 +23,7 @@ pub trait PythonObject<'p> {
/// Retrieves the type object for this python object type. /// Retrieves the type object for this python object type.
/// unused_self is necessary until UFCS is implemented. /// 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. /// Retrieve python instance from an existing python object.
fn python(&self) -> Python<'p> { fn python(&self) -> Python<'p> {
@ -58,7 +58,7 @@ impl <'p> PythonObject<'p> for PyObject<'p> {
self.py self.py
} }
fn type_object(_ : Option<&Self>) -> &'p PyTypeObject<'p> { fn type_object(_ : Option<&Self>) -> &'p PyType<'p> {
panic!() panic!()
} }
} }
@ -82,8 +82,8 @@ impl <'p> PyObject<'p> {
unsafe { ffi::Py_REFCNT(self.as_ptr()) } unsafe { ffi::Py_REFCNT(self.as_ptr()) }
} }
/*pub fn get_type(&self) -> &PyTypeObject { /*pub fn get_type(&self) -> &PyType {
unsafe { PyTypeObject::from_type_ptr(self.python(), ffi::Py_TYPE(self.as_ptr())) } unsafe { PyType::from_type_ptr(self.python(), ffi::Py_TYPE(self.as_ptr())) }
}*/ }*/
/// Casts the PyObject to a concrete python object type. /// Casts the PyObject to a concrete python object type.
@ -120,7 +120,7 @@ pub trait ObjectProtocol<'p> : PythonObject<'p> {
let py = self.python(); let py = self.python();
let attr_name = try!(attr_name.to_py_object(py)); let attr_name = try!(attr_name.to_py_object(py));
unsafe { 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 py = self.python();
let attr_name = try!(attr_name.to_py_object(py)); let attr_name = try!(attr_name.to_py_object(py));
unsafe { 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)); let value = try!(value.to_py_object(py));
unsafe { unsafe {
err::result_from_error_code(py, 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)); let attr_name = try!(attr_name.to_py_object(py));
unsafe { unsafe {
err::result_from_error_code(py, 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. /// Compares two python objects.
/// This is equivalent to the python expression 'cmp(self, other)'. /// 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 { unsafe {
let mut result : libc::c_int = std::mem::uninitialized(); let mut result : libc::c_int = std::mem::uninitialized();
try!(err::result_from_error_code(self.python(), try!(err::result_from_error_code(self.python(),

View File

@ -79,6 +79,16 @@ pub trait PythonPointer {
fn steal_ptr(self) -> *mut ffi::PyObject; fn steal_ptr(self) -> *mut ffi::PyObject;
} }
/// Workaround because 'p.as_ptr()' doesn't work for associated types.
pub fn as_ptr<P: PythonPointer>(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: PythonPointer>(p: P) -> *mut ffi::PyObject {
PythonPointer::steal_ptr(p)
}
impl <'p, T : 'p + PythonObject<'p>> PythonPointer for PyPtr<'p, T> { impl <'p, T : 'p + PythonObject<'p>> PythonPointer for PyPtr<'p, T> {
#[inline] #[inline]
fn as_ptr(&self) -> *mut ffi::PyObject { fn as_ptr(&self) -> *mut ffi::PyObject {

View File

@ -4,14 +4,14 @@ use ffi;
use libc::c_char; use libc::c_char;
use std; use std;
pub struct PyTypeObject<'p> { pub struct PyType<'p> {
cell : std::cell::UnsafeCell<ffi::PyTypeObject>, cell : std::cell::UnsafeCell<ffi::PyTypeObject>,
py : Python<'p> py : Python<'p>
} }
impl <'p> PythonObject<'p> for PyTypeObject<'p> { impl <'p> PythonObject<'p> for PyType<'p> {
#[inline] #[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 { unsafe {
if ffi::PyType_Check(obj.as_ptr()) { if ffi::PyType_Check(obj.as_ptr()) {
Some(std::mem::transmute(obj)) Some(std::mem::transmute(obj))
@ -31,24 +31,24 @@ impl <'p> PythonObject<'p> for PyTypeObject<'p> {
self.py self.py
} }
fn type_object(_ : Option<&Self>) -> &'p PyTypeObject<'p> { fn type_object(_ : Option<&Self>) -> &'p PyType<'p> {
panic!() panic!()
} }
} }
/* /*
impl PyTypeObject { impl PyType {
pub fn as_type_ptr(&self) -> *mut ffi::PyTypeObjectRaw { pub fn as_type_ptr(&self) -> *mut ffi::PyTypeObjectRaw {
// safe because the PyObject is only accessed while holding the GIL // safe because the PyObject is only accessed while holding the GIL
(unsafe { self.cell.get() }) (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()) debug_assert!(p.is_not_null())
&*(p as *mut PyTypeObject) &*(p as *mut PyType)
} }
/// Return true if self is a subtype of b. /// 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 } unsafe { ffi::PyType_IsSubtype(self.as_type_ptr(), b.as_type_ptr()) != 0 }
} }