@@ -22,9 +22,10 @@ use crate::{
2222 AsMapping , AsSequence , Comparable , Constructor , Initializer , IterNext , Iterable ,
2323 PyComparisonOp , Representable , SelfIter ,
2424 } ,
25- utils:: collection_repr,
2625 vm:: VirtualMachine ,
2726} ;
27+ use rustpython_common:: wtf8:: Wtf8Buf ;
28+
2829use alloc:: fmt;
2930use core:: ops:: DerefMut ;
3031
@@ -521,14 +522,40 @@ impl Representable for PyList {
521522 if zelf. __len__ ( ) == 0 {
522523 return Ok ( vm. ctx . intern_str ( "[]" ) . to_owned ( ) ) ;
523524 }
525+
524526 if let Some ( _guard) = ReprGuard :: enter ( vm, zelf. as_object ( ) ) {
525527 // Clone elements before calling repr to release the read lock.
526528 // Element repr may mutate the list (e.g., list.clear()), which
527529 // needs a write lock and would deadlock if read lock is held.
528- let elements: Vec < PyObjectRef > = zelf. borrow_vec ( ) . to_vec ( ) ;
529- Ok ( vm
530- . ctx
531- . new_str ( collection_repr ( None , "[" , "]" , elements. iter ( ) , vm) ?) )
530+ let mut writer = Wtf8Buf :: new ( ) ;
531+ writer. push_char ( '[' ) ;
532+
533+ let mut elements = zelf. borrow_vec ( ) . to_vec ( ) ;
534+ let mut size = zelf. __len__ ( ) ;
535+ let mut first = true ;
536+ let mut i = 0 ;
537+ while i < size {
538+ if elements. len ( ) != size {
539+ // `repr` mutated the list. refetch it.
540+ elements = zelf. borrow_vec ( ) . to_vec ( ) ;
541+ }
542+
543+ let item = & elements[ i] ;
544+
545+ if first {
546+ first = false ;
547+ } else {
548+ writer. push_str ( ", " ) ;
549+ }
550+
551+ writer. push_wtf8 ( item. repr ( vm) ?. as_wtf8 ( ) ) ;
552+
553+ size = zelf. __len__ ( ) ; // Refetch list size as `repr` may mutate the list.
554+ i += 1 ;
555+ }
556+
557+ writer. push_char ( ']' ) ;
558+ Ok ( vm. ctx . new_str ( writer) )
532559 } else {
533560 Ok ( vm. ctx . intern_str ( "[...]" ) . to_owned ( ) )
534561 }
0 commit comments