@@ -139,7 +139,7 @@ impl PyList {
139139 }
140140
141141 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) {
143143 zelf. borrow_vec_mut ( ) . append ( & mut seq) ;
144144 zelf. to_owned ( ) . into ( )
145145 } else {
@@ -149,7 +149,7 @@ impl PyList {
149149
150150 #[ pymethod( magic) ]
151151 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) {
153153 zelf. borrow_vec_mut ( ) . append ( & mut seq) ;
154154 zelf. into ( )
155155 } else {
@@ -215,7 +215,7 @@ impl PyList {
215215 match SequenceIndex :: try_from_borrowed_object ( vm, needle) ? {
216216 SequenceIndex :: Int ( index) => self . borrow_vec_mut ( ) . set_item_by_index ( vm, index, value) ,
217217 SequenceIndex :: Slice ( slice) => {
218- let sec = PySequence :: from ( value . as_ref ( ) ) . extract_cloned ( Ok , vm) ?;
218+ let sec = extract_cloned ( & * value , Ok , vm) ?;
219219 self . borrow_vec_mut ( ) . set_item_by_slice ( vm, slice, & sec)
220220 }
221221 }
@@ -352,6 +352,31 @@ impl PyList {
352352 }
353353}
354354
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+
355380impl < ' a > MutObjectSequenceOp < ' a > for PyList {
356381 type Guard = PyMappedRwLockReadGuard < ' a , [ PyObjectRef ] > ;
357382
0 commit comments