Author: Armin Rigo <[email protected]>
Branch: py3.5-bytearray
Changeset: r88843:a862812d5e11
Date: 2016-12-03 11:54 +0100
http://bitbucket.org/pypy/pypy/changeset/a862812d5e11/
Log: .find, .index, .__contains__ should work without forcing _offset==0
diff --git a/pypy/objspace/std/bytearrayobject.py
b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -18,7 +18,7 @@
getbytevalue, makebytesdata_w, newbytesdata_w)
from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef
-from pypy.objspace.std.sliceobject import W_SliceObject
+from pypy.objspace.std.sliceobject import W_SliceObject, unwrap_start_stop
from pypy.objspace.std.stringmethods import StringMethods, _get_buffer
from pypy.objspace.std.bytesobject import W_BytesObject
from pypy.objspace.std.util import get_positive_index
@@ -498,7 +498,13 @@
return self._getitem_result(space, index)
def descr_alloc(self, space):
- return space.wrap(self._len() + 1)
+ return space.wrap(len(self._data) + 1) # includes the _offset part
+
+ def _convert_idx_params(self, space, w_start, w_end):
+ # optimization: this version doesn't force getdata()
+ start, end = unwrap_start_stop(space, self._len(), w_start, w_end)
+ ofs = self._offset
+ return (self._data, start + ofs, end + ofs, ofs)
# ____________________________________________________________
diff --git a/pypy/objspace/std/stringmethods.py
b/pypy/objspace/std/stringmethods.py
--- a/pypy/objspace/std/stringmethods.py
+++ b/pypy/objspace/std/stringmethods.py
@@ -25,7 +25,8 @@
value = self._val(space)
lenself = len(value)
start, end = unwrap_start_stop(space, lenself, w_start, w_end)
- return (value, start, end)
+ # the None means "no offset"; see bytearrayobject.py
+ return (value, start, end, None)
@staticmethod
def descr_maketrans(space, w_type, w_from, w_to):
@@ -79,12 +80,12 @@
return W_StringIterObject(self, self._iter_getitem_result)
def descr_contains(self, space, w_sub):
- value = self._val(space)
+ value, start, end, _ = self._convert_idx_params(space, None, None)
other = self._op_val(space, w_sub, allow_char=True)
if self._use_rstr_ops(space, w_sub):
- res = value.find(other)
+ res = value.find(other, start, end)
else:
- res = find(value, other, 0, len(value))
+ res = find(value, other, start, end)
return space.newbool(res >= 0)
def descr_add(self, space, w_other):
@@ -179,7 +180,7 @@
return self._new(centered)
def descr_count(self, space, w_sub, w_start=None, w_end=None):
- value, start, end = self._convert_idx_params(space, w_start, w_end)
+ value, start, end, _ = self._convert_idx_params(space, w_start, w_end)
sub = self._op_val(space, w_sub, allow_char=True)
if self._use_rstr_ops(space, w_sub):
@@ -247,27 +248,31 @@
return distance
def descr_find(self, space, w_sub, w_start=None, w_end=None):
- (value, start, end) = self._convert_idx_params(space, w_start, w_end)
+ value, start, end, ofs = self._convert_idx_params(space, w_start,
w_end)
sub = self._op_val(space, w_sub, allow_char=True)
if self._use_rstr_ops(space, w_sub):
res = value.find(sub, start, end)
else:
res = find(value, sub, start, end)
+ if ofs is not None and res >= 0:
+ res -= ofs
return space.wrap(res)
def descr_rfind(self, space, w_sub, w_start=None, w_end=None):
- (value, start, end) = self._convert_idx_params(space, w_start, w_end)
+ value, start, end, ofs = self._convert_idx_params(space, w_start,
w_end)
sub = self._op_val(space, w_sub, allow_char=True)
if self._use_rstr_ops(space, w_sub):
res = value.rfind(sub, start, end)
else:
res = rfind(value, sub, start, end)
+ if ofs is not None and res >= 0:
+ res -= ofs
return space.wrap(res)
def descr_index(self, space, w_sub, w_start=None, w_end=None):
- (value, start, end) = self._convert_idx_params(space, w_start, w_end)
+ value, start, end, ofs = self._convert_idx_params(space, w_start,
w_end)
sub = self._op_val(space, w_sub, allow_char=True)
if self._use_rstr_ops(space, w_sub):
@@ -278,10 +283,12 @@
if res < 0:
raise oefmt(space.w_ValueError,
"substring not found in " + self._KIND2 + ".index")
+ if ofs is not None:
+ res -= ofs
return space.wrap(res)
def descr_rindex(self, space, w_sub, w_start=None, w_end=None):
- (value, start, end) = self._convert_idx_params(space, w_start, w_end)
+ value, start, end, ofs = self._convert_idx_params(space, w_start,
w_end)
sub = self._op_val(space, w_sub, allow_char=True)
if self._use_rstr_ops(space, w_sub):
@@ -292,6 +299,8 @@
if res < 0:
raise oefmt(space.w_ValueError,
"substring not found in " + self._KIND2 + ".rindex")
+ if ofs is not None:
+ res -= ofs
return space.wrap(res)
@specialize.arg(2)
@@ -595,7 +604,7 @@
return "bytes"
def descr_startswith(self, space, w_prefix, w_start=None, w_end=None):
- (value, start, end) = self._convert_idx_params(space, w_start, w_end)
+ value, start, end, _ = self._convert_idx_params(space, w_start, w_end)
if space.isinstance_w(w_prefix, space.w_tuple):
return self._startswith_tuple(space, value, w_prefix, start, end)
try:
@@ -620,7 +629,7 @@
return startswith(value, prefix, start, end)
def descr_endswith(self, space, w_suffix, w_start=None, w_end=None):
- (value, start, end) = self._convert_idx_params(space, w_start, w_end)
+ value, start, end, _ = self._convert_idx_params(space, w_start, w_end)
if space.isinstance_w(w_suffix, space.w_tuple):
return self._endswith_tuple(space, value, w_suffix, start, end)
try:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit