Skip to content

Commit

Permalink
add PyDictProxy, see dgrunwald#221
Browse files Browse the repository at this point in the history
  • Loading branch information
Emanuel GS committed Apr 25, 2020
1 parent 3b3b0e6 commit b9efa9f
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 1 deletion.
15 changes: 14 additions & 1 deletion python3-sys/src/descrobject.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use libc::{c_char, c_int, c_void};

use crate::methodobject::PyMethodDef;
use crate::object::{PyObject, PyTypeObject};
use crate::object::*;
use crate::structmember::PyMemberDef;
use crate::pyport::Py_ssize_t;

pub type getter = unsafe extern "C" fn(slf: *mut PyObject, closure: *mut c_void) -> *mut PyObject;

Expand Down Expand Up @@ -32,6 +33,18 @@ impl Clone for PyGetSetDef {
}
}


#[inline(always)]
pub unsafe fn PyDictProxy_Check(op: *mut PyObject) -> c_int {
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC)
}

#[inline(always)]
pub unsafe fn PyDictProxy_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == &mut PyDictProxy_Type) as c_int
}


#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
pub static mut PyClassMethodDescr_Type: PyTypeObject;
Expand Down
64 changes: 64 additions & 0 deletions src/objects/descrobject.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use std::ptr;

use crate::conversion::ToPyObject;
use crate::err::{self, PyErr, PyResult};
use crate::ffi;
use crate::objects::{PyObject, PyTuple};
use crate::python::{Python, PythonObject, ToPythonPointer};

/// Represents a read-only Python dictionary
pub struct PyDictProxy(PyObject);

pyobject_newtype!(PyDictProxy, PyDictProxy_Check, PyDictProxy_Type);

impl PyDictProxy {
#[inline]
pub fn len(&self, _py: Python) -> usize {
unsafe { ffi::PyObject_Size(self.0.as_ptr()) as usize }
}

pub fn get_item<K>(&self, py: Python, key: K) -> Option<PyObject>
where
K: ToPyObject,
{
key.with_borrowed_ptr(py, |key| unsafe {
PyObject::from_borrowed_ptr_opt(py, ffi::PyObject_GetItem(self.0.as_ptr(), key))
})
}

pub fn contains<K>(&self, py: Python, key: K) -> PyResult<bool>
where
K: ToPyObject,
{
key.with_borrowed_ptr(py, |key| unsafe {
match ffi::PyMapping_HasKey(self.0.as_ptr(), key) {
1 => Ok(true),
0 => Ok(false),
_ => Err(PyErr::fetch(py)),
}
})
}

pub fn keys(&self, py: Python) -> PyObject {
// Returns a PySequence object
unsafe {
PyObject::from_borrowed_ptr(py, ffi::PyMapping_Keys(self.0.as_ptr()))
}
}

pub fn values(&self, py: Python) -> PyObject {
// Returns a PySequence object
unsafe {
PyObject::from_borrowed_ptr(py, ffi::PyMapping_Values(self.0.as_ptr()))
}
}

pub fn items(&self, py: Python) -> PyObject {
// Returns a PySequence object
unsafe {
PyObject::from_borrowed_ptr(py, ffi::PyMapping_Items(self.0.as_ptr()))
}
}
}


2 changes: 2 additions & 0 deletions src/objects/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ pub use self::num::{PyFloat, PyLong};
pub use self::sequence::PySequence;
pub use self::set::PySet;
pub use self::tuple::{NoArgs, PyTuple};
pub use self::descrobject::PyDictProxy;

#[macro_export]
macro_rules! pyobject_newtype(
Expand Down Expand Up @@ -146,6 +147,7 @@ mod set;
mod string;
mod tuple;
mod typeobject;
mod descrobject;

#[cfg(feature = "python27-sys")]
pub mod oldstyle;
Expand Down

0 comments on commit b9efa9f

Please sign in to comment.