1- use num_traits:: ToPrimitive ;
2-
31use super :: { PyMethod , VirtualMachine } ;
42use crate :: {
53 builtins:: { PyInt , PyIntRef , PyStrInterned } ,
@@ -8,6 +6,7 @@ use crate::{
86 protocol:: { PyIterReturn , PyNumberMethodsOffset , PySequence } ,
97 types:: PyComparisonOp ,
108} ;
9+ use num_traits:: ToPrimitive ;
1110
1211/// Collection of operators
1312impl VirtualMachine {
@@ -281,15 +280,34 @@ impl VirtualMachine {
281280 let seq_a = PySequence :: new ( a, self ) ;
282281 let seq_b = PySequence :: new ( b, self ) ;
283282
283+ // TODO: remove the duplicated conditions
284+ // The reason I don't put the below sepecial condition into `PyBytes::AsSequence::repeat` is
285+ // we cannot use `to_owned()` in `PyBytes::repeat`.
284286 if let Some ( seq_a) = seq_a {
285- let n = b. try_int ( self ) ?. as_bigint ( ) . to_usize ( ) . ok_or_else ( || {
287+ let n = b. try_int ( self ) ?. as_bigint ( ) . to_isize ( ) . ok_or_else ( || {
286288 self . new_overflow_error ( "repeated bytes are too long" . to_owned ( ) )
287289 } ) ?;
290+
291+ if n == 1 && a. class ( ) . is ( self . ctx . types . bytes_type ) {
292+ // Special case: when some `bytes` is multiplied by `1`,
293+ // nothing really happens, we need to return an object itself
294+ // with the same `id()` to be compatible with CPython.
295+ // This only works for `bytes` itself, not its subclasses.
296+ return Ok ( a. to_owned ( ) ) ;
297+ }
288298 return seq_a. repeat ( n, self ) ;
289299 } else if let Some ( seq_b) = seq_b {
290- let n = a. try_int ( self ) ?. as_bigint ( ) . to_usize ( ) . ok_or_else ( || {
300+ let n = a. try_int ( self ) ?. as_bigint ( ) . to_isize ( ) . ok_or_else ( || {
291301 self . new_overflow_error ( "repeated bytes are too long" . to_owned ( ) )
292302 } ) ?;
303+
304+ if n == 1 && b. class ( ) . is ( self . ctx . types . bytes_type ) {
305+ // Special case: when some `bytes` is multiplied by `1`,
306+ // nothing really happens, we need to return an object itself
307+ // with the same `id()` to be compatible with CPython.
308+ // This only works for `bytes` itself, not its subclasses.
309+ return Ok ( b. to_owned ( ) ) ;
310+ }
293311 return seq_b. repeat ( n, self ) ;
294312 }
295313 return Ok ( self . ctx . not_implemented ( ) ) ;
0 commit comments