@@ -9,6 +9,7 @@ use crate::common::{
9
9
PyMappedRwLockReadGuard , PyMappedRwLockWriteGuard , PyMutex , PyRwLock , PyRwLockReadGuard ,
10
10
PyRwLockWriteGuard ,
11
11
} ,
12
+ static_cell,
12
13
} ;
13
14
use crate :: {
14
15
anystr:: { self , AnyStr } ,
@@ -21,19 +22,20 @@ use crate::{
21
22
function:: { ArgBytesLike , ArgIterable , FuncArgs , IntoPyObject , OptionalArg , OptionalOption } ,
22
23
protocol:: {
23
24
BufferInternal , BufferOptions , BufferResizeGuard , PyBuffer , PyIterReturn , PyMappingMethods ,
25
+ PySequenceMethods ,
24
26
} ,
25
27
sliceable:: { PySliceableSequence , PySliceableSequenceMut , SequenceIndex } ,
26
28
types:: {
27
- AsBuffer , AsMapping , Callable , Comparable , Constructor , Hashable , IterNext ,
29
+ AsBuffer , AsMapping , AsSequence , Callable , Comparable , Constructor , Hashable , IterNext ,
28
30
IterNextIterable , Iterable , PyComparisonOp , Unconstructible , Unhashable ,
29
31
} ,
30
32
utils:: Either ,
31
33
IdProtocol , PyClassDef , PyClassImpl , PyComparisonValue , PyContext , PyObjectRef , PyRef ,
32
- PyResult , PyValue , TypeProtocol , VirtualMachine ,
34
+ PyResult , PyValue , TryFromObject , TypeProtocol , VirtualMachine ,
33
35
} ;
34
36
use bstr:: ByteSlice ;
35
37
use crossbeam_utils:: atomic:: AtomicCell ;
36
- use std:: mem:: size_of;
38
+ use std:: { borrow :: Cow , mem:: size_of} ;
37
39
38
40
/// "bytearray(iterable_of_ints) -> bytearray\n\
39
41
/// bytearray(string, encoding[, errors]) -> bytearray\n\
@@ -102,7 +104,7 @@ pub(crate) fn init(context: &PyContext) {
102
104
103
105
#[ pyimpl(
104
106
flags( BASETYPE ) ,
105
- with( Hashable , Comparable , AsBuffer , AsMapping , Iterable )
107
+ with( Hashable , Comparable , AsBuffer , AsMapping , AsSequence , Iterable )
106
108
) ]
107
109
impl PyByteArray {
108
110
#[ pyslot]
@@ -164,6 +166,17 @@ impl PyByteArray {
164
166
self . inner ( ) . contains ( needle, vm)
165
167
}
166
168
169
+ fn setitem_by_idx ( & self , i : isize , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
170
+ let value = value_from_object ( vm, & value) ?;
171
+ let mut elements = self . borrow_buf_mut ( ) ;
172
+ if let Some ( i) = elements. wrap_index ( i) {
173
+ elements[ i] = value;
174
+ Ok ( ( ) )
175
+ } else {
176
+ Err ( vm. new_index_error ( "index out of range" . to_owned ( ) ) )
177
+ }
178
+ }
179
+
167
180
#[ pymethod( magic) ]
168
181
fn setitem (
169
182
zelf : PyRef < Self > ,
@@ -172,16 +185,7 @@ impl PyByteArray {
172
185
vm : & VirtualMachine ,
173
186
) -> PyResult < ( ) > {
174
187
match SequenceIndex :: try_from_object_for ( vm, needle, Self :: NAME ) ? {
175
- SequenceIndex :: Int ( i) => {
176
- let value = value_from_object ( vm, & value) ?;
177
- let mut elements = zelf. borrow_buf_mut ( ) ;
178
- if let Some ( i) = elements. wrap_index ( i) {
179
- elements[ i] = value;
180
- Ok ( ( ) )
181
- } else {
182
- Err ( vm. new_index_error ( "index out of range" . to_owned ( ) ) )
183
- }
184
- }
188
+ SequenceIndex :: Int ( i) => zelf. setitem_by_idx ( i, value, vm) ,
185
189
SequenceIndex :: Slice ( slice) => {
186
190
let slice = slice. to_saturated ( vm) ?;
187
191
let items = if zelf. is ( & value) {
@@ -212,18 +216,20 @@ impl PyByteArray {
212
216
self . inner ( ) . getitem ( Self :: NAME , needle, vm)
213
217
}
214
218
219
+ fn delitem_by_idx ( & self , i : isize , vm : & VirtualMachine ) -> PyResult < ( ) > {
220
+ let elements = & mut self . try_resizable ( vm) ?. elements ;
221
+ if let Some ( idx) = elements. wrap_index ( i) {
222
+ elements. remove ( idx) ;
223
+ Ok ( ( ) )
224
+ } else {
225
+ Err ( vm. new_index_error ( "index out of range" . to_owned ( ) ) )
226
+ }
227
+ }
228
+
215
229
#[ pymethod( magic) ]
216
230
pub fn delitem ( & self , needle : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
217
231
match SequenceIndex :: try_from_object_for ( vm, needle, Self :: NAME ) ? {
218
- SequenceIndex :: Int ( int) => {
219
- let elements = & mut self . try_resizable ( vm) ?. elements ;
220
- if let Some ( idx) = elements. wrap_index ( int) {
221
- elements. remove ( idx) ;
222
- Ok ( ( ) )
223
- } else {
224
- Err ( vm. new_index_error ( "index out of range" . to_owned ( ) ) )
225
- }
226
- }
232
+ SequenceIndex :: Int ( i) => self . delitem_by_idx ( i, vm) ,
227
233
SequenceIndex :: Slice ( slice) => {
228
234
let slice = slice. to_saturated ( vm) ?;
229
235
let elements = & mut self . try_resizable ( vm) ?. elements ;
@@ -790,6 +796,52 @@ impl AsMapping for PyByteArray {
790
796
}
791
797
}
792
798
799
+ impl AsSequence for PyByteArray {
800
+ fn as_sequence ( _zelf : & PyRef < Self > , _vm : & VirtualMachine ) -> Cow < ' static , PySequenceMethods > {
801
+ static_cell ! {
802
+ static METHODS : PySequenceMethods ;
803
+ }
804
+ Cow :: Borrowed ( METHODS . get_or_init ( || PySequenceMethods {
805
+ length : Some ( |zelf, _vm| Ok ( zelf. payload :: < Self > ( ) . unwrap ( ) . len ( ) ) ) ,
806
+ concat : Some ( |zelf, other, vm| {
807
+ zelf. payload :: < Self > ( )
808
+ . unwrap ( )
809
+ . inner ( )
810
+ . concat ( other, vm)
811
+ . map ( |x| PyByteArray :: from ( x) . into_object ( vm) )
812
+ } ) ,
813
+ repeat : Some ( |zelf, n, vm| {
814
+ zelf. payload :: < Self > ( )
815
+ . unwrap ( )
816
+ . mul ( n as isize , vm)
817
+ . map ( |x| x. into_object ( vm) )
818
+ } ) ,
819
+ item : Some ( |zelf, i, vm| zelf. payload :: < Self > ( ) . unwrap ( ) . inner ( ) . item ( i, vm) ) ,
820
+ ass_item : Some ( |zelf, i, value, vm| {
821
+ let zelf = zelf. payload :: < Self > ( ) . unwrap ( ) ;
822
+ if let Some ( value) = value {
823
+ zelf. setitem_by_idx ( i, value, vm)
824
+ } else {
825
+ zelf. delitem_by_idx ( i, vm)
826
+ }
827
+ } ) ,
828
+ contains : Some ( |zelf, other, vm| {
829
+ let other = <Either < PyBytesInner , PyIntRef > >:: try_from_object ( vm, other. clone ( ) ) ?;
830
+ zelf. payload :: < Self > ( ) . unwrap ( ) . contains ( other, vm)
831
+ } ) ,
832
+ inplace_concat : Some ( |zelf, other, vm| {
833
+ let other = ArgBytesLike :: try_from_object ( vm, other. clone ( ) ) ?;
834
+ let zelf = zelf. clone ( ) . downcast :: < Self > ( ) . unwrap ( ) ;
835
+ Self :: iadd ( zelf, other, vm) . map ( |x| x. into ( ) )
836
+ } ) ,
837
+ inplace_repeat : Some ( |zelf, n, vm| {
838
+ let zelf = zelf. clone ( ) . downcast :: < Self > ( ) . unwrap ( ) ;
839
+ Self :: imul ( zelf, n as isize , vm) . map ( |x| x. into ( ) )
840
+ } ) ,
841
+ } ) )
842
+ }
843
+ }
844
+
793
845
impl Unhashable for PyByteArray { }
794
846
795
847
impl Iterable for PyByteArray {
0 commit comments