diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index b589e121a..d93055a00 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -7,10 +7,10 @@ use crate::{ common::ascii, dictdatatype::{self, DictKey}, function::{ArgIterable, FuncArgs, IntoPyObject, KwArgs, OptionalArg}, - protocol::{PyIterIter, PyIterReturn, PyMappingMethods}, + protocol::{PyIterIter, PyIterReturn, PyMappingMethods, PySequenceMethods}, types::{ - AsMapping, Comparable, Constructor, Hashable, IterNext, IterNextIterable, Iterable, - PyComparisonOp, Unconstructible, Unhashable, + AsMapping, AsSequence, Comparable, Constructor, Hashable, IterNext, IterNextIterable, + Iterable, PyComparisonOp, Unconstructible, Unhashable, }, vm::{ReprGuard, VirtualMachine}, IdProtocol, @@ -19,8 +19,8 @@ use crate::{ PyObjectView, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol, }; use rustpython_common::lock::PyMutex; -use std::fmt; use std::mem::size_of; +use std::{borrow::Cow, fmt}; pub type DictContentType = dictdatatype::Dict; @@ -61,7 +61,10 @@ impl PyDict { // Python dict methods: #[allow(clippy::len_without_is_empty)] -#[pyimpl(with(AsMapping, Hashable, Comparable, Iterable), flags(BASETYPE))] +#[pyimpl( + with(AsMapping, Hashable, Comparable, Iterable, AsSequence), + flags(BASETYPE) +)] impl PyDict { /// escape hatch to access the underlying data structure directly. prefer adding a method on /// PyDict instead of using this @@ -451,6 +454,22 @@ impl AsMapping for PyDict { } } +impl AsSequence for PyDict { + fn as_sequence( + _zelf: &PyObjectView, + _vm: &VirtualMachine, + ) -> Cow<'static, PySequenceMethods> { + Cow::Borrowed(&Self::SEQUENCE_METHODS) + } +} + +impl PyDict { + const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods { + contains: Some(|seq, target, vm| seq.obj_as::().entries.contains(vm, target)), + ..*PySequenceMethods::not_implemented() + }; +} + impl Comparable for PyDict { fn cmp( zelf: &PyObjectView,