diff --git a/stdlib/src/array.rs b/stdlib/src/array.rs index 6984455aa..abf4065d9 100644 --- a/stdlib/src/array.rs +++ b/stdlib/src/array.rs @@ -12,12 +12,12 @@ mod array { }; use crate::vm::{ builtins::{ - dict::PyMapping, IntoPyFloat, PyByteArray, PyBytes, PyBytesRef, PyIntRef, PyList, - PyListRef, PySliceRef, PyStr, PyStrRef, PyTypeRef, + IntoPyFloat, PyByteArray, PyBytes, PyBytesRef, PyIntRef, PyList, PyListRef, PySliceRef, + PyStr, PyStrRef, PyTypeRef, }, class_or_notimplemented, function::{ArgBytesLike, ArgIterable, OptionalArg}, - protocol::{BufferInternal, BufferOptions, PyBuffer, PyIterReturn, ResizeGuard}, + protocol::{BufferInternal, BufferOptions, PyBuffer, PyIterReturn, PyMapping, ResizeGuard}, sliceable::{saturate_index, PySliceableSequence, PySliceableSequenceMut, SequenceIndex}, slots::{ AsBuffer, AsMapping, Comparable, Iterable, IteratorIterable, PyComparisonOp, diff --git a/vm/src/builtins/bytearray.rs b/vm/src/builtins/bytearray.rs index 77139f93f..26557401b 100644 --- a/vm/src/builtins/bytearray.rs +++ b/vm/src/builtins/bytearray.rs @@ -9,14 +9,13 @@ use crate::common::{ }; use crate::{ anystr::{self, AnyStr}, - builtins::dict::PyMapping, bytesinner::{ bytes_decode, bytes_from_object, value_from_object, ByteInnerFindOptions, ByteInnerNewOptions, ByteInnerPaddingOptions, ByteInnerSplitOptions, ByteInnerTranslateOptions, DecodeArgs, PyBytesInner, }, function::{ArgBytesLike, ArgIterable, FuncArgs, OptionalArg, OptionalOption}, - protocol::{BufferInternal, BufferOptions, PyBuffer, PyIterReturn, ResizeGuard}, + protocol::{BufferInternal, BufferOptions, PyBuffer, PyIterReturn, PyMapping, ResizeGuard}, sliceable::{PySliceableSequence, PySliceableSequenceMut, SequenceIndex}, slots::{ AsBuffer, AsMapping, Callable, Comparable, Hashable, Iterable, IteratorIterable, diff --git a/vm/src/builtins/bytes.rs b/vm/src/builtins/bytes.rs index 783763cc1..18ce64929 100644 --- a/vm/src/builtins/bytes.rs +++ b/vm/src/builtins/bytes.rs @@ -1,14 +1,13 @@ use super::{PyDictRef, PyIntRef, PyStrRef, PyTupleRef, PyTypeRef}; use crate::{ anystr::{self, AnyStr}, - builtins::dict::PyMapping, bytesinner::{ bytes_decode, ByteInnerFindOptions, ByteInnerNewOptions, ByteInnerPaddingOptions, ByteInnerSplitOptions, ByteInnerTranslateOptions, DecodeArgs, PyBytesInner, }, common::hash::PyHash, function::{ArgBytesLike, ArgIterable, OptionalArg, OptionalOption}, - protocol::{BufferInternal, BufferOptions, PyBuffer, PyIterReturn}, + protocol::{BufferInternal, BufferOptions, PyBuffer, PyIterReturn, PyMapping}, slots::{ AsBuffer, AsMapping, Callable, Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp, SlotConstructor, SlotIterator, diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index e9263b199..f856567be 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -4,7 +4,7 @@ use crate::{ common::ascii, dictdatatype::{self, DictKey}, function::{ArgIterable, FuncArgs, KwArgs, OptionalArg}, - protocol::PyIterReturn, + protocol::{PyIterReturn, PyMapping}, slots::{ AsMapping, Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp, SlotIterator, Unhashable, @@ -13,7 +13,7 @@ use crate::{ IdProtocol, IntoPyObject, ItemProtocol, PyArithmeticValue::*, PyAttributes, PyClassDef, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, - PyResult, PyValue, TryFromBorrowedObject, TypeProtocol, + PyResult, PyValue, TypeProtocol, }; use crossbeam_utils::atomic::AtomicCell; use std::fmt; @@ -935,36 +935,3 @@ pub(crate) fn init(context: &PyContext) { PyDictItemIterator::extend_class(context, &context.types.dict_itemiterator_type); PyDictReverseItemIterator::extend_class(context, &context.types.dict_reverseitemiterator_type); } - -#[allow(clippy::type_complexity)] -pub struct PyMapping { - pub length: Option PyResult>, - pub subscript: Option PyResult>, - pub ass_subscript: - Option, &VirtualMachine) -> PyResult<()>>, -} - -impl PyMapping { - pub fn check(cls: &PyObjectRef, vm: &VirtualMachine) -> bool { - if let Ok(mapping) = PyMapping::try_from_borrowed_object(vm, cls) { - mapping.subscript.is_some() - } else { - false - } - } -} - -impl TryFromBorrowedObject for PyMapping { - fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult { - let obj_cls = obj.class(); - for cls in obj_cls.iter_mro() { - if let Some(f) = cls.slots.as_mapping.load() { - return f(obj, vm); - } - } - Err(vm.new_type_error(format!( - "a dict-like object is required, not '{}'", - obj_cls.name() - ))) - } -} diff --git a/vm/src/builtins/list.rs b/vm/src/builtins/list.rs index e80d10e2b..34dd2c2bf 100644 --- a/vm/src/builtins/list.rs +++ b/vm/src/builtins/list.rs @@ -7,9 +7,8 @@ use crate::common::lock::{ PyMappedRwLockReadGuard, PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard, }; use crate::{ - builtins::dict::PyMapping, function::{ArgIterable, FuncArgs, OptionalArg}, - protocol::PyIterReturn, + protocol::{PyIterReturn, PyMapping}, sequence::{self, SimpleSeq}, sliceable::{PySliceableSequence, PySliceableSequenceMut, SequenceIndex}, slots::{ diff --git a/vm/src/builtins/mappingproxy.rs b/vm/src/builtins/mappingproxy.rs index bed79c4b1..035e5b376 100644 --- a/vm/src/builtins/mappingproxy.rs +++ b/vm/src/builtins/mappingproxy.rs @@ -1,7 +1,7 @@ use super::{PyDict, PyList, PyStrRef, PyTuple, PyTypeRef}; use crate::{ - builtins::dict::PyMapping, function::OptionalArg, + protocol::PyMapping, slots::{AsMapping, Iterable, SlotConstructor}, IntoPyObject, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol, VirtualMachine, diff --git a/vm/src/builtins/memory.rs b/vm/src/builtins/memory.rs index 4b682ddc2..fa8a2f98b 100644 --- a/vm/src/builtins/memory.rs +++ b/vm/src/builtins/memory.rs @@ -6,10 +6,9 @@ use crate::common::{ rc::PyRc, }; use crate::{ - builtins::dict::PyMapping, bytesinner::bytes_to_hex, function::{FuncArgs, OptionalArg}, - protocol::{BufferInternal, BufferOptions, PyBuffer}, + protocol::{BufferInternal, BufferOptions, PyBuffer, PyMapping}, sliceable::{convert_slice, wrap_index, SequenceIndex}, slots::{AsBuffer, AsMapping, Comparable, Hashable, PyComparisonOp, SlotConstructor}, stdlib::pystruct::FormatSpec, diff --git a/vm/src/builtins/pytype.rs b/vm/src/builtins/pytype.rs index 4415c95dd..bd8757cef 100644 --- a/vm/src/builtins/pytype.rs +++ b/vm/src/builtins/pytype.rs @@ -4,9 +4,8 @@ use super::{ }; use crate::common::{ascii, lock::PyRwLock}; use crate::{ - builtins::dict::PyMapping, function::{FuncArgs, KwArgs, OptionalArg}, - protocol::PyIterReturn, + protocol::{PyIterReturn, PyMapping}, slots::{self, Callable, PyTypeFlags, PyTypeSlots, SlotGetattro, SlotSetattro}, utils::Either, IdProtocol, PyAttributes, PyClassImpl, PyContext, PyLease, PyObjectRef, PyRef, PyResult, diff --git a/vm/src/builtins/range.rs b/vm/src/builtins/range.rs index 66187c6fa..792b29a2a 100644 --- a/vm/src/builtins/range.rs +++ b/vm/src/builtins/range.rs @@ -1,9 +1,8 @@ use super::{PyInt, PyIntRef, PySlice, PySliceRef, PyTypeRef}; use crate::common::hash::PyHash; use crate::{ - builtins::dict::PyMapping, function::{FuncArgs, OptionalArg}, - protocol::PyIterReturn, + protocol::{PyIterReturn, PyMapping}, slots::{ AsMapping, Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp, SlotIterator, }, diff --git a/vm/src/builtins/tuple.rs b/vm/src/builtins/tuple.rs index 1dab3a0e9..6e7199e70 100644 --- a/vm/src/builtins/tuple.rs +++ b/vm/src/builtins/tuple.rs @@ -3,11 +3,10 @@ use super::{ iter::IterStatus::{self, Active, Exhausted}, PyInt, PyTypeRef, }; -use crate::builtins::dict::PyMapping; use crate::common::hash::PyHash; use crate::{ function::OptionalArg, - protocol::PyIterReturn, + protocol::{PyIterReturn, PyMapping}, sequence::{self, SimpleSeq}, sliceable::PySliceableSequence, slots::{ diff --git a/vm/src/protocol/mapping.rs b/vm/src/protocol/mapping.rs new file mode 100644 index 000000000..3003edcc4 --- /dev/null +++ b/vm/src/protocol/mapping.rs @@ -0,0 +1,36 @@ +//! Mapping protocol + +use crate::{vm::VirtualMachine, PyObjectRef, PyResult, TryFromBorrowedObject, TypeProtocol}; + +#[allow(clippy::type_complexity)] +pub struct PyMapping { + pub length: Option PyResult>, + pub subscript: Option PyResult>, + pub ass_subscript: + Option, &VirtualMachine) -> PyResult<()>>, +} + +impl PyMapping { + pub fn check(cls: &PyObjectRef, vm: &VirtualMachine) -> bool { + if let Ok(mapping) = PyMapping::try_from_borrowed_object(vm, cls) { + mapping.subscript.is_some() + } else { + false + } + } +} + +impl TryFromBorrowedObject for PyMapping { + fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult { + let obj_cls = obj.class(); + for cls in obj_cls.iter_mro() { + if let Some(f) = cls.slots.as_mapping.load() { + return f(obj, vm); + } + } + Err(vm.new_type_error(format!( + "a dict-like object is required, not '{}'", + obj_cls.name() + ))) + } +} diff --git a/vm/src/protocol/mod.rs b/vm/src/protocol/mod.rs index 0c44ab754..eb4ff328c 100644 --- a/vm/src/protocol/mod.rs +++ b/vm/src/protocol/mod.rs @@ -1,5 +1,7 @@ mod buffer; mod iter; +mod mapping; pub use buffer::{BufferInternal, BufferOptions, PyBuffer, ResizeGuard}; pub use iter::{PyIter, PyIterReturn}; +pub(crate) use mapping::PyMapping; diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index e268f3204..5306d28a7 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -10,7 +10,6 @@ use crate::{ builtinfunc::PyNativeFuncDef, bytearray, bytes, code::{self, PyCode}, - dict::PyMapping, getset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet}, namespace::PyNamespace, object, pystr, @@ -21,6 +20,7 @@ use crate::{ dictdatatype::Dict, exceptions, function::{IntoFuncArgs, IntoPyNativeFunc}, + protocol::PyMapping, slots::{PyTypeFlags, PyTypeSlots}, types::{create_type_with_slots, TypeZoo}, VirtualMachine, diff --git a/vm/src/slots.rs b/vm/src/slots.rs index e5c5e7b22..7252cc30f 100644 --- a/vm/src/slots.rs +++ b/vm/src/slots.rs @@ -1,8 +1,8 @@ -use crate::builtins::{dict::PyMapping, PyStrRef, PyTypeRef}; +use crate::builtins::{PyStrRef, PyTypeRef}; use crate::common::hash::PyHash; use crate::common::lock::PyRwLock; use crate::function::{FromArgs, FuncArgs, OptionalArg}; -use crate::protocol::{PyBuffer, PyIterReturn}; +use crate::protocol::{PyBuffer, PyIterReturn, PyMapping}; use crate::utils::Either; use crate::VirtualMachine; use crate::{