Skip to content

Commit dacd119

Browse files
committed
Fix str.[r]split
1 parent b8eba6a commit dacd119

File tree

1 file changed

+58
-20
lines changed

1 file changed

+58
-20
lines changed

vm/src/obj/objstr.rs

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -349,43 +349,81 @@ impl PyString {
349349
fn split(
350350
&self,
351351
pattern: OptionalArg<PyStringRef>,
352-
num: OptionalArg<usize>,
352+
num: OptionalArg<isize>,
353353
vm: &VirtualMachine,
354354
) -> PyObjectRef {
355355
let value = &self.value;
356356
let pattern = match pattern {
357-
OptionalArg::Present(ref s) => &s.value,
358-
OptionalArg::Missing => " ",
357+
OptionalArg::Present(ref s) => Some(s.as_str()),
358+
OptionalArg::Missing => None,
359+
};
360+
let num_splits = num.into_option().unwrap_or(-1);
361+
let elements = if let Some(pattern) = pattern {
362+
if num_splits.is_negative() {
363+
value
364+
.split(pattern)
365+
.map(|o| vm.ctx.new_str(o.to_string()))
366+
.collect()
367+
} else {
368+
value
369+
.splitn(num_splits as usize + 1, pattern)
370+
.map(|o| vm.ctx.new_str(o.to_string()))
371+
.collect()
372+
}
373+
} else if num_splits.is_negative() {
374+
value
375+
.split(|c: char| c.is_ascii_whitespace())
376+
.filter(|s| !s.is_empty())
377+
.map(|o| vm.ctx.new_str(o.to_string()))
378+
.collect()
379+
} else {
380+
value
381+
.splitn(num_splits as usize + 1, |c: char| c.is_ascii_whitespace())
382+
.filter(|s| !s.is_empty())
383+
.map(|o| vm.ctx.new_str(o.to_string()))
384+
.collect()
359385
};
360-
let num_splits = num
361-
.into_option()
362-
.unwrap_or_else(|| value.split(pattern).count());
363-
let elements = value
364-
.splitn(num_splits + 1, pattern)
365-
.map(|o| vm.ctx.new_str(o.to_string()))
366-
.collect();
367386
vm.ctx.new_list(elements)
368387
}
369388

370389
#[pymethod]
371390
fn rsplit(
372391
&self,
373392
pattern: OptionalArg<PyStringRef>,
374-
num: OptionalArg<usize>,
393+
num: OptionalArg<isize>,
375394
vm: &VirtualMachine,
376395
) -> PyObjectRef {
377396
let value = &self.value;
378397
let pattern = match pattern {
379-
OptionalArg::Present(ref s) => &s.value,
380-
OptionalArg::Missing => " ",
398+
OptionalArg::Present(ref s) => Some(s.as_str()),
399+
OptionalArg::Missing => None,
400+
};
401+
let num_splits = num.into_option().unwrap_or(-1);
402+
let mut elements: Vec<_> = if let Some(pattern) = pattern {
403+
if num_splits.is_negative() {
404+
value
405+
.split(pattern)
406+
.map(|o| vm.ctx.new_str(o.to_string()))
407+
.collect()
408+
} else {
409+
value
410+
.splitn(num_splits as usize + 1, pattern)
411+
.map(|o| vm.ctx.new_str(o.to_string()))
412+
.collect()
413+
}
414+
} else if num_splits.is_negative() {
415+
value
416+
.split(|c: char| c.is_ascii_whitespace())
417+
.filter(|s| !s.is_empty())
418+
.map(|o| vm.ctx.new_str(o.to_string()))
419+
.collect()
420+
} else {
421+
value
422+
.splitn(num_splits as usize + 1, |c: char| c.is_ascii_whitespace())
423+
.filter(|s| !s.is_empty())
424+
.map(|o| vm.ctx.new_str(o.to_string()))
425+
.collect()
381426
};
382-
let num_splits = num
383-
.into_option()
384-
.unwrap_or_else(|| value.split(pattern).count());
385-
let mut elements: Vec<_> = value
386-
.rsplitn(num_splits + 1, pattern)
387-
.map(|o| vm.ctx.new_str(o.to_string()))
388-
.collect();
389427
// Unlike Python rsplit, Rust rsplitn returns an iterator that
390428
// starts from the end of the string.
391429
elements.reverse();

0 commit comments

Comments
 (0)