Fix {bytes|bytearray}.{|r|l}strip

This commit is contained in:
Jeong YunWon committed 2020-04-11 22:22:33 +09:00
1 parent fc2949c6fb
commit 75ebaedaf1
4 files changed
+46 -67

No files matched your search

-2
View File
@@ -777,7 +777,6 @@ class BaseTest:
self.checkequal(['arf', 'barf'], b, 'rsplit', None)
self.checkequal(['arf', 'barf'], b, 'rsplit', None, 2)
@unittest.skip("TODO: RUSTPYTHON test_bytes")
def test_strip_whitespace(self):
self.checkequal('hello', ' hello ', 'strip')
self.checkequal('hello ', ' hello ', 'lstrip')
@@ -795,7 +794,6 @@ class BaseTest:
self.checkequal(' hello', ' hello ', 'rstrip', None)
self.checkequal('hello', 'hello', 'strip', None)
@unittest.skip("TODO: RUSTPYTHON test_bytes")
def test_strip(self):
# strip/lstrip/rstrip with str arg
self.checkequal('hello', 'xyzzyhelloxyzzy', 'strip', 'xyz')
+9 -18
View File
@@ -5,8 +5,8 @@ use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use super::objbyteinner::{
ByteInnerExpandtabsOptions, ByteInnerFindOptions, ByteInnerNewOptions, ByteInnerPaddingOptions,
ByteInnerPosition, ByteInnerSplitOptions, ByteInnerSplitlinesOptions,
ByteInnerTranslateOptions, ByteOr, PyByteInner,
ByteInnerSplitOptions, ByteInnerSplitlinesOptions, ByteInnerTranslateOptions, ByteOr,
PyByteInner,
};
use super::objint::PyIntRef;
use super::objiter;
@@ -15,7 +15,7 @@ use super::objstr::{PyString, PyStringRef};
use super::objtuple::PyTupleRef;
use super::objtype::PyClassRef;
use crate::cformat::CFormatString;
use crate::function::OptionalArg;
use crate::function::{OptionalArg, OptionalOption};
use crate::obj::objstr::do_cformat_string;
use crate::pyobject::{
Either, PyClassImpl, PyComparisonValue, PyContext, PyIterable, PyObjectRef, PyRef, PyResult,
@@ -373,27 +373,18 @@ impl PyByteArray {
}
#[pymethod(name = "strip")]
fn strip(&self, chars: OptionalArg<PyByteInner>) -> PyResult<PyByteArray> {
Ok(self
.borrow_value()
.strip(chars, ByteInnerPosition::All)?
.into())
fn strip(&self, chars: OptionalOption<PyByteInner>) -> PyByteArray {
self.borrow_value().strip(chars).into()
}
#[pymethod(name = "lstrip")]
fn lstrip(&self, chars: OptionalArg<PyByteInner>) -> PyResult<PyByteArray> {
Ok(self
.borrow_value()
.strip(chars, ByteInnerPosition::Left)?
.into())
fn lstrip(&self, chars: OptionalOption<PyByteInner>) -> PyByteArray {
self.borrow_value().lstrip(chars).into()
}
#[pymethod(name = "rstrip")]
fn rstrip(&self, chars: OptionalArg<PyByteInner>) -> PyResult<PyByteArray> {
Ok(self
.borrow_value()
.strip(chars, ByteInnerPosition::Right)?
.into())
fn rstrip(&self, chars: OptionalOption<PyByteInner>) -> PyByteArray {
self.borrow_value().rstrip(chars).into()
}
#[pymethod(name = "split")]
+29 -38
View File
@@ -15,7 +15,7 @@ use super::objsequence::{is_valid_slice_arg, PySliceableSequence};
use super::objslice::PySliceRef;
use super::objstr::{self, adjust_indices, PyString, PyStringRef, StringRange};
use super::objtuple::PyTupleRef;
use crate::function::OptionalArg;
use crate::function::{OptionalArg, OptionalOption};
use crate::pyhash;
use crate::pyobject::{
Either, PyComparisonValue, PyIterable, PyObjectRef, PyResult, ThreadSafe, TryFromObject,
@@ -938,40 +938,37 @@ impl PyByteInner {
Ok(res)
}
pub fn strip(
&self,
chars: OptionalArg<PyByteInner>,
position: ByteInnerPosition,
) -> PyResult<Vec<u8>> {
let is_valid_char = |c| {
if let OptionalArg::Present(ref bytes) = chars {
bytes.elements.contains(c)
} else {
c.is_ascii_whitespace()
}
pub fn strip(&self, chars: OptionalOption<PyByteInner>) -> Vec<u8> {
let chars = chars.flat_option();
let chars = match chars {
Some(ref chars) => &chars.elements,
None => return self.elements.trim().to_owned(),
};
self.elements
.trim_with(|c| chars.contains(&(c as u8)))
.to_owned()
}
let mut start = 0;
let mut end = self.len();
pub fn lstrip(&self, chars: OptionalOption<PyByteInner>) -> Vec<u8> {
let chars = chars.flat_option();
let chars = match chars {
Some(ref chars) => &chars.elements,
None => return self.elements.trim_start().to_owned(),
};
self.elements
.trim_start_with(|c| chars.contains(&(c as u8)))
.to_owned()
}
if let ByteInnerPosition::Left | ByteInnerPosition::All = position {
for (i, c) in self.elements.iter().enumerate() {
if !is_valid_char(c) {
start = i;
break;
}
}
}
if let ByteInnerPosition::Right | ByteInnerPosition::All = position {
for (i, c) in self.elements.iter().rev().enumerate() {
if !is_valid_char(c) {
end = self.len() - i;
break;
}
}
}
Ok(self.elements[start..end].to_vec())
pub fn rstrip(&self, chars: OptionalOption<PyByteInner>) -> Vec<u8> {
let chars = chars.flat_option();
let chars = match chars {
Some(ref chars) => &chars.elements,
None => return self.elements.trim_end().to_owned(),
};
self.elements
.trim_end_with(|c| chars.contains(&(c as u8)))
.to_owned()
}
pub fn split(&self, options: ByteInnerSplitOptions, reverse: bool) -> PyResult<Vec<&[u8]>> {
@@ -1213,12 +1210,6 @@ pub trait ByteOr: ToPrimitive {
impl ByteOr for BigInt {}
pub enum ByteInnerPosition {
Left,
Right,
All,
}
fn split_slice<'a>(slice: &'a [u8], sep: &[u8], maxsplit: isize) -> Vec<&'a [u8]> {
let mut splitted: Vec<&[u8]> = vec![];
let mut prev_index = 0;
+8 -9
View File
@@ -4,8 +4,7 @@ use std::ops::Deref;
use super::objbyteinner::{
ByteInnerExpandtabsOptions, ByteInnerFindOptions, ByteInnerNewOptions, ByteInnerPaddingOptions,
ByteInnerPosition, ByteInnerSplitOptions, ByteInnerSplitlinesOptions,
ByteInnerTranslateOptions, PyByteInner,
ByteInnerSplitOptions, ByteInnerSplitlinesOptions, ByteInnerTranslateOptions, PyByteInner,
};
use super::objint::PyIntRef;
use super::objiter;
@@ -14,7 +13,7 @@ use super::objstr::{PyString, PyStringRef};
use super::objtuple::PyTupleRef;
use super::objtype::PyClassRef;
use crate::cformat::CFormatString;
use crate::function::OptionalArg;
use crate::function::{OptionalArg, OptionalOption};
use crate::obj::objstr::do_cformat_string;
use crate::pyhash;
use crate::pyobject::{
@@ -329,18 +328,18 @@ impl PyBytes {
}
#[pymethod(name = "strip")]
fn strip(&self, chars: OptionalArg<PyByteInner>) -> PyResult<PyBytes> {
Ok(self.inner.strip(chars, ByteInnerPosition::All)?.into())
fn strip(&self, chars: OptionalOption<PyByteInner>) -> PyBytes {
self.inner.strip(chars).into()
}
#[pymethod(name = "lstrip")]
fn lstrip(&self, chars: OptionalArg<PyByteInner>) -> PyResult<PyBytes> {
Ok(self.inner.strip(chars, ByteInnerPosition::Left)?.into())
fn lstrip(&self, chars: OptionalOption<PyByteInner>) -> PyBytes {
self.inner.lstrip(chars).into()
}
#[pymethod(name = "rstrip")]
fn rstrip(&self, chars: OptionalArg<PyByteInner>) -> PyResult<PyBytes> {
Ok(self.inner.strip(chars, ByteInnerPosition::Right)?.into())
fn rstrip(&self, chars: OptionalOption<PyByteInner>) -> PyBytes {
self.inner.rstrip(chars).into()
}
#[pymethod(name = "split")]