@@ -139,7 +139,7 @@ impl PyList {
139
139
}
140
140
141
141
fn inplace_concat ( zelf : & Py < Self > , other : & PyObject , vm : & VirtualMachine ) -> PyObjectRef {
142
- if let Ok ( mut seq) = PySequence :: from ( other ) . extract_cloned ( Ok , vm) {
142
+ if let Ok ( mut seq) = extract_cloned ( other , Ok , vm) {
143
143
zelf. borrow_vec_mut ( ) . append ( & mut seq) ;
144
144
zelf. to_owned ( ) . into ( )
145
145
} else {
@@ -149,7 +149,7 @@ impl PyList {
149
149
150
150
#[ pymethod( magic) ]
151
151
fn iadd ( zelf : PyRef < Self > , other : PyObjectRef , vm : & VirtualMachine ) -> PyObjectRef {
152
- if let Ok ( mut seq) = PySequence :: from ( other . as_ref ( ) ) . extract_cloned ( Ok , vm) {
152
+ if let Ok ( mut seq) = extract_cloned ( & * other , Ok , vm) {
153
153
zelf. borrow_vec_mut ( ) . append ( & mut seq) ;
154
154
zelf. into ( )
155
155
} else {
@@ -215,7 +215,7 @@ impl PyList {
215
215
match SequenceIndex :: try_from_borrowed_object ( vm, needle) ? {
216
216
SequenceIndex :: Int ( index) => self . borrow_vec_mut ( ) . set_item_by_index ( vm, index, value) ,
217
217
SequenceIndex :: Slice ( slice) => {
218
- let sec = PySequence :: from ( value . as_ref ( ) ) . extract_cloned ( Ok , vm) ?;
218
+ let sec = extract_cloned ( & * value , Ok , vm) ?;
219
219
self . borrow_vec_mut ( ) . set_item_by_slice ( vm, slice, & sec)
220
220
}
221
221
}
@@ -352,6 +352,31 @@ impl PyList {
352
352
}
353
353
}
354
354
355
+ fn extract_cloned < F , R > ( obj : & PyObject , mut f : F , vm : & VirtualMachine ) -> PyResult < Vec < R > >
356
+ where
357
+ F : FnMut ( PyObjectRef ) -> PyResult < R > ,
358
+ {
359
+ use crate :: builtins:: PyTuple ;
360
+ if let Some ( tuple) = obj. payload_if_exact :: < PyTuple > ( vm) {
361
+ tuple. iter ( ) . map ( |x| f ( x. clone ( ) ) ) . collect ( )
362
+ } else if let Some ( list) = obj. payload_if_exact :: < PyList > ( vm) {
363
+ list. borrow_vec ( ) . iter ( ) . map ( |x| f ( x. clone ( ) ) ) . collect ( )
364
+ } else {
365
+ let iter = obj. to_owned ( ) . get_iter ( vm) ?;
366
+ let iter = iter. iter :: < PyObjectRef > ( vm) ?;
367
+ let len = PySequence :: new ( obj, vm)
368
+ . and_then ( |seq| seq. length_opt ( vm) )
369
+ . transpose ( ) ?
370
+ . unwrap_or ( 0 ) ;
371
+ let mut v = Vec :: with_capacity ( len) ;
372
+ for x in iter {
373
+ v. push ( f ( x?) ?) ;
374
+ }
375
+ v. shrink_to_fit ( ) ;
376
+ Ok ( v)
377
+ }
378
+ }
379
+
355
380
impl < ' a > MutObjectSequenceOp < ' a > for PyList {
356
381
type Guard = PyMappedRwLockReadGuard < ' a , [ PyObjectRef ] > ;
357
382
0 commit comments