Add methods for PyDict

This commit is contained in:
Daniel Grunwald 2015-05-24 22:45:43 +02:00
parent 7931e8f1f6
commit 0b712d0679
3 changed files with 70 additions and 10 deletions

View File

@ -175,12 +175,12 @@ pub trait ObjectProtocol<'p> : PythonObject<'p> {
/// Returns the length of the sequence or mapping. /// Returns the length of the sequence or mapping.
/// This is equivalent to the python expression: 'len(self)' /// This is equivalent to the python expression: 'len(self)'
#[inline] #[inline]
fn len(&self) -> PyResult<'p, ffi::Py_ssize_t> { fn len(&self) -> PyResult<'p, usize> {
let v = unsafe { ffi::PyObject_Size(self.as_ptr()) }; let v = unsafe { ffi::PyObject_Size(self.as_ptr()) };
if v == -1 { if v == -1 {
Err(PyErr::fetch(self.python())) Err(PyErr::fetch(self.python()))
} else { } else {
Ok(v) Ok(v as usize)
} }
} }

View File

@ -18,9 +18,10 @@
use std; use std;
use ffi; use ffi;
use python::{Python, PythonObject}; use python::{Python, ToPythonPointer, PythonObject};
use conversion::ToPyObject;
use objects::PyObject; use objects::PyObject;
use err::{self, PyResult}; use err::{self, PyResult, PyErr};
pyobject_newtype!(PyDict, PyDict_Check, PyDict_Type); pyobject_newtype!(PyDict, PyDict_Check, PyDict_Type);
@ -34,5 +35,68 @@ impl <'p> PyDict<'p> {
err::cast_from_owned_ptr_or_panic(py, ffi::PyDict_New()) err::cast_from_owned_ptr_or_panic(py, ffi::PyDict_New())
} }
} }
/// Return a new dictionary that contains the same key-value pairs as self.
pub fn copy(&self) -> PyResult<'p, PyDict<'p>> {
let py = self.python();
unsafe {
err::result_cast_from_owned_ptr(py, ffi::PyDict_Copy(self.as_ptr()))
}
}
/// Empty an existing dictionary of all key-value pairs.
#[inline]
pub fn clear(&self) {
unsafe { ffi::PyDict_Clear(self.as_ptr()) }
}
#[inline]
pub fn len(&self) -> usize {
unsafe { ffi::PyDict_Size(self.as_ptr()) as usize }
}
/// Determine if the dictionary contains the specified key.
/// This is equivalent to the Python expression `key in self`.
pub fn contains(&self, key: &PyObject<'p>) -> PyResult<'p, bool> {
let py = self.python();
unsafe {
match ffi::PyDict_Contains(self.as_ptr(), key.as_ptr()) {
1 => Ok(true),
0 => Ok(false),
_ => Err(PyErr::fetch(py))
}
}
}
/// Gets an item from the dictionary.
/// Returns None if the item is not present, or if an error occurs.
pub fn get_item<K>(&self, key: K) -> Option<PyObject<'p>> where K: ToPyObject<'p> {
let py = self.python();
key.with_borrowed_ptr(py, |key| unsafe {
PyObject::from_borrowed_ptr_opt(py,
ffi::PyDict_GetItem(self.as_ptr(), key))
})
}
/// Sets an item value.
/// This is equivalent to the Python expression `self[key] = value`.
pub fn set_item<K, V>(&self, key: K, value: V) -> PyResult<'p, ()> where K: ToPyObject<'p>, V: ToPyObject<'p> {
let py = self.python();
key.with_borrowed_ptr(py, move |key|
value.with_borrowed_ptr(py, |value| unsafe {
err::error_on_minusone(py,
ffi::PyDict_SetItem(self.as_ptr(), key, value))
}))
}
/// Deletes an item.
/// This is equivalent to the Python expression 'del self[key]'.
pub fn del_item<K>(&self, key: K) -> PyResult<'p, ()> where K: ToPyObject<'p> {
let py = self.python();
key.with_borrowed_ptr(py, |key| unsafe {
err::error_on_minusone(py,
ffi::PyDict_DelItem(self.as_ptr(), key))
})
}
} }

View File

@ -114,11 +114,7 @@ impl <'p> PyModule<'p> {
/// ///
/// This is a convenience function which can be used from the module's initialization function. /// This is a convenience function which can be used from the module's initialization function.
pub fn add<V>(&self, name: &str, value: V) -> PyResult<'p, ()> where V: ToPyObject<'p> { pub fn add<V>(&self, name: &str, value: V) -> PyResult<'p, ()> where V: ToPyObject<'p> {
let py = self.python(); self.dict().set_item(name, value)
let name = CString::new(name).unwrap();
let value = value.into_py_object(py);
let r = unsafe { ffi::PyModule_AddObject(self.as_ptr(), name.as_ptr(), value.steal_ptr()) };
err::error_on_minusone(py, r)
} }
} }