Skip to content

Commit

Permalink
types: add dict views
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed May 11, 2022
1 parent 76c09ac commit 140fbd9
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Implement `ToPyObject` for `[T; N]`. [#2313](https://github.com/PyO3/pyo3/pull/2313)
- Added the internal `IntoPyResult` trait to give better error messages when function return types do not implement `IntoPy`. [#2326](https://github.com/PyO3/pyo3/pull/2326)
- Add `PyDictKeys`, `PyDictValues` and `PyDictItems` Rust types to represent `dict_keys`, `dict_values` and `dict_items` types. [#2358](https://github.com/PyO3/pyo3/pull/2358)

### Changed

Expand Down
85 changes: 78 additions & 7 deletions src/types/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,42 @@ pyobject_native_type!(
#checkfunction=ffi::PyDict_Check
);

/// Represents a Python `dict_keys`.
#[cfg(not(PyPy))]
#[repr(transparent)]
pub struct PyDictKeys(PyAny);

#[cfg(not(PyPy))]
pyobject_native_type_core!(
PyDictKeys,
ffi::PyDictKeys_Type,
#checkfunction=ffi::PyDictKeys_Check
);

/// Represents a Python `dict_values`.
#[cfg(not(PyPy))]
#[repr(transparent)]
pub struct PyDictValues(PyAny);

#[cfg(not(PyPy))]
pyobject_native_type_core!(
PyDictValues,
ffi::PyDictValues_Type,
#checkfunction=ffi::PyDictValues_Check
);

/// Represents a Python `dict_items`.
#[cfg(not(PyPy))]
#[repr(transparent)]
pub struct PyDictItems(PyAny);

#[cfg(not(PyPy))]
pyobject_native_type_core!(
PyDictItems,
ffi::PyDictItems_Type,
#checkfunction=ffi::PyDictItems_Check
);

impl PyDict {
/// Creates a new empty dictionary.
pub fn new(py: Python<'_>) -> &PyDict {
Expand Down Expand Up @@ -379,14 +415,10 @@ where

#[cfg(test)]
mod tests {
use crate::conversion::IntoPy;
use crate::types::dict::IntoPyDict;
use super::*;
#[cfg(not(PyPy))]
use crate::types::PyList;
use crate::types::{PyDict, PyTuple};
use crate::PyObject;
use crate::Python;
use crate::{PyTryFrom, ToPyObject};
use crate::{types::PyList, PyTypeInfo};
use crate::{types::PyTuple, IntoPy, PyObject, PyTryFrom, Python, ToPyObject};
use std::collections::{BTreeMap, HashMap};

#[test]
Expand Down Expand Up @@ -796,4 +828,43 @@ mod tests {
);
});
}

#[cfg(not(PyPy))]
fn abc_dict(py: Python<'_>) -> &PyDict {
let mut map = HashMap::<&'static str, i32>::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
map.into_py_dict(py)
}

#[test]
#[cfg(not(PyPy))]
fn dict_keys_view() {
Python::with_gil(|py| {
let dict = abc_dict(py);
let keys = dict.call_method0("keys").unwrap();
assert!(keys.is_instance(PyDictKeys::type_object(py)).unwrap());
})
}

#[test]
#[cfg(not(PyPy))]
fn dict_values_view() {
Python::with_gil(|py| {
let dict = abc_dict(py);
let values = dict.call_method0("values").unwrap();
assert!(values.is_instance(PyDictValues::type_object(py)).unwrap());
})
}

#[test]
#[cfg(not(PyPy))]
fn dict_items_view() {
Python::with_gil(|py| {
let dict = abc_dict(py);
let items = dict.call_method0("items").unwrap();
assert!(items.is_instance(PyDictItems::type_object(py)).unwrap());
})
}
}

0 comments on commit 140fbd9

Please sign in to comment.