Skip to content

Commit b9efa9f

Browse files
author
Emanuel GS
committed
add PyDictProxy, see #221
1 parent 3b3b0e6 commit b9efa9f

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

python3-sys/src/descrobject.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use libc::{c_char, c_int, c_void};
22

33
use crate::methodobject::PyMethodDef;
4-
use crate::object::{PyObject, PyTypeObject};
4+
use crate::object::*;
55
use crate::structmember::PyMemberDef;
6+
use crate::pyport::Py_ssize_t;
67

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

@@ -32,6 +33,18 @@ impl Clone for PyGetSetDef {
3233
}
3334
}
3435

36+
37+
#[inline(always)]
38+
pub unsafe fn PyDictProxy_Check(op: *mut PyObject) -> c_int {
39+
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC)
40+
}
41+
42+
#[inline(always)]
43+
pub unsafe fn PyDictProxy_CheckExact(op: *mut PyObject) -> c_int {
44+
(Py_TYPE(op) == &mut PyDictProxy_Type) as c_int
45+
}
46+
47+
3548
#[cfg_attr(windows, link(name = "pythonXY"))]
3649
extern "C" {
3750
pub static mut PyClassMethodDescr_Type: PyTypeObject;

src/objects/descrobject.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use std::ptr;
2+
3+
use crate::conversion::ToPyObject;
4+
use crate::err::{self, PyErr, PyResult};
5+
use crate::ffi;
6+
use crate::objects::{PyObject, PyTuple};
7+
use crate::python::{Python, PythonObject, ToPythonPointer};
8+
9+
/// Represents a read-only Python dictionary
10+
pub struct PyDictProxy(PyObject);
11+
12+
pyobject_newtype!(PyDictProxy, PyDictProxy_Check, PyDictProxy_Type);
13+
14+
impl PyDictProxy {
15+
#[inline]
16+
pub fn len(&self, _py: Python) -> usize {
17+
unsafe { ffi::PyObject_Size(self.0.as_ptr()) as usize }
18+
}
19+
20+
pub fn get_item<K>(&self, py: Python, key: K) -> Option<PyObject>
21+
where
22+
K: ToPyObject,
23+
{
24+
key.with_borrowed_ptr(py, |key| unsafe {
25+
PyObject::from_borrowed_ptr_opt(py, ffi::PyObject_GetItem(self.0.as_ptr(), key))
26+
})
27+
}
28+
29+
pub fn contains<K>(&self, py: Python, key: K) -> PyResult<bool>
30+
where
31+
K: ToPyObject,
32+
{
33+
key.with_borrowed_ptr(py, |key| unsafe {
34+
match ffi::PyMapping_HasKey(self.0.as_ptr(), key) {
35+
1 => Ok(true),
36+
0 => Ok(false),
37+
_ => Err(PyErr::fetch(py)),
38+
}
39+
})
40+
}
41+
42+
pub fn keys(&self, py: Python) -> PyObject {
43+
// Returns a PySequence object
44+
unsafe {
45+
PyObject::from_borrowed_ptr(py, ffi::PyMapping_Keys(self.0.as_ptr()))
46+
}
47+
}
48+
49+
pub fn values(&self, py: Python) -> PyObject {
50+
// Returns a PySequence object
51+
unsafe {
52+
PyObject::from_borrowed_ptr(py, ffi::PyMapping_Values(self.0.as_ptr()))
53+
}
54+
}
55+
56+
pub fn items(&self, py: Python) -> PyObject {
57+
// Returns a PySequence object
58+
unsafe {
59+
PyObject::from_borrowed_ptr(py, ffi::PyMapping_Items(self.0.as_ptr()))
60+
}
61+
}
62+
}
63+
64+

src/objects/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub use self::num::{PyFloat, PyLong};
3939
pub use self::sequence::PySequence;
4040
pub use self::set::PySet;
4141
pub use self::tuple::{NoArgs, PyTuple};
42+
pub use self::descrobject::PyDictProxy;
4243

4344
#[macro_export]
4445
macro_rules! pyobject_newtype(
@@ -146,6 +147,7 @@ mod set;
146147
mod string;
147148
mod tuple;
148149
mod typeobject;
150+
mod descrobject;
149151

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

0 commit comments

Comments
 (0)