2015-01-04 20:37:43 +00:00
|
|
|
use std;
|
|
|
|
use std::cmp::Ordering;
|
|
|
|
use ffi;
|
|
|
|
use libc;
|
2015-01-07 00:40:48 +00:00
|
|
|
use python::{Python, PythonObject, PythonObjectWithCheckedDowncast, ToPythonPointer};
|
2015-01-05 16:02:30 +00:00
|
|
|
use objects::PyObject;
|
2015-01-04 20:37:43 +00:00
|
|
|
use conversion::ToPyObject;
|
|
|
|
use err::{PyErr, PyResult, result_from_owned_ptr, error_on_minusone};
|
|
|
|
|
2015-01-05 20:14:01 +00:00
|
|
|
// Workaround because .as_ptr() doesn't work for associated types
|
|
|
|
#[inline]
|
2015-01-07 00:40:48 +00:00
|
|
|
fn as_ptr<O>(obj: &O) -> *mut ffi::PyObject where O: ToPythonPointer {
|
|
|
|
obj.as_ptr()
|
2015-01-05 20:14:01 +00:00
|
|
|
}
|
|
|
|
|
2015-01-04 20:37:43 +00:00
|
|
|
pub trait ObjectProtocol<'p> : PythonObject<'p> {
|
|
|
|
/// Determines whether this object has the given attribute.
|
|
|
|
/// This is equivalent to the Python expression 'hasattr(self, attr_name)'.
|
|
|
|
#[inline]
|
2015-01-05 20:14:01 +00:00
|
|
|
fn hasattr<N>(&self, attr_name: N) -> PyResult<'p, bool> where N: ToPyObject<'p> {
|
2015-01-07 00:40:48 +00:00
|
|
|
attr_name.with_borrowed_ptr(self.python(), |attr_name| unsafe {
|
|
|
|
Ok(ffi::PyObject_HasAttr(self.as_ptr(), attr_name) != 0)
|
2015-01-05 20:14:01 +00:00
|
|
|
})
|
2015-01-04 20:37:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Retrieves an attribute value.
|
|
|
|
/// This is equivalent to the Python expression 'self.attr_name'.
|
|
|
|
#[inline]
|
2015-01-07 00:40:48 +00:00
|
|
|
fn getattr<N>(&self, attr_name: N) -> PyResult<'p, PyObject<'p>> where N: ToPyObject<'p> {
|
2015-01-04 20:37:43 +00:00
|
|
|
let py = self.python();
|
2015-01-07 00:40:48 +00:00
|
|
|
attr_name.with_borrowed_ptr(py, |attr_name| unsafe {
|
2015-01-04 20:37:43 +00:00
|
|
|
result_from_owned_ptr(py,
|
2015-01-07 00:40:48 +00:00
|
|
|
ffi::PyObject_GetAttr(self.as_ptr(), attr_name))
|
2015-01-05 20:14:01 +00:00
|
|
|
})
|
2015-01-04 20:37:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Sets an attribute value.
|
|
|
|
/// This is equivalent to the Python expression 'self.attr_name = value'.
|
|
|
|
#[inline]
|
2015-01-05 20:14:01 +00:00
|
|
|
fn setattr<N, V>(&self, attr_name: N, value: V) -> PyResult<'p, ()>
|
|
|
|
where N: ToPyObject<'p>, V: ToPyObject<'p>
|
|
|
|
{
|
2015-01-04 20:37:43 +00:00
|
|
|
let py = self.python();
|
2015-01-07 00:40:48 +00:00
|
|
|
attr_name.with_borrowed_ptr(py, move |attr_name|
|
|
|
|
value.with_borrowed_ptr(py, |value| unsafe {
|
2015-01-05 20:14:01 +00:00
|
|
|
error_on_minusone(py,
|
2015-01-07 00:40:48 +00:00
|
|
|
ffi::PyObject_SetAttr(self.as_ptr(), attr_name, value))
|
2015-01-05 20:14:01 +00:00
|
|
|
}))
|
2015-01-04 20:37:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Deletes an attribute.
|
|
|
|
/// This is equivalent to the Python expression 'del self.attr_name'.
|
|
|
|
#[inline]
|
2015-01-05 20:14:01 +00:00
|
|
|
fn delattr<N>(&self, attr_name: N) -> PyResult<'p, ()> where N: ToPyObject<'p> {
|
2015-01-04 20:37:43 +00:00
|
|
|
let py = self.python();
|
2015-01-07 00:40:48 +00:00
|
|
|
attr_name.with_borrowed_ptr(py, |attr_name| unsafe {
|
2015-01-04 20:37:43 +00:00
|
|
|
error_on_minusone(py,
|
2015-01-07 00:40:48 +00:00
|
|
|
ffi::PyObject_DelAttr(self.as_ptr(), attr_name))
|
2015-01-05 20:14:01 +00:00
|
|
|
})
|
2015-01-04 20:37:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Compares two python objects.
|
|
|
|
/// This is equivalent to the python expression 'cmp(self, other)'.
|
|
|
|
#[inline]
|
2015-01-05 20:14:01 +00:00
|
|
|
fn compare<O>(&self, other: O) -> PyResult<'p, Ordering> where O: ToPyObject<'p> {
|
|
|
|
let py = self.python();
|
2015-01-07 00:40:48 +00:00
|
|
|
other.with_borrowed_ptr(py, |other| unsafe {
|
2015-01-04 20:37:43 +00:00
|
|
|
let mut result : libc::c_int = std::mem::uninitialized();
|
2015-01-05 20:14:01 +00:00
|
|
|
try!(error_on_minusone(py,
|
2015-01-07 00:40:48 +00:00
|
|
|
ffi::PyObject_Cmp(self.as_ptr(), other, &mut result)));
|
2015-01-04 20:37:43 +00:00
|
|
|
Ok(if result < 0 {
|
|
|
|
Ordering::Less
|
|
|
|
} else if result > 0 {
|
|
|
|
Ordering::Greater
|
|
|
|
} else {
|
|
|
|
Ordering::Equal
|
|
|
|
})
|
2015-01-05 20:14:01 +00:00
|
|
|
})
|
2015-01-04 20:37:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Compute the string representation of self.
|
|
|
|
/// This is equivalent to the python expression 'repr(self)'.
|
|
|
|
#[inline]
|
2015-01-07 00:40:48 +00:00
|
|
|
fn repr(&self) -> PyResult<'p, PyObject<'p>> {
|
2015-01-04 20:37:43 +00:00
|
|
|
unsafe {
|
|
|
|
result_from_owned_ptr(self.python(), ffi::PyObject_Repr(self.as_ptr()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Compute the string representation of self.
|
|
|
|
/// This is equivalent to the python expression 'str(self)'.
|
|
|
|
#[inline]
|
2015-01-07 00:40:48 +00:00
|
|
|
fn str(&self) -> PyResult<'p, PyObject<'p>> {
|
2015-01-04 20:37:43 +00:00
|
|
|
unsafe {
|
|
|
|
result_from_owned_ptr(self.python(), ffi::PyObject_Str(self.as_ptr()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Compute the unicode string representation of self.
|
|
|
|
/// This is equivalent to the python expression 'unistr(self)'.
|
|
|
|
#[inline]
|
2015-01-07 00:40:48 +00:00
|
|
|
fn unistr(&self) -> PyResult<'p, PyObject<'p>> {
|
2015-01-04 20:37:43 +00:00
|
|
|
unsafe {
|
|
|
|
result_from_owned_ptr(self.python(), ffi::PyObject_Unicode(self.as_ptr()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Determines whether this object is callable.
|
|
|
|
#[inline]
|
|
|
|
fn is_callable(&self) -> bool {
|
|
|
|
unsafe {
|
|
|
|
ffi::PyCallable_Check(self.as_ptr()) != 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Calls the object.
|
|
|
|
/// This is equivalent to the python expression: 'self(*args, **kw)'
|
|
|
|
#[inline]
|
2015-01-07 00:40:48 +00:00
|
|
|
fn call(&self, args: &PyObject<'p>, kw: Option<&PyObject<'p>>) -> PyResult<'p, PyObject<'p>> {
|
2015-01-04 20:37:43 +00:00
|
|
|
unimplemented!()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Calls a method on the object.
|
|
|
|
/// This is equivalent to the python expression: 'self.name(*args, **kw)'
|
|
|
|
#[inline]
|
|
|
|
fn call_method(&self, name: &str, args: &PyObject<'p>, kw: Option<&PyObject<'p>>)
|
2015-01-07 00:40:48 +00:00
|
|
|
-> PyResult<'p, PyObject<'p>> {
|
2015-01-04 20:37:43 +00:00
|
|
|
try!(self.getattr(name)).call(args, kw)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Retrieves the hash code of the object.
|
|
|
|
/// This is equivalent to the python expression: 'hash(self)'
|
|
|
|
#[inline]
|
|
|
|
fn hash(&self) -> PyResult<'p, libc::c_long> {
|
|
|
|
let v = unsafe { ffi::PyObject_Hash(self.as_ptr()) };
|
|
|
|
if v == -1 {
|
|
|
|
Err(PyErr::fetch(self.python()))
|
|
|
|
} else {
|
|
|
|
Ok(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns whether the object is considered to be true.
|
|
|
|
/// This is equivalent to the python expression: 'not not self'
|
|
|
|
#[inline]
|
|
|
|
fn is_true(&self) -> PyResult<'p, bool> {
|
|
|
|
let v = unsafe { ffi::PyObject_IsTrue(self.as_ptr()) };
|
|
|
|
if v == -1 {
|
|
|
|
Err(PyErr::fetch(self.python()))
|
|
|
|
} else {
|
|
|
|
Ok(v != 0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the length of the sequence or mapping.
|
|
|
|
/// This is equivalent to the python expression: 'len(self)'
|
|
|
|
#[inline]
|
|
|
|
fn len(&self) -> PyResult<'p, ffi::Py_ssize_t> {
|
|
|
|
let v = unsafe { ffi::PyObject_Size(self.as_ptr()) };
|
|
|
|
if v == -1 {
|
|
|
|
Err(PyErr::fetch(self.python()))
|
|
|
|
} else {
|
|
|
|
Ok(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// This is equivalent to the python expression: 'self[key]'
|
|
|
|
#[inline]
|
2015-01-07 00:40:48 +00:00
|
|
|
fn get_item<K>(&self, key: K) -> PyResult<'p, PyObject<'p>> where K: ToPyObject<'p> {
|
2015-01-05 20:14:01 +00:00
|
|
|
let py = self.python();
|
2015-01-07 00:40:48 +00:00
|
|
|
key.with_borrowed_ptr(py, |key| unsafe {
|
2015-01-04 20:37:43 +00:00
|
|
|
result_from_owned_ptr(py,
|
2015-01-07 00:40:48 +00:00
|
|
|
ffi::PyObject_GetItem(self.as_ptr(), key))
|
2015-01-05 20:14:01 +00:00
|
|
|
})
|
2015-01-04 20:37:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Sets an item value.
|
|
|
|
/// This is equivalent to the Python expression 'self[key] = value'.
|
|
|
|
#[inline]
|
2015-01-05 20:14:01 +00:00
|
|
|
fn set_item<K, V>(&self, key: K, value: V) -> PyResult<'p, ()> where K: ToPyObject<'p>, V: ToPyObject<'p> {
|
2015-01-04 20:37:43 +00:00
|
|
|
let py = self.python();
|
2015-01-07 00:40:48 +00:00
|
|
|
key.with_borrowed_ptr(py, move |key|
|
|
|
|
value.with_borrowed_ptr(py, |value| unsafe {
|
2015-01-05 20:14:01 +00:00
|
|
|
error_on_minusone(py,
|
2015-01-07 00:40:48 +00:00
|
|
|
ffi::PyObject_SetItem(self.as_ptr(), key, value))
|
2015-01-05 20:14:01 +00:00
|
|
|
}))
|
2015-01-04 20:37:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Deletes an item.
|
|
|
|
/// This is equivalent to the Python expression 'del self[key]'.
|
|
|
|
#[inline]
|
2015-01-05 20:14:01 +00:00
|
|
|
fn del_item<K>(&self, key: K) -> PyResult<'p, ()> where K: ToPyObject<'p> {
|
2015-01-04 20:37:43 +00:00
|
|
|
let py = self.python();
|
2015-01-07 00:40:48 +00:00
|
|
|
key.with_borrowed_ptr(py, |key| unsafe {
|
2015-01-04 20:37:43 +00:00
|
|
|
error_on_minusone(py,
|
2015-01-07 00:40:48 +00:00
|
|
|
ffi::PyObject_DelItem(self.as_ptr(), key))
|
2015-01-05 20:14:01 +00:00
|
|
|
})
|
2015-01-04 20:37:43 +00:00
|
|
|
}
|
2015-01-05 20:14:01 +00:00
|
|
|
/*
|
2015-01-04 20:37:43 +00:00
|
|
|
/// Takes an object and returns an iterator for it.
|
|
|
|
/// This is typically a new iterator but if the argument
|
|
|
|
/// is an iterator, this returns itself.
|
|
|
|
#[inline]
|
2015-01-05 15:34:12 +00:00
|
|
|
fn iter(&self) -> PyResult<'p, PyPtr<'p, PyIterator<'p>>> {
|
|
|
|
let it = try!(unsafe {
|
2015-01-04 20:37:43 +00:00
|
|
|
result_from_owned_ptr(self.python(), ffi::PyObject_GetIter(self.as_ptr()))
|
2015-01-05 15:34:12 +00:00
|
|
|
});
|
|
|
|
it.downcast_into()
|
2015-01-05 20:14:01 +00:00
|
|
|
}*/
|
2015-01-05 15:34:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl <'p> ObjectProtocol<'p> for PyObject<'p> {}
|
|
|
|
|
2015-01-05 20:14:01 +00:00
|
|
|
/*
|
2015-01-05 15:34:12 +00:00
|
|
|
pub struct PyIterator<'p>(PyObject<'p>);
|
|
|
|
|
|
|
|
impl <'p> PythonObject<'p> for PyIterator<'p> {
|
|
|
|
#[inline]
|
|
|
|
fn as_object<'a>(&'a self) -> &'a PyObject<'p> {
|
|
|
|
&self.0
|
2015-01-04 20:37:43 +00:00
|
|
|
}
|
|
|
|
|
2015-01-05 15:34:12 +00:00
|
|
|
#[inline]
|
|
|
|
unsafe fn unchecked_downcast_from<'a>(o: &'a PyObject<'p>) -> &'a PyIterator<'p> {
|
|
|
|
std::mem::transmute(o)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 20:14:01 +00:00
|
|
|
*/
|
2015-01-04 20:37:43 +00:00
|
|
|
|