Skip to content

Commit ac20b00

Browse files
authored
str.replace support count as keyword arg (#5954)
1 parent e75aebb commit ac20b00

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

Lib/test/string_tests.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,6 @@ def test_count(self):
154154
self.assertEqual(rem, 0, '%s != 0 for %s' % (rem, i))
155155
self.assertEqual(r1, r2, '%s != %s for %s' % (r1, r2, i))
156156

157-
# TODO: RUSTPYTHON; TypeError: Unexpected keyword argument count
158-
@unittest.expectedFailure
159157
def test_count_keyword(self):
160158
self.assertEqual('aa'.replace('a', 'b', 0), 'aa'.replace('a', 'b', count=0))
161159
self.assertEqual('aa'.replace('a', 'b', 1), 'aa'.replace('a', 'b', count=1))

vm/src/builtins/str.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,20 +1018,27 @@ impl PyStr {
10181018
}
10191019

10201020
#[pymethod]
1021-
fn replace(&self, old: PyStrRef, new: PyStrRef, count: OptionalArg<isize>) -> Wtf8Buf {
1021+
fn replace(&self, args: ReplaceArgs) -> Wtf8Buf {
1022+
use std::cmp::Ordering;
1023+
10221024
let s = self.as_wtf8();
1023-
match count {
1024-
OptionalArg::Present(max_count) if max_count >= 0 => {
1025-
if max_count == 0 || (s.is_empty() && !old.is_empty()) {
1026-
// nothing to do; return the original bytes
1025+
let ReplaceArgs { old, new, count } = args;
1026+
1027+
match count.cmp(&0) {
1028+
Ordering::Less => s.replace(old.as_wtf8(), new.as_wtf8()),
1029+
Ordering::Equal => s.to_owned(),
1030+
Ordering::Greater => {
1031+
let s_is_empty = s.is_empty();
1032+
let old_is_empty = old.is_empty();
1033+
1034+
if s_is_empty && !old_is_empty {
10271035
s.to_owned()
1028-
} else if s.is_empty() && old.is_empty() {
1036+
} else if s_is_empty && old_is_empty {
10291037
new.as_wtf8().to_owned()
10301038
} else {
1031-
s.replacen(old.as_wtf8(), new.as_wtf8(), max_count as usize)
1039+
s.replacen(old.as_wtf8(), new.as_wtf8(), count as usize)
10321040
}
10331041
}
1034-
_ => s.replace(old.as_wtf8(), new.as_wtf8()),
10351042
}
10361043
}
10371044

@@ -1685,6 +1692,18 @@ impl FindArgs {
16851692
}
16861693
}
16871694

1695+
#[derive(FromArgs)]
1696+
struct ReplaceArgs {
1697+
#[pyarg(positional)]
1698+
old: PyStrRef,
1699+
1700+
#[pyarg(positional)]
1701+
new: PyStrRef,
1702+
1703+
#[pyarg(any, default = -1)]
1704+
count: isize,
1705+
}
1706+
16881707
pub fn init(ctx: &Context) {
16891708
PyStr::extend_class(ctx, ctx.types.str_type);
16901709

0 commit comments

Comments
 (0)