Skip to content

Commit ee890ad

Browse files
committed
resolve: bytes-related issue
1 parent 6864833 commit ee890ad

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

vm/src/vm/vm_ops.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use num_traits::ToPrimitive;
2-
31
use super::{PyMethod, VirtualMachine};
42
use 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
1312
impl 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

Comments
 (0)