[pypy-commit] pypy release-2.3.x: issue 1752: the peek() method must not create a string slice. This leads

arigo noreply at buildbot.pypy.org
Tue May 20 18:21:28 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: release-2.3.x
Changeset: r71608:d204591b2495
Date: 2014-05-18 15:24 +0200
http://bitbucket.org/pypy/pypy/changeset/d204591b2495/

Log:	issue 1752: the peek() method must not create a string slice. This
	leads to bogus complexity as soon as the buffer size is more than
	some small number.

diff --git a/pypy/module/bz2/interp_bz2.py b/pypy/module/bz2/interp_bz2.py
--- a/pypy/module/bz2/interp_bz2.py
+++ b/pypy/module/bz2/interp_bz2.py
@@ -458,9 +458,7 @@
         return result
 
     def peek(self):
-        pos = self.pos
-        assert pos >= 0
-        return self.buffer[pos:]
+        return (self.pos, self.buffer)
 
     def try_to_find_file_descriptor(self):
         return self.stream.try_to_find_file_descriptor()
diff --git a/rpython/rlib/streamio.py b/rpython/rlib/streamio.py
--- a/rpython/rlib/streamio.py
+++ b/rpython/rlib/streamio.py
@@ -234,11 +234,12 @@
         while True:
             # "peeks" on the underlying stream to see how many characters
             # we can safely read without reading past an end-of-line
-            peeked = self.peek()
-            pn = peeked.find("\n")
+            startindex, peeked = self.peek()
+            assert 0 <= startindex <= len(peeked)
+            pn = peeked.find("\n", startindex)
             if pn < 0:
                 pn = len(peeked)
-            c = self.read(pn + 1)
+            c = self.read(pn - startindex + 1)
             if not c:
                 break
             result.append(c)
@@ -265,7 +266,7 @@
         pass
 
     def peek(self):
-        return ''
+        return (0, '')
 
     def try_to_find_file_descriptor(self):
         return -1
@@ -705,9 +706,7 @@
         return "".join(chunks)
 
     def peek(self):
-        pos = self.pos
-        assert pos >= 0
-        return self.buf[pos:]
+        return (self.pos, self.buf)
 
     write      = PassThrough("write",     flush_buffers=True)
     truncate   = PassThrough("truncate",  flush_buffers=True)
@@ -970,12 +969,13 @@
         while True:
             # "peeks" on the underlying stream to see how many characters
             # we can safely read without reading past an end-of-line
-            peeked = self.base.peek()
-            pn = peeked.find("\n")
-            pr = peeked.find("\r")
+            startindex, peeked = self.base.peek()
+            assert 0 <= startindex <= len(peeked)
+            pn = peeked.find("\n", startindex)
+            pr = peeked.find("\r", startindex)
             if pn < 0: pn = len(peeked)
             if pr < 0: pr = len(peeked)
-            c = self.read(min(pn, pr) + 1)
+            c = self.read(min(pn, pr) - startindex + 1)
             if not c:
                 break
             result.append(c)
@@ -1028,7 +1028,7 @@
                 self.buf = ""
 
     def peek(self):
-        return self.buf
+        return (0, self.buf)
 
     write      = PassThrough("write",     flush_buffers=True)
     truncate   = PassThrough("truncate",  flush_buffers=True)


More information about the pypy-commit mailing list