Skip to content

Commit

Permalink
Mappingproxy (#1)
Browse files Browse the repository at this point in the history
Adds in the MappingProxy type.
  • Loading branch information
KLMatlock authored Oct 22, 2024
1 parent 7909eb6 commit b2c4d76
Show file tree
Hide file tree
Showing 7 changed files with 667 additions and 10 deletions.
7 changes: 6 additions & 1 deletion pyo3-ffi/src/descrobject.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::methodobject::PyMethodDef;
use crate::object::{PyObject, PyTypeObject};
use crate::Py_ssize_t;
use crate::{PyObject_TypeCheck, Py_ssize_t};
use std::os::raw::{c_char, c_int, c_void};
use std::ptr;

Expand Down Expand Up @@ -68,6 +68,11 @@ extern "C" {
pub fn PyWrapper_New(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject;
}

#[inline]
pub unsafe fn PyDictProxy_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, std::ptr::addr_of_mut!(PyDictProxy_Type))
}

/// Represents the [PyMemberDef](https://docs.python.org/3/c-api/structures.html#c.PyMemberDef)
/// structure.
///
Expand Down
31 changes: 25 additions & 6 deletions src/conversions/std/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::ToPyObject;
use crate::{
conversion::IntoPyObject,
instance::Bound,
types::{any::PyAnyMethods, dict::PyDictMethods, PyDict},
types::{any::PyAnyMethods, dict::PyDictMethods, PyDict, PyMappingProxy},
FromPyObject, IntoPy, PyAny, PyErr, PyObject, Python,
};

Expand Down Expand Up @@ -162,9 +162,19 @@ where
S: hash::BuildHasher + Default,
{
fn extract_bound(ob: &Bound<'py, PyAny>) -> Result<Self, PyErr> {
let dict = ob.downcast::<PyDict>()?;
let mut ret = collections::HashMap::with_capacity_and_hasher(dict.len(), S::default());
for (k, v) in dict {
if let Ok(dict) = ob.downcast::<PyDict>() {
let mut ret = collections::HashMap::with_capacity_and_hasher(dict.len(), S::default());
for (k, v) in dict {
ret.insert(k.extract()?, v.extract()?);
}
return Ok(ret);
}

let mappingproxy = ob.downcast::<PyMappingProxy>()?;
let mut ret =
collections::HashMap::with_capacity_and_hasher(mappingproxy.len()?, S::default());
for res in mappingproxy.clone() {
let (k, v) = res?;
ret.insert(k.extract()?, v.extract()?);
}
Ok(ret)
Expand All @@ -182,9 +192,18 @@ where
V: FromPyObject<'py>,
{
fn extract_bound(ob: &Bound<'py, PyAny>) -> Result<Self, PyErr> {
let dict = ob.downcast::<PyDict>()?;
if let Ok(dict) = ob.downcast::<PyDict>() {
let mut ret = collections::BTreeMap::new();
for (k, v) in dict {
ret.insert(k.extract()?, v.extract()?);
}
return Ok(ret);
}

let mappingproxy = ob.downcast::<PyMappingProxy>()?;
let mut ret = collections::BTreeMap::new();
for (k, v) in dict {
for res in mappingproxy.clone() {
let (k, v) = res?;
ret.insert(k.extract()?, v.extract()?);
}
Ok(ret)
Expand Down
1 change: 1 addition & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub use crate::types::float::PyFloatMethods;
pub use crate::types::frozenset::PyFrozenSetMethods;
pub use crate::types::list::PyListMethods;
pub use crate::types::mapping::PyMappingMethods;
pub use crate::types::mappingproxy::PyMappingProxyMethods;
pub use crate::types::module::PyModuleMethods;
pub use crate::types::sequence::PySequenceMethods;
pub use crate::types::set::PySetMethods;
Expand Down
5 changes: 3 additions & 2 deletions src/sealed.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::types::{
PyBool, PyByteArray, PyBytes, PyCapsule, PyComplex, PyDict, PyFloat, PyFrozenSet, PyList,
PyMapping, PyModule, PySequence, PySet, PySlice, PyString, PyTraceback, PyTuple, PyType,
PyWeakref, PyWeakrefProxy, PyWeakrefReference,
PyMapping, PyMappingProxy, PyModule, PySequence, PySet, PySlice, PyString, PyTraceback,
PyTuple, PyType, PyWeakref, PyWeakrefProxy, PyWeakrefReference,
};
use crate::{ffi, Bound, PyAny, PyResult};

Expand Down Expand Up @@ -33,6 +33,7 @@ impl Sealed for Bound<'_, PyFloat> {}
impl Sealed for Bound<'_, PyFrozenSet> {}
impl Sealed for Bound<'_, PyList> {}
impl Sealed for Bound<'_, PyMapping> {}
impl Sealed for Bound<'_, PyMappingProxy> {}
impl Sealed for Bound<'_, PyModule> {}
impl Sealed for Bound<'_, PySequence> {}
impl Sealed for Bound<'_, PySet> {}
Expand Down
2 changes: 1 addition & 1 deletion src/types/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ where
}

/// Represents a tuple which can be used as a PyDict item.
trait PyDictItem<'py> {
pub trait PyDictItem<'py> {
type K: IntoPyObject<'py>;
type V: IntoPyObject<'py>;
fn unpack(self) -> (Self::K, Self::V);
Expand Down
Loading

0 comments on commit b2c4d76

Please sign in to comment.