forked from Rust-related/RustPython
Merge pull request #1855 from youknowone/strbytes-partition
Fix str, bytes partition
This commit is contained in:
@@ -737,13 +737,11 @@ class BaseBytesTest:
|
||||
b = self.type2test(b"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F")
|
||||
self.assertEqual(b.rsplit(), [b'\x1c\x1d\x1e\x1f'])
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON")
|
||||
def test_partition(self):
|
||||
b = self.type2test(b'mississippi')
|
||||
self.assertEqual(b.partition(b'ss'), (b'mi', b'ss', b'issippi'))
|
||||
self.assertEqual(b.partition(b'w'), (b'mississippi', b'', b''))
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON")
|
||||
def test_rpartition(self):
|
||||
b = self.type2test(b'mississippi')
|
||||
self.assertEqual(b.rpartition(b'ss'), (b'missi', b'ss', b'ippi'))
|
||||
@@ -1578,7 +1576,6 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):
|
||||
x = bytearray(b'')
|
||||
self.assertIsNot(x, x.translate(t))
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON")
|
||||
def test_partition_bytearray_doesnt_share_nullstring(self):
|
||||
a, b, c = bytearray(b"x").partition(b"y")
|
||||
self.assertEqual(b, b"")
|
||||
|
||||
@@ -419,8 +419,6 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.checkequal([left, right],
|
||||
left + delim * 2 + right, 'rsplit', delim *2)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_partition(self):
|
||||
string_tests.MixinStrUnicodeUserStringTest.test_partition(self)
|
||||
# test mixed kinds
|
||||
@@ -438,8 +436,6 @@ class UnicodeTest(string_tests.CommonTest,
|
||||
self.checkequal((left, delim * 2, right),
|
||||
left + delim * 2 + right, 'partition', delim * 2)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_rpartition(self):
|
||||
string_tests.MixinStrUnicodeUserStringTest.test_rpartition(self)
|
||||
# test mixed kinds
|
||||
|
||||
@@ -413,21 +413,25 @@ impl PyByteArray {
|
||||
fn partition(&self, sep: PyByteInner, vm: &VirtualMachine) -> PyResult {
|
||||
// sep ALWAYS converted to bytearray even it's bytes or memoryview
|
||||
// so its ok to accept PyByteInner
|
||||
let (left, right) = self.borrow_value().partition(&sep, false)?;
|
||||
let value = self.borrow_value();
|
||||
let (front, has_mid, back) = value.partition(&sep, vm)?;
|
||||
Ok(vm.ctx.new_tuple(vec![
|
||||
vm.ctx.new_bytearray(left),
|
||||
vm.ctx.new_bytearray(sep.elements),
|
||||
vm.ctx.new_bytearray(right),
|
||||
vm.ctx.new_bytearray(front.to_vec()),
|
||||
vm.ctx
|
||||
.new_bytearray(if has_mid { sep.elements } else { Vec::new() }),
|
||||
vm.ctx.new_bytearray(back.to_vec()),
|
||||
]))
|
||||
}
|
||||
|
||||
#[pymethod(name = "rpartition")]
|
||||
fn rpartition(&self, sep: PyByteInner, vm: &VirtualMachine) -> PyResult {
|
||||
let (left, right) = self.borrow_value().partition(&sep, true)?;
|
||||
let value = self.borrow_value();
|
||||
let (front, has_mid, back) = value.rpartition(&sep, vm)?;
|
||||
Ok(vm.ctx.new_tuple(vec![
|
||||
vm.ctx.new_bytearray(left),
|
||||
vm.ctx.new_bytearray(sep.elements),
|
||||
vm.ctx.new_bytearray(right),
|
||||
vm.ctx.new_bytearray(front.to_vec()),
|
||||
vm.ctx
|
||||
.new_bytearray(if has_mid { sep.elements } else { Vec::new() }),
|
||||
vm.ctx.new_bytearray(back.to_vec()),
|
||||
]))
|
||||
}
|
||||
|
||||
|
||||
@@ -1012,13 +1012,42 @@ impl PyByteInner {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn partition(&self, sep: &PyByteInner, reverse: bool) -> PyResult<(Vec<u8>, Vec<u8>)> {
|
||||
let splitted = if reverse {
|
||||
split_slice_reverse(&self.elements, &sep.elements, 1)
|
||||
pub fn partition(
|
||||
&self,
|
||||
sub: &PyByteInner,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(Vec<u8>, bool, Vec<u8>)> {
|
||||
if sub.elements.is_empty() {
|
||||
return Err(vm.new_value_error("empty separator".to_owned()));
|
||||
}
|
||||
|
||||
let mut sp = self.elements.splitn_str(2, &sub.elements);
|
||||
let front = sp.next().unwrap().to_vec();
|
||||
let (has_mid, back) = if let Some(back) = sp.next() {
|
||||
(true, back.to_vec())
|
||||
} else {
|
||||
split_slice(&self.elements, &sep.elements, 1)
|
||||
(false, Vec::new())
|
||||
};
|
||||
Ok((splitted[0].to_vec(), splitted[1].to_vec()))
|
||||
Ok((front, has_mid, back))
|
||||
}
|
||||
|
||||
pub fn rpartition(
|
||||
&self,
|
||||
sub: &PyByteInner,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<(Vec<u8>, bool, Vec<u8>)> {
|
||||
if sub.elements.is_empty() {
|
||||
return Err(vm.new_value_error("empty separator".to_owned()));
|
||||
}
|
||||
|
||||
let mut sp = self.elements.rsplitn_str(2, &sub.elements);
|
||||
let back = sp.next().unwrap().to_vec();
|
||||
let (has_mid, front) = if let Some(front) = sp.next() {
|
||||
(true, front.to_vec())
|
||||
} else {
|
||||
(false, Vec::new())
|
||||
};
|
||||
Ok((front, has_mid, back))
|
||||
}
|
||||
|
||||
pub fn expandtabs(&self, options: ByteInnerExpandtabsOptions) -> Vec<u8> {
|
||||
|
||||
@@ -366,21 +366,32 @@ impl PyBytes {
|
||||
|
||||
#[pymethod(name = "partition")]
|
||||
fn partition(&self, sep: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
let sepa = PyByteInner::try_from_object(vm, sep.clone())?;
|
||||
|
||||
let (left, right) = self.inner.partition(&sepa, false)?;
|
||||
Ok(vm
|
||||
.ctx
|
||||
.new_tuple(vec![vm.ctx.new_bytes(left), sep, vm.ctx.new_bytes(right)]))
|
||||
let sub = PyByteInner::try_from_object(vm, sep.clone())?;
|
||||
let (front, has_mid, back) = self.inner.partition(&sub, vm)?;
|
||||
Ok(vm.ctx.new_tuple(vec![
|
||||
vm.ctx.new_bytes(front),
|
||||
if has_mid {
|
||||
sep
|
||||
} else {
|
||||
vm.ctx.new_bytes(Vec::new())
|
||||
},
|
||||
vm.ctx.new_bytes(back),
|
||||
]))
|
||||
}
|
||||
|
||||
#[pymethod(name = "rpartition")]
|
||||
fn rpartition(&self, sep: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
let sepa = PyByteInner::try_from_object(vm, sep.clone())?;
|
||||
|
||||
let (left, right) = self.inner.partition(&sepa, true)?;
|
||||
Ok(vm
|
||||
.ctx
|
||||
.new_tuple(vec![vm.ctx.new_bytes(left), sep, vm.ctx.new_bytes(right)]))
|
||||
let sub = PyByteInner::try_from_object(vm, sep.clone())?;
|
||||
let (front, has_mid, back) = self.inner.rpartition(&sub, vm)?;
|
||||
Ok(vm.ctx.new_tuple(vec![
|
||||
vm.ctx.new_bytes(front),
|
||||
if has_mid {
|
||||
sep
|
||||
} else {
|
||||
vm.ctx.new_bytes(Vec::new())
|
||||
},
|
||||
vm.ctx.new_bytes(back),
|
||||
]))
|
||||
}
|
||||
|
||||
#[pymethod(name = "expandtabs")]
|
||||
|
||||
@@ -954,42 +954,43 @@ impl PyString {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn partition(&self, sub: PyStringRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
let value = &self.value;
|
||||
let sub = &sub.value;
|
||||
let mut new_tup = Vec::new();
|
||||
if value.contains(sub) {
|
||||
new_tup = value
|
||||
.splitn(2, sub)
|
||||
.map(|s| vm.ctx.new_str(s.to_owned()))
|
||||
.collect();
|
||||
new_tup.insert(1, vm.ctx.new_str(sub.clone()));
|
||||
} else {
|
||||
new_tup.push(vm.ctx.new_str(value.clone()));
|
||||
new_tup.push(vm.ctx.new_str("".to_owned()));
|
||||
new_tup.push(vm.ctx.new_str("".to_owned()));
|
||||
fn partition(&self, sub: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
if sub.value.is_empty() {
|
||||
return Err(vm.new_value_error("empty separator".to_owned()));
|
||||
}
|
||||
vm.ctx.new_tuple(new_tup)
|
||||
let mut sp = self.value.splitn(2, &sub.value);
|
||||
let front = sp.next().unwrap();
|
||||
let elems = if let Some(back) = sp.next() {
|
||||
[front, &sub.value, back]
|
||||
} else {
|
||||
[front, "", ""]
|
||||
};
|
||||
Ok(vm.ctx.new_tuple(
|
||||
elems
|
||||
.iter()
|
||||
.map(|&s| vm.ctx.new_str(s.to_owned()))
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn rpartition(&self, sub: PyStringRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
let value = &self.value;
|
||||
let sub = &sub.value;
|
||||
let mut new_tup = Vec::new();
|
||||
if value.contains(sub) {
|
||||
new_tup = value
|
||||
.rsplitn(2, sub)
|
||||
.map(|s| vm.ctx.new_str(s.to_owned()))
|
||||
.collect();
|
||||
new_tup.swap(0, 1); // so it's in the right order
|
||||
new_tup.insert(1, vm.ctx.new_str(sub.clone()));
|
||||
} else {
|
||||
new_tup.push(vm.ctx.new_str("".to_owned()));
|
||||
new_tup.push(vm.ctx.new_str("".to_owned()));
|
||||
new_tup.push(vm.ctx.new_str(value.clone()));
|
||||
fn rpartition(&self, sub: PyStringRef, vm: &VirtualMachine) -> PyResult {
|
||||
if sub.value.is_empty() {
|
||||
return Err(vm.new_value_error("empty separator".to_owned()));
|
||||
}
|
||||
vm.ctx.new_tuple(new_tup)
|
||||
let mut sp = self.value.rsplitn(2, &sub.value);
|
||||
let back = sp.next().unwrap();
|
||||
let elems = if let Some(front) = sp.next() {
|
||||
[front, &sub.value, back]
|
||||
} else {
|
||||
["", "", back]
|
||||
};
|
||||
Ok(vm.ctx.new_tuple(
|
||||
elems
|
||||
.iter()
|
||||
.map(|&s| vm.ctx.new_str(s.to_owned()))
|
||||
.collect(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Return `true` if the sequence is ASCII titlecase and the sequence is not
|
||||
|
||||
Reference in New Issue
Block a user