impl sequence protocol for mappingproxy

This commit is contained in:
Kangzhi Shi
2021-11-17 09:38:48 +02:00
committed by Jeong YunWon
parent 52b458d524
commit 5f0a58fbc6

View File

@@ -1,4 +1,6 @@
use super::{PyDict, PyGenericAlias, PyList, PyStrRef, PyTuple, PyTypeRef};
use std::borrow::Cow;
use super::{PyDict, PyGenericAlias, PyList, PyStr, PyStrRef, PyTuple, PyTypeRef};
use crate::{
function::{IntoPyObject, OptionalArg},
protocol::{PyMapping, PyMappingMethods},
@@ -54,7 +56,7 @@ impl Constructor for PyMappingProxy {
}
}
#[pyimpl(with(AsMapping, Iterable, Constructor))]
#[pyimpl(with(AsMapping, Iterable, Constructor, AsSequence))]
impl PyMappingProxy {
fn get_inner(&self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<PyObjectRef>> {
let opt = match &self.mapping {
@@ -85,20 +87,24 @@ impl PyMappingProxy {
.ok_or_else(|| vm.new_key_error(key))
}
#[pymethod(magic)]
pub fn contains(&self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult {
fn _contains(&self, key: &PyObject, vm: &VirtualMachine) -> PyResult<bool> {
match &self.mapping {
MappingProxyInner::Class(class) => {
let key = PyStrRef::try_from_object(vm, key)?;
Ok(vm
.ctx
.new_bool(class.attributes.read().contains_key(key.as_str()))
.into())
// let key = PyStrRef::try_from_object(vm, key)?;
let key = key
.payload::<PyStr>()
.ok_or_else(|| pyref_type_error(vm, PyStr::class(vm), key))?;
Ok(class.attributes.read().contains_key(key.as_str()))
}
MappingProxyInner::Dict(obj) => vm._membership(obj.clone(), key),
MappingProxyInner::Dict(obj) => PySequence::from(obj.as_ref()).contains(key, vm),
}
}
#[pymethod(magic)]
pub fn contains(&self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult<bool> {
self._contains(&key, vm)
}
#[pymethod]
pub fn items(&self, vm: &VirtualMachine) -> PyResult {
let obj = match &self.mapping {
@@ -171,6 +177,22 @@ impl AsMapping for PyMappingProxy {
}
}
impl AsSequence for PyMappingProxy {
fn as_sequence(
_zelf: &crate::PyObjectView<Self>,
_vm: &VirtualMachine,
) -> Cow<'static, PySequenceMethods> {
Cow::Borrowed(&Self::SEQUENCE_METHODS)
}
}
impl PyMappingProxy {
const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods {
contains: Some(|seq, target, vm| seq.obj_as::<Self>()._contains(target, vm)),
..*PySequenceMethods::not_implemented()
};
}
impl Iterable for PyMappingProxy {
fn iter(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
let obj = match &zelf.mapping {