mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 10:44:36 +08:00
add mapping protocol methods to update_slot
Signed-off-by: snowapril <sinjihng@gmail.com>
This commit is contained in:
1 parent
1fbbdaabe3
commit
6e11b8931c
1 file changed
+50
@@ -4,6 +4,7 @@ use super::{
|
||||
};
|
||||
use crate::common::{ascii, lock::PyRwLock};
|
||||
use crate::{
|
||||
builtins::dict::PyMapping,
|
||||
function::{FuncArgs, KwArgs, OptionalArg},
|
||||
protocol::PyIterReturn,
|
||||
slots::{self, Callable, PyTypeFlags, PyTypeSlots, SlotGetattro, SlotSetattro},
|
||||
@@ -12,6 +13,7 @@ use crate::{
|
||||
PyValue, TryFromObject, TypeProtocol, VirtualMachine,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use num_traits::ToPrimitive;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt;
|
||||
use std::ops::Deref;
|
||||
@@ -270,6 +272,54 @@ impl PyType {
|
||||
};
|
||||
update_slot!(iternext, func);
|
||||
}
|
||||
"__len__" | "__getitem__" | "__setitem__" | "__delitem__" => {
|
||||
macro_rules! then_some_closure {
|
||||
($cond:expr, $closure:expr) => {
|
||||
if $cond {
|
||||
Some($closure)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let func: slots::MappingFunc = |zelf, _vm| {
|
||||
Ok(PyMapping {
|
||||
length: then_some_closure!(zelf.has_class_attr("__len__"), |zelf, vm| {
|
||||
vm.call_special_method(zelf, "__len__", ()).map(|obj| {
|
||||
obj.payload_if_subclass::<PyInt>(vm)
|
||||
.map(|length_obj| {
|
||||
length_obj.as_bigint().to_usize().ok_or_else(|| {
|
||||
vm.new_value_error(
|
||||
"__len__() should return >= 0".to_owned(),
|
||||
)
|
||||
})
|
||||
})
|
||||
.unwrap()
|
||||
})?
|
||||
}),
|
||||
subscript: then_some_closure!(
|
||||
zelf.has_class_attr("__getitem__"),
|
||||
|zelf: PyObjectRef, needle: PyObjectRef, vm: &VirtualMachine| {
|
||||
vm.call_special_method(zelf, "__getitem__", (needle,))
|
||||
}
|
||||
),
|
||||
ass_subscript: then_some_closure!(
|
||||
zelf.has_class_attr("__setitem__") | zelf.has_class_attr("__delitem__"),
|
||||
|zelf, needle, value, vm| match value {
|
||||
Some(value) => vm
|
||||
.call_special_method(zelf, "__setitem__", (needle, value),)
|
||||
.map(|_| Ok(()))?,
|
||||
None => vm
|
||||
.call_special_method(zelf, "__delitem__", (needle,))
|
||||
.map(|_| Ok(()))?,
|
||||
}
|
||||
),
|
||||
})
|
||||
};
|
||||
update_slot!(as_mapping, func);
|
||||
// TODO: need to update sequence protocol too
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user