11use super :: {
2- PyBytes , PyBytesRef , PyInt , PyListRef , PySlice , PyStr , PyStrRef , PyTuple , PyTupleRef , PyType ,
3- PyTypeRef ,
2+ PositionIterInternal , PyBytes , PyBytesRef , PyInt , PyListRef , PySlice , PyStr , PyStrRef , PyTuple ,
3+ PyTupleRef , PyType , PyTypeRef ,
44} ;
55use crate :: {
66 buffer:: FormatSpec ,
@@ -15,15 +15,20 @@ use crate::{
1515 function:: Either ,
1616 function:: { FuncArgs , OptionalArg , PyComparisonValue } ,
1717 protocol:: {
18- BufferDescriptor , BufferMethods , PyBuffer , PyMappingMethods , PySequenceMethods , VecBuffer ,
18+ BufferDescriptor , BufferMethods , PyBuffer , PyIterReturn , PyMappingMethods ,
19+ PySequenceMethods , VecBuffer ,
1920 } ,
2021 sliceable:: SequenceIndexOp ,
21- types:: { AsBuffer , AsMapping , AsSequence , Comparable , Constructor , Hashable , PyComparisonOp } ,
22+ types:: {
23+ AsBuffer , AsMapping , AsSequence , Comparable , Constructor , Hashable , IterNext ,
24+ IterNextIterable , Iterable , PyComparisonOp , Unconstructible ,
25+ } ,
2226 AsObject , Context , Py , PyObject , PyObjectRef , PyPayload , PyRef , PyResult ,
2327 TryFromBorrowedObject , TryFromObject , VirtualMachine ,
2428} ;
2529use crossbeam_utils:: atomic:: AtomicCell ;
2630use itertools:: Itertools ;
31+ use rustpython_common:: lock:: PyMutex ;
2732use std:: { cmp:: Ordering , fmt:: Debug , mem:: ManuallyDrop , ops:: Range } ;
2833
2934#[ derive( FromArgs ) ]
@@ -61,7 +66,15 @@ impl Constructor for PyMemoryView {
6166 }
6267}
6368
64- #[ pyclass( with( Hashable , Comparable , AsBuffer , AsMapping , AsSequence , Constructor ) ) ]
69+ #[ pyclass( with(
70+ Hashable ,
71+ Comparable ,
72+ AsBuffer ,
73+ AsMapping ,
74+ AsSequence ,
75+ Constructor ,
76+ Iterable
77+ ) ) ]
6578impl PyMemoryView {
6679 fn parse_format ( format : & str , vm : & VirtualMachine ) -> PyResult < FormatSpec > {
6780 FormatSpec :: parse ( format. as_bytes ( ) , vm)
@@ -1038,7 +1051,8 @@ impl PyPayload for PyMemoryView {
10381051}
10391052
10401053pub ( crate ) fn init ( ctx : & Context ) {
1041- PyMemoryView :: extend_class ( ctx, ctx. types . memoryview_type )
1054+ PyMemoryView :: extend_class ( ctx, ctx. types . memoryview_type ) ;
1055+ PyMemoryViewIterator :: extend_class ( ctx, ctx. types . memoryviewiterator_type ) ;
10421056}
10431057
10441058fn format_unpack (
@@ -1082,3 +1096,49 @@ fn is_equiv_format(a: &BufferDescriptor, b: &BufferDescriptor) -> bool {
10821096fn is_equiv_structure ( a : & BufferDescriptor , b : & BufferDescriptor ) -> bool {
10831097 is_equiv_format ( a, b) && is_equiv_shape ( a, b)
10841098}
1099+
1100+ impl Iterable for PyMemoryView {
1101+ fn iter ( zelf : PyRef < Self > , vm : & VirtualMachine ) -> PyResult {
1102+ Ok ( PyMemoryViewIterator {
1103+ internal : PyMutex :: new ( PositionIterInternal :: new ( zelf, 0 ) ) ,
1104+ }
1105+ . into_pyobject ( vm) )
1106+ }
1107+ }
1108+
1109+ #[ pyclass( module = false , name = "memory_iterator" ) ]
1110+ #[ derive( Debug ) ]
1111+ pub struct PyMemoryViewIterator {
1112+ internal : PyMutex < PositionIterInternal < PyRef < PyMemoryView > > > ,
1113+ }
1114+
1115+ impl PyPayload for PyMemoryViewIterator {
1116+ fn class ( vm : & VirtualMachine ) -> & ' static Py < PyType > {
1117+ vm. ctx . types . memoryviewiterator_type
1118+ }
1119+ }
1120+
1121+ #[ pyclass( with( Constructor , IterNext ) ) ]
1122+ impl PyMemoryViewIterator {
1123+ #[ pymethod( magic) ]
1124+ fn reduce ( & self , vm : & VirtualMachine ) -> PyTupleRef {
1125+ self . internal
1126+ . lock ( )
1127+ . builtins_iter_reduce ( |x| x. clone ( ) . into ( ) , vm)
1128+ }
1129+ }
1130+ impl Unconstructible for PyMemoryViewIterator { }
1131+
1132+ impl IterNextIterable for PyMemoryViewIterator { }
1133+ impl IterNext for PyMemoryViewIterator {
1134+ fn next ( zelf : & crate :: Py < Self > , vm : & VirtualMachine ) -> PyResult < PyIterReturn > {
1135+ zelf. internal . lock ( ) . next ( |mv, pos| {
1136+ let len = mv. len ( vm) ?;
1137+ Ok ( if pos >= len {
1138+ PyIterReturn :: StopIteration ( None )
1139+ } else {
1140+ PyIterReturn :: Return ( mv. getitem_by_idx ( pos. try_into ( ) . unwrap ( ) , vm) ?)
1141+ } )
1142+ } )
1143+ }
1144+ }
0 commit comments