add mapping protocol to proper types

This commit is contained in:
snowapril committed 2021-10-02 14:43:20 +09:00
1 parent 1b6cdf507e
commit fc761b4e5b
9 files changed
+317 -25

No files matched your search

+35 -5
View File
@@ -12,16 +12,16 @@ mod array {
};
use crate::vm::{
builtins::{
IntoPyFloat, PyByteArray, PyBytes, PyBytesRef, PyIntRef, PyList, PyListRef, PySliceRef,
PyStr, PyStrRef, PyTypeRef,
dict::PyMapping, IntoPyFloat, PyByteArray, PyBytes, PyBytesRef, PyIntRef, PyList,
PyListRef, PySliceRef, PyStr, PyStrRef, PyTypeRef,
},
class_or_notimplemented,
function::{ArgBytesLike, ArgIterable, OptionalArg},
protocol::{BufferInternal, BufferOptions, PyBuffer, PyIterReturn, ResizeGuard},
sliceable::{saturate_index, PySliceableSequence, PySliceableSequenceMut, SequenceIndex},
slots::{
AsBuffer, Comparable, Iterable, IteratorIterable, PyComparisonOp, SlotConstructor,
SlotIterator,
AsBuffer, AsMapping, Comparable, Iterable, IteratorIterable, PyComparisonOp,
SlotConstructor, SlotIterator,
},
IdProtocol, IntoPyObject, IntoPyResult, PyComparisonValue, PyObjectRef, PyRef, PyResult,
PyValue, TryFromObject, TypeProtocol, VirtualMachine,
@@ -665,7 +665,10 @@ mod array {
}
}
#[pyimpl(flags(BASETYPE), with(Comparable, AsBuffer, Iterable, SlotConstructor))]
#[pyimpl(
flags(BASETYPE),
with(Comparable, AsBuffer, AsMapping, Iterable, SlotConstructor)
)]
impl PyArray {
fn read(&self) -> PyRwLockReadGuard<'_, ArrayContentType> {
self.array.read()
@@ -1161,6 +1164,33 @@ mod array {
}
}
impl AsMapping for PyArray {
fn as_mapping(_zelf: &PyRef<Self>, _vm: &VirtualMachine) -> PyResult<PyMapping> {
Ok(PyMapping {
length: Some(Self::length),
subscript: Some(Self::subscript),
ass_subscript: Some(Self::ass_subscript),
})
}
fn length(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
Self::downcast_ref(&zelf, vm).map(|zelf| Ok(zelf.len()))?
}
fn subscript(zelf: PyObjectRef, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
Self::downcast_ref(&zelf, vm).map(|zelf| zelf.getitem(needle, vm))?
}
fn ass_subscript(
zelf: PyObjectRef,
needle: PyObjectRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
Self::downcast(zelf, vm).map(|zelf| Self::setitem(zelf, needle, value, vm))?
}
}
impl Iterable for PyArray {
fn iter(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
Ok(PyArrayIter {
+37 -3
View File
@@ -9,6 +9,7 @@ use crate::common::{
};
use crate::{
anystr::{self, AnyStr},
builtins::dict::PyMapping,
bytesinner::{
bytes_decode, bytes_from_object, value_from_object, ByteInnerFindOptions,
ByteInnerNewOptions, ByteInnerPaddingOptions, ByteInnerSplitOptions,
@@ -18,8 +19,8 @@ use crate::{
protocol::{BufferInternal, BufferOptions, PyBuffer, PyIterReturn, ResizeGuard},
sliceable::{PySliceableSequence, PySliceableSequenceMut, SequenceIndex},
slots::{
AsBuffer, Callable, Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp,
SlotIterator, Unhashable,
AsBuffer, AsMapping, Callable, Comparable, Hashable, Iterable, IteratorIterable,
PyComparisonOp, SlotIterator, Unhashable,
},
utils::Either,
IdProtocol, IntoPyObject, PyClassDef, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef,
@@ -95,7 +96,10 @@ pub(crate) fn init(context: &PyContext) {
PyByteArrayIterator::extend_class(context, &context.types.bytearray_iterator_type);
}
#[pyimpl(flags(BASETYPE), with(Hashable, Comparable, AsBuffer, Iterable))]
#[pyimpl(
flags(BASETYPE),
with(Hashable, Comparable, AsBuffer, AsMapping, Iterable)
)]
impl PyByteArray {
#[pyslot]
fn slot_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult {
@@ -712,6 +716,36 @@ impl<'a> ResizeGuard<'a> for PyByteArray {
}
}
impl AsMapping for PyByteArray {
fn as_mapping(_zelf: &PyRef<Self>, _vm: &VirtualMachine) -> PyResult<PyMapping> {
Ok(PyMapping {
length: Some(Self::length),
subscript: Some(Self::subscript),
ass_subscript: Some(Self::ass_subscript),
})
}
#[inline]
fn length(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
Self::downcast_ref(&zelf, vm).map(|zelf| Ok(zelf.len()))?
}
#[inline]
fn subscript(zelf: PyObjectRef, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
Self::downcast_ref(&zelf, vm).map(|zelf| zelf.getitem(needle, vm))?
}
#[inline]
fn ass_subscript(
zelf: PyObjectRef,
needle: PyObjectRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
Self::downcast(zelf, vm).map(|zelf| Self::setitem(zelf, needle, value, vm))?
}
}
impl Unhashable for PyByteArray {}
impl Iterable for PyByteArray {
+34 -3
View File
@@ -1,6 +1,7 @@
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,
@@ -9,8 +10,8 @@ use crate::{
function::{ArgBytesLike, ArgIterable, OptionalArg, OptionalOption},
protocol::{BufferInternal, BufferOptions, PyBuffer, PyIterReturn},
slots::{
AsBuffer, Callable, Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp,
SlotConstructor, SlotIterator,
AsBuffer, AsMapping, Callable, Comparable, Hashable, Iterable, IteratorIterable,
PyComparisonOp, SlotConstructor, SlotIterator,
},
utils::Either,
IdProtocol, IntoPyObject, IntoPyResult, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef,
@@ -103,7 +104,7 @@ impl SlotConstructor for PyBytes {
#[pyimpl(
flags(BASETYPE),
with(Hashable, Comparable, AsBuffer, Iterable, SlotConstructor)
with(AsMapping, Hashable, Comparable, AsBuffer, Iterable, SlotConstructor)
)]
impl PyBytes {
#[pymethod(magic)]
@@ -540,6 +541,36 @@ impl BufferInternal for PyRef<PyBytes> {
fn retain(&self) {}
}
impl AsMapping for PyBytes {
fn as_mapping(_zelf: &PyRef<Self>, _vm: &VirtualMachine) -> PyResult<PyMapping> {
Ok(PyMapping {
length: Some(Self::length),
subscript: Some(Self::subscript),
ass_subscript: None,
})
}
#[inline]
fn length(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
Self::downcast_ref(&zelf, vm).map(|zelf| Ok(zelf.len()))?
}
#[inline]
fn subscript(zelf: PyObjectRef, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
Self::downcast_ref(&zelf, vm).map(|zelf| zelf.getitem(needle, vm))?
}
#[inline]
fn ass_subscript(
zelf: PyObjectRef,
_needle: PyObjectRef,
_value: PyObjectRef,
_vm: &VirtualMachine,
) -> PyResult<()> {
unreachable!("ass_subscript not implemented for {}", zelf.class())
}
}
impl Hashable for PyBytes {
fn hash(zelf: &PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyHash> {
Ok(zelf.inner.hash(vm))
+33 -2
View File
@@ -6,7 +6,8 @@ use crate::{
function::{ArgIterable, FuncArgs, KwArgs, OptionalArg},
protocol::PyIterReturn,
slots::{
Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp, SlotIterator, Unhashable,
AsMapping, Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp, SlotIterator,
Unhashable,
},
vm::{ReprGuard, VirtualMachine},
IdProtocol, IntoPyObject, ItemProtocol,
@@ -51,7 +52,7 @@ impl PyValue for PyDict {
// Python dict methods:
#[allow(clippy::len_without_is_empty)]
#[pyimpl(with(Hashable, Comparable, Iterable), flags(BASETYPE))]
#[pyimpl(with(AsMapping, Hashable, Comparable, Iterable), flags(BASETYPE))]
impl PyDict {
#[pyslot]
fn slot_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult {
@@ -410,6 +411,36 @@ impl PyDict {
}
}
impl AsMapping for PyDict {
fn as_mapping(_zelf: &PyRef<Self>, _vm: &VirtualMachine) -> PyResult<PyMapping> {
Ok(PyMapping {
length: Some(Self::length),
subscript: Some(Self::subscript),
ass_subscript: Some(Self::ass_subscript),
})
}
#[inline]
fn length(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
Self::downcast_ref(&zelf, vm).map(|zelf| Ok(zelf.len()))?
}
#[inline]
fn subscript(zelf: PyObjectRef, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
Self::downcast(zelf, vm).map(|zelf| Self::getitem(zelf, needle, vm))?
}
#[inline]
fn ass_subscript(
zelf: PyObjectRef,
needle: PyObjectRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
Self::downcast_ref(&zelf, vm).map(|zelf| zelf.setitem(needle, value, vm))?
}
}
impl Comparable for PyDict {
fn cmp(
zelf: &PyRef<Self>,
+34 -2
View File
@@ -7,12 +7,14 @@ use crate::common::lock::{
PyMappedRwLockReadGuard, PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard,
};
use crate::{
builtins::dict::PyMapping,
function::{ArgIterable, FuncArgs, OptionalArg},
protocol::PyIterReturn,
sequence::{self, SimpleSeq},
sliceable::{PySliceableSequence, PySliceableSequenceMut, SequenceIndex},
slots::{
Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp, SlotIterator, Unhashable,
AsMapping, Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp, SlotIterator,
Unhashable,
},
utils::Either,
vm::{ReprGuard, VirtualMachine},
@@ -82,7 +84,7 @@ pub(crate) struct SortOptions {
pub type PyListRef = PyRef<PyList>;
#[pyimpl(with(Iterable, Hashable, Comparable), flags(BASETYPE))]
#[pyimpl(with(AsMapping, Iterable, Hashable, Comparable), flags(BASETYPE))]
impl PyList {
#[pymethod]
pub(crate) fn append(&self, x: PyObjectRef) {
@@ -416,6 +418,36 @@ impl PyList {
}
}
impl AsMapping for PyList {
fn as_mapping(_zelf: &PyRef<Self>, _vm: &VirtualMachine) -> PyResult<PyMapping> {
Ok(PyMapping {
length: Some(Self::length),
subscript: Some(Self::subscript),
ass_subscript: Some(Self::ass_subscript),
})
}
#[inline]
fn length(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
Self::downcast_ref(&zelf, vm).map(|zelf| Ok(zelf.len()))?
}
#[inline]
fn subscript(zelf: PyObjectRef, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
Self::downcast(zelf, vm).map(|zelf| Self::getitem(zelf, needle, vm))?
}
#[inline]
fn ass_subscript(
zelf: PyObjectRef,
needle: PyObjectRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
Self::downcast_ref(&zelf, vm).map(|zelf| zelf.setitem(needle, value, vm))?
}
}
impl Iterable for PyList {
fn iter(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
Ok(PyListIterator {
+35 -3
View File
@@ -1,9 +1,10 @@
use super::{PyDict, PyStrRef, PyTypeRef};
use crate::{
builtins::dict::PyMapping,
function::OptionalArg,
slots::{Iterable, SlotConstructor},
slots::{AsMapping, Iterable, SlotConstructor},
IntoPyObject, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
TryFromObject, VirtualMachine,
TryFromObject, TypeProtocol, VirtualMachine,
};
#[pyclass(module = false, name = "mappingproxy")]
@@ -43,7 +44,7 @@ impl SlotConstructor for PyMappingProxy {
}
}
#[pyimpl(with(Iterable, SlotConstructor))]
#[pyimpl(with(AsMapping, Iterable, SlotConstructor))]
impl PyMappingProxy {
fn get_inner(&self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<PyObjectRef>> {
let opt = match &self.mapping {
@@ -127,6 +128,37 @@ impl PyMappingProxy {
}
}
}
impl AsMapping for PyMappingProxy {
fn as_mapping(_zelf: &PyRef<Self>, _vm: &VirtualMachine) -> PyResult<PyMapping> {
Ok(PyMapping {
length: None,
subscript: Some(Self::subscript),
ass_subscript: None,
})
}
#[inline]
fn length(zelf: PyObjectRef, _vm: &VirtualMachine) -> PyResult<usize> {
unreachable!("length not implemented for {}", zelf.class())
}
#[inline]
fn subscript(zelf: PyObjectRef, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
Self::downcast_ref(&zelf, vm).map(|zelf| zelf.getitem(needle, vm))?
}
#[inline]
fn ass_subscript(
zelf: PyObjectRef,
_needle: PyObjectRef,
_value: PyObjectRef,
_vm: &VirtualMachine,
) -> PyResult<()> {
unreachable!("ass_subscript not implemented for {}", zelf.class())
}
}
impl Iterable for PyMappingProxy {
fn iter(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
let obj = match &zelf.mapping {
+36 -2
View File
@@ -6,11 +6,12 @@ use crate::common::{
rc::PyRc,
};
use crate::{
builtins::dict::PyMapping,
bytesinner::bytes_to_hex,
function::{FuncArgs, OptionalArg},
protocol::{BufferInternal, BufferOptions, PyBuffer},
sliceable::{convert_slice, wrap_index, SequenceIndex},
slots::{AsBuffer, Comparable, Hashable, PyComparisonOp, SlotConstructor},
slots::{AsBuffer, AsMapping, Comparable, Hashable, PyComparisonOp, SlotConstructor},
stdlib::pystruct::FormatSpec,
utils::Either,
IdProtocol, IntoPyObject, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef,
@@ -53,7 +54,7 @@ impl SlotConstructor for PyMemoryView {
}
}
#[pyimpl(with(Hashable, Comparable, AsBuffer, SlotConstructor))]
#[pyimpl(with(Hashable, Comparable, AsBuffer, AsMapping, SlotConstructor))]
impl PyMemoryView {
#[cfg(debug_assertions)]
fn validate(self) -> Self {
@@ -734,6 +735,39 @@ impl BufferInternal for PyRef<PyMemoryView> {
fn retain(&self) {}
}
impl AsMapping for PyMemoryView {
fn as_mapping(_zelf: &PyRef<Self>, _vm: &VirtualMachine) -> PyResult<PyMapping> {
Ok(PyMapping {
length: Some(Self::length),
subscript: Some(Self::subscript),
ass_subscript: Some(Self::ass_subscript),
})
}
#[inline]
fn length(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
Self::downcast_ref(&zelf, vm).map(|zelf| zelf.len(vm))?
}
#[inline]
fn subscript(zelf: PyObjectRef, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
Self::downcast(zelf, vm)
.map(|zelf| Self::getitem(zelf, SequenceIndex::try_from_object(vm, needle)?, vm))?
}
#[inline]
fn ass_subscript(
zelf: PyObjectRef,
needle: PyObjectRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
Self::downcast(zelf, vm).map(|zelf| {
Self::setitem(zelf, SequenceIndex::try_from_object(vm, needle)?, value, vm)
})?
}
}
impl Comparable for PyMemoryView {
fn cmp(
zelf: &PyRef<Self>,
+36 -2
View File
@@ -1,9 +1,12 @@
use super::{PyInt, PyIntRef, PySlice, PySliceRef, PyTypeRef};
use crate::common::hash::PyHash;
use crate::{
builtins::dict::PyMapping,
function::{FuncArgs, OptionalArg},
protocol::PyIterReturn,
slots::{Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp, SlotIterator},
slots::{
AsMapping, Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp, SlotIterator,
},
IdProtocol, IntoPyRef, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
TryFromObject, TypeProtocol, VirtualMachine,
};
@@ -173,7 +176,7 @@ pub fn init(context: &PyContext) {
PyRangeIterator::extend_class(context, &context.types.range_iterator_type);
}
#[pyimpl(with(Hashable, Comparable, Iterable))]
#[pyimpl(with(AsMapping, Hashable, Comparable, Iterable))]
impl PyRange {
fn new(cls: PyTypeRef, stop: PyIntRef, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
PyRange {
@@ -372,6 +375,37 @@ impl PyRange {
}
}
impl AsMapping for PyRange {
fn as_mapping(_zelf: &PyRef<Self>, _vm: &VirtualMachine) -> PyResult<PyMapping> {
Ok(PyMapping {
length: Some(Self::length),
subscript: Some(Self::subscript),
ass_subscript: None,
})
}
#[inline]
fn length(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
Self::downcast_ref(&zelf, vm).map(|zelf| Ok(zelf.len().to_usize().unwrap()))?
}
#[inline]
fn subscript(zelf: PyObjectRef, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
Self::downcast_ref(&zelf, vm)
.map(|zelf| zelf.getitem(RangeIndex::try_from_object(vm, needle)?, vm))?
}
#[inline]
fn ass_subscript(
zelf: PyObjectRef,
_needle: PyObjectRef,
_value: PyObjectRef,
_vm: &VirtualMachine,
) -> PyResult<()> {
unreachable!("ass_subscript not implemented for {}", zelf.class())
}
}
impl Hashable for PyRange {
fn hash(zelf: &PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyHash> {
let length = zelf.compute_length();
+37 -3
View File
@@ -3,6 +3,7 @@ use super::{
iter::IterStatus::{self, Active, Exhausted},
PyInt, PyTypeRef,
};
use crate::builtins::dict::PyMapping;
use crate::common::hash::PyHash;
use crate::{
function::OptionalArg,
@@ -10,8 +11,8 @@ use crate::{
sequence::{self, SimpleSeq},
sliceable::PySliceableSequence,
slots::{
Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp, SlotConstructor,
SlotIterator,
AsMapping, Comparable, Hashable, Iterable, IteratorIterable, PyComparisonOp,
SlotConstructor, SlotIterator,
},
utils::Either,
vm::{ReprGuard, VirtualMachine},
@@ -111,7 +112,10 @@ impl SlotConstructor for PyTuple {
}
}
#[pyimpl(flags(BASETYPE), with(Hashable, Comparable, Iterable, SlotConstructor))]
#[pyimpl(
flags(BASETYPE),
with(AsMapping, Hashable, Comparable, Iterable, SlotConstructor)
)]
impl PyTuple {
/// Creating a new tuple with given boxed slice.
/// NOTE: for usual case, you probably want to use PyTupleRef::with_elements.
@@ -284,6 +288,36 @@ impl PyTuple {
}
}
impl AsMapping for PyTuple {
fn as_mapping(_zelf: &PyRef<Self>, _vm: &VirtualMachine) -> PyResult<PyMapping> {
Ok(PyMapping {
length: Some(Self::length),
subscript: Some(Self::subscript),
ass_subscript: None,
})
}
#[inline]
fn length(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
Self::downcast_ref(&zelf, vm).map(|zelf| Ok(zelf.len()))?
}
#[inline]
fn subscript(zelf: PyObjectRef, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
Self::downcast(zelf, vm).map(|zelf| Self::getitem(zelf, needle, vm))?
}
#[inline]
fn ass_subscript(
zelf: PyObjectRef,
_needle: PyObjectRef,
_value: PyObjectRef,
_vm: &VirtualMachine,
) -> PyResult<()> {
unreachable!("ass_subscript not implemented for {}", zelf.class())
}
}
impl Hashable for PyTuple {
fn hash(zelf: &PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyHash> {
crate::utils::hash_iter(zelf.elements.iter(), vm)