Skip to content

Commit e686b64

Browse files
committed
ArgSize for str
1 parent 7d1fae0 commit e686b64

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

vm/src/builtins/str.rs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)