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.
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, 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();

View File

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

View File

@ -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};

View File

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

View File

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

View File

@ -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: 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> {
#[inline]
fn as_ptr(&self) -> *mut ffi::PyObject {

View File

@ -4,14 +4,14 @@ use ffi;
use libc::c_char;
use std;
pub struct PyTypeObject<'p> {
pub struct PyType<'p> {
cell : std::cell::UnsafeCell<ffi::PyTypeObject>,
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 }
}