@@ -13,7 +13,7 @@ use crate::{
1313 } ,
1414 convert:: { IntoPyException , ToPyException , ToPyObject , ToPyResult } ,
1515 format:: { format, format_map} ,
16- function:: { ArgIterable , FuncArgs , OptionalArg , OptionalOption , PyComparisonValue } ,
16+ function:: { ArgSize , ArgIterable , FuncArgs , OptionalArg , OptionalOption , PyComparisonValue } ,
1717 intern:: PyInterned ,
1818 protocol:: { PyIterReturn , PyMappingMethods , PyNumberMethods , PySequenceMethods } ,
1919 sequence:: SequenceExt ,
@@ -350,6 +350,25 @@ impl PyStr {
350350 fn borrow ( & self ) -> & BorrowedStr {
351351 unsafe { std:: mem:: transmute ( self ) }
352352 }
353+
354+ fn repeat ( zelf : PyRef < Self > , value : isize , vm : & VirtualMachine ) -> PyResult < PyRef < Self > > {
355+ if value == 0 && zelf. class ( ) . is ( vm. ctx . types . str_type ) {
356+ // Special case: when some `str` is multiplied by `0`,
357+ // returns the empty `str`.
358+ return Ok ( vm. ctx . empty_str . clone ( ) ) ;
359+ }
360+ if ( value == 1 || zelf. is_empty ( ) ) && zelf. class ( ) . is ( vm. ctx . types . str_type ) {
361+ // Special case: when some `str` is multiplied by `1` or is the empty `str`,
362+ // nothing really happens, we need to return an object itself
363+ // with the same `id()` to be compatible with CPython.
364+ // This only works for `str` itself, not its subclasses.
365+ return Ok ( zelf) ;
366+ }
367+ zelf. as_str ( )
368+ . as_bytes ( )
369+ . mul ( vm, value)
370+ . map ( |x| Self :: from ( unsafe { String :: from_utf8_unchecked ( x) } ) . into_ref ( vm) )
371+ }
353372}
354373
355374#[ pyclass(
@@ -467,23 +486,8 @@ impl PyStr {
467486
468487 #[ pymethod( name = "__rmul__" ) ]
469488 #[ pymethod( magic) ]
470- fn mul ( zelf : PyRef < Self > , value : isize , vm : & VirtualMachine ) -> PyResult < PyRef < Self > > {
471- if value == 0 && zelf. class ( ) . is ( vm. ctx . types . str_type ) {
472- // Special case: when some `str` is multiplied by `0`,
473- // returns the empty `str`.
474- return Ok ( vm. ctx . empty_str . clone ( ) ) ;
475- }
476- if ( value == 1 || zelf. is_empty ( ) ) && zelf. class ( ) . is ( vm. ctx . types . str_type ) {
477- // Special case: when some `str` is multiplied by `1` or is the empty `str`,
478- // nothing really happens, we need to return an object itself
479- // with the same `id()` to be compatible with CPython.
480- // This only works for `str` itself, not its subclasses.
481- return Ok ( zelf) ;
482- }
483- zelf. as_str ( )
484- . as_bytes ( )
485- . mul ( vm, value)
486- . map ( |x| Self :: from ( unsafe { String :: from_utf8_unchecked ( x) } ) . into_ref ( vm) )
489+ fn mul ( zelf : PyRef < Self > , value : ArgSize , vm : & VirtualMachine ) -> PyResult < PyRef < Self > > {
490+ Self :: repeat ( zelf, value. into ( ) , vm)
487491 }
488492
489493 #[ pymethod( magic) ]
@@ -1325,7 +1329,7 @@ impl AsSequence for PyStr {
13251329 } ) ,
13261330 repeat : atomic_func ! ( |seq, n, vm| {
13271331 let zelf = PyStr :: sequence_downcast( seq) ;
1328- PyStr :: mul ( zelf. to_owned( ) , n, vm) . map( |x| x. into( ) )
1332+ PyStr :: repeat ( zelf. to_owned( ) , n, vm) . map( |x| x. into( ) )
13291333 } ) ,
13301334 item : atomic_func ! ( |seq, i, vm| {
13311335 let zelf = PyStr :: sequence_downcast( seq) ;
0 commit comments