Merge pull request #3678 from davidhewitt/mapping2
implement `PyMappingMethods`
This commit is contained in:
commit
7f626b26d4
|
@ -32,5 +32,6 @@ pub use crate::wrap_pyfunction;
|
|||
// pub(crate) use crate::types::bytes::PyBytesMethods;
|
||||
// pub(crate) use crate::types::dict::PyDictMethods;
|
||||
// pub(crate) use crate::types::float::PyFloatMethods;
|
||||
// pub(crate) use crate::types::mapping::PyMappingMethods;
|
||||
// pub(crate) use crate::types::sequence::PySequenceMethods;
|
||||
// pub(crate) use crate::types::string::PyStringMethods;
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
use crate::err::{PyDowncastError, PyResult};
|
||||
use crate::ffi_ptr_ext::FfiPtrExt;
|
||||
use crate::instance::Py2;
|
||||
use crate::py_result_ext::PyResultExt;
|
||||
use crate::sync::GILOnceCell;
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::types::any::PyAnyMethods;
|
||||
use crate::types::{PyAny, PyDict, PySequence, PyType};
|
||||
use crate::{ffi, Py, PyNativeType, PyTypeCheck, Python, ToPyObject};
|
||||
|
||||
|
@ -16,15 +20,13 @@ impl PyMapping {
|
|||
/// This is equivalent to the Python expression `len(self)`.
|
||||
#[inline]
|
||||
pub fn len(&self) -> PyResult<usize> {
|
||||
let v = unsafe { ffi::PyMapping_Size(self.as_ptr()) };
|
||||
crate::err::error_on_minusone(self.py(), v)?;
|
||||
Ok(v as usize)
|
||||
Py2::borrowed_from_gil_ref(&self).len()
|
||||
}
|
||||
|
||||
/// Returns whether the mapping is empty.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> PyResult<bool> {
|
||||
self.len().map(|l| l == 0)
|
||||
Py2::borrowed_from_gil_ref(&self).is_empty()
|
||||
}
|
||||
|
||||
/// Determines if the mapping contains the specified key.
|
||||
|
@ -34,7 +36,7 @@ impl PyMapping {
|
|||
where
|
||||
K: ToPyObject,
|
||||
{
|
||||
PyAny::contains(self, key)
|
||||
Py2::borrowed_from_gil_ref(&self).contains(key)
|
||||
}
|
||||
|
||||
/// Gets the item in self with key `key`.
|
||||
|
@ -47,7 +49,9 @@ impl PyMapping {
|
|||
where
|
||||
K: ToPyObject,
|
||||
{
|
||||
PyAny::get_item(self, key)
|
||||
Py2::borrowed_from_gil_ref(&self)
|
||||
.get_item(key)
|
||||
.map(Py2::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Sets the item in self with key `key`.
|
||||
|
@ -59,7 +63,7 @@ impl PyMapping {
|
|||
K: ToPyObject,
|
||||
V: ToPyObject,
|
||||
{
|
||||
PyAny::set_item(self, key, value)
|
||||
Py2::borrowed_from_gil_ref(&self).set_item(key, value)
|
||||
}
|
||||
|
||||
/// Deletes the item with key `key`.
|
||||
|
@ -70,34 +74,31 @@ impl PyMapping {
|
|||
where
|
||||
K: ToPyObject,
|
||||
{
|
||||
PyAny::del_item(self, key)
|
||||
Py2::borrowed_from_gil_ref(&self).del_item(key)
|
||||
}
|
||||
|
||||
/// Returns a sequence containing all keys in the mapping.
|
||||
#[inline]
|
||||
pub fn keys(&self) -> PyResult<&PySequence> {
|
||||
unsafe {
|
||||
self.py()
|
||||
.from_owned_ptr_or_err(ffi::PyMapping_Keys(self.as_ptr()))
|
||||
}
|
||||
Py2::borrowed_from_gil_ref(&self)
|
||||
.keys()
|
||||
.map(Py2::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Returns a sequence containing all values in the mapping.
|
||||
#[inline]
|
||||
pub fn values(&self) -> PyResult<&PySequence> {
|
||||
unsafe {
|
||||
self.py()
|
||||
.from_owned_ptr_or_err(ffi::PyMapping_Values(self.as_ptr()))
|
||||
}
|
||||
Py2::borrowed_from_gil_ref(&self)
|
||||
.values()
|
||||
.map(Py2::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Returns a sequence of tuples of all (key, value) pairs in the mapping.
|
||||
#[inline]
|
||||
pub fn items(&self) -> PyResult<&PySequence> {
|
||||
unsafe {
|
||||
self.py()
|
||||
.from_owned_ptr_or_err(ffi::PyMapping_Items(self.as_ptr()))
|
||||
}
|
||||
Py2::borrowed_from_gil_ref(&self)
|
||||
.items()
|
||||
.map(Py2::into_gil_ref)
|
||||
}
|
||||
|
||||
/// Register a pyclass as a subclass of `collections.abc.Mapping` (from the Python standard
|
||||
|
@ -110,6 +111,135 @@ impl PyMapping {
|
|||
}
|
||||
}
|
||||
|
||||
/// Implementation of functionality for [`PyMapping`].
|
||||
///
|
||||
/// These methods are defined for the `Py2<'py, PyMapping>` smart pointer, so to use method call
|
||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||
/// `arbitrary_self_types`.
|
||||
#[doc(alias = "PyMapping")]
|
||||
pub(crate) trait PyMappingMethods<'py> {
|
||||
/// Returns the number of objects in the mapping.
|
||||
///
|
||||
/// This is equivalent to the Python expression `len(self)`.
|
||||
fn len(&self) -> PyResult<usize>;
|
||||
|
||||
/// Returns whether the mapping is empty.
|
||||
fn is_empty(&self) -> PyResult<bool>;
|
||||
|
||||
/// Determines if the mapping contains the specified key.
|
||||
///
|
||||
/// This is equivalent to the Python expression `key in self`.
|
||||
fn contains<K>(&self, key: K) -> PyResult<bool>
|
||||
where
|
||||
K: ToPyObject;
|
||||
|
||||
/// Gets the item in self with key `key`.
|
||||
///
|
||||
/// Returns an `Err` if the item with specified key is not found, usually `KeyError`.
|
||||
///
|
||||
/// This is equivalent to the Python expression `self[key]`.
|
||||
fn get_item<K>(&self, key: K) -> PyResult<Py2<'py, PyAny>>
|
||||
where
|
||||
K: ToPyObject;
|
||||
|
||||
/// Sets the item in self with key `key`.
|
||||
///
|
||||
/// This is equivalent to the Python expression `self[key] = value`.
|
||||
fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
|
||||
where
|
||||
K: ToPyObject,
|
||||
V: ToPyObject;
|
||||
|
||||
/// Deletes the item with key `key`.
|
||||
///
|
||||
/// This is equivalent to the Python statement `del self[key]`.
|
||||
fn del_item<K>(&self, key: K) -> PyResult<()>
|
||||
where
|
||||
K: ToPyObject;
|
||||
|
||||
/// Returns a sequence containing all keys in the mapping.
|
||||
fn keys(&self) -> PyResult<Py2<'py, PySequence>>;
|
||||
|
||||
/// Returns a sequence containing all values in the mapping.
|
||||
fn values(&self) -> PyResult<Py2<'py, PySequence>>;
|
||||
|
||||
/// Returns a sequence of tuples of all (key, value) pairs in the mapping.
|
||||
fn items(&self) -> PyResult<Py2<'py, PySequence>>;
|
||||
}
|
||||
|
||||
impl<'py> PyMappingMethods<'py> for Py2<'py, PyMapping> {
|
||||
#[inline]
|
||||
fn len(&self) -> PyResult<usize> {
|
||||
let v = unsafe { ffi::PyMapping_Size(self.as_ptr()) };
|
||||
crate::err::error_on_minusone(self.py(), v)?;
|
||||
Ok(v as usize)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_empty(&self) -> PyResult<bool> {
|
||||
self.len().map(|l| l == 0)
|
||||
}
|
||||
|
||||
fn contains<K>(&self, key: K) -> PyResult<bool>
|
||||
where
|
||||
K: ToPyObject,
|
||||
{
|
||||
PyAnyMethods::contains(&**self, key)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_item<K>(&self, key: K) -> PyResult<Py2<'py, PyAny>>
|
||||
where
|
||||
K: ToPyObject,
|
||||
{
|
||||
PyAnyMethods::get_item(&**self, key)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
|
||||
where
|
||||
K: ToPyObject,
|
||||
V: ToPyObject,
|
||||
{
|
||||
PyAnyMethods::set_item(&**self, key, value)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn del_item<K>(&self, key: K) -> PyResult<()>
|
||||
where
|
||||
K: ToPyObject,
|
||||
{
|
||||
PyAnyMethods::del_item(&**self, key)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn keys(&self) -> PyResult<Py2<'py, PySequence>> {
|
||||
unsafe {
|
||||
ffi::PyMapping_Keys(self.as_ptr())
|
||||
.assume_owned_or_err(self.py())
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn values(&self) -> PyResult<Py2<'py, PySequence>> {
|
||||
unsafe {
|
||||
ffi::PyMapping_Values(self.as_ptr())
|
||||
.assume_owned_or_err(self.py())
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn items(&self) -> PyResult<Py2<'py, PySequence>> {
|
||||
unsafe {
|
||||
ffi::PyMapping_Items(self.as_ptr())
|
||||
.assume_owned_or_err(self.py())
|
||||
.downcast_into_unchecked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static MAPPING_ABC: GILOnceCell<Py<PyType>> = GILOnceCell::new();
|
||||
|
||||
fn get_mapping_abc(py: Python<'_>) -> PyResult<&PyType> {
|
||||
|
|
|
@ -290,7 +290,7 @@ mod frozenset;
|
|||
mod function;
|
||||
mod iterator;
|
||||
pub(crate) mod list;
|
||||
mod mapping;
|
||||
pub(crate) mod mapping;
|
||||
mod memoryview;
|
||||
mod module;
|
||||
mod none;
|
||||
|
|
Loading…
Reference in a new issue