[Jython-checkins] jython: Fix index computation for StringBuilder after seek back in cStringIO
jim.baker
jython-checkins at python.org
Wed Apr 15 17:09:14 CEST 2015
https://hg.python.org/jython/rev/ce136d0b598f
changeset: 7669:ce136d0b598f
user: Jim Baker <jim.baker at rackspace.com>
date: Wed Apr 15 11:09:09 2015 -0400
summary:
Fix index computation for StringBuilder after seek back in cStringIO
Also updates test_StringIO to latest, then reapply Jython-specific FIXME
for subsequent work.
Fixes http://bugs.jython.org/issue2324
files:
Lib/test/test_StringIO.py | 48 ++++++++++++++-
Lib/test/test_StringIO_jy.py | 11 +++
src/org/python/modules/cStringIO.java | 4 +-
3 files changed, 59 insertions(+), 4 deletions(-)
diff --git a/Lib/test/test_StringIO.py b/Lib/test/test_StringIO.py
--- a/Lib/test/test_StringIO.py
+++ b/Lib/test/test_StringIO.py
@@ -5,6 +5,7 @@
import cStringIO
import types
import array
+import sys
from test import test_support
@@ -27,6 +28,8 @@
eq = self.assertEqual
self.assertRaises(TypeError, self._fp.seek)
eq(self._fp.read(10), self._line[:10])
+ eq(self._fp.read(0), '')
+ eq(self._fp.readline(0), '')
eq(self._fp.readline(), self._line[10:] + '\n')
eq(len(self._fp.readlines(60)), 2)
self._fp.seek(0)
@@ -105,6 +108,45 @@
self._fp.close()
self.assertRaises(ValueError, self._fp.getvalue)
+ @test_support.bigmemtest(test_support._2G + 2**26, memuse=2.001)
+ def test_reads_from_large_stream(self, size):
+ linesize = 2**26 # 64 MiB
+ lines = ['x' * (linesize - 1) + '\n'] * (size // linesize) + \
+ ['y' * (size % linesize)]
+ f = self.MODULE.StringIO(''.join(lines))
+ for i, expected in enumerate(lines):
+ line = f.read(len(expected))
+ self.assertEqual(len(line), len(expected))
+ self.assertEqual(line, expected)
+ self.assertEqual(f.read(), '')
+ f.seek(0)
+ for i, expected in enumerate(lines):
+ line = f.readline()
+ self.assertEqual(len(line), len(expected))
+ self.assertEqual(line, expected)
+ self.assertEqual(f.readline(), '')
+ f.seek(0)
+ self.assertEqual(f.readlines(), lines)
+ self.assertEqual(f.readlines(), [])
+ f.seek(0)
+ self.assertEqual(f.readlines(size), lines)
+ self.assertEqual(f.readlines(), [])
+
+ # In worst case cStringIO requires 2 + 1 + 1/2 + 1/2**2 + ... = 4
+ # bytes per input character.
+ @test_support.bigmemtest(test_support._2G, memuse=4)
+ def test_writes_to_large_stream(self, size):
+ s = 'x' * 2**26 # 64 MiB
+ f = self.MODULE.StringIO()
+ n = size
+ while n > len(s):
+ f.write(s)
+ n -= len(s)
+ s = None
+ f.write('x' * n)
+ self.assertEqual(len(f.getvalue()), size)
+
+
class TestStringIO(TestGenericStringIO):
MODULE = StringIO
@@ -153,8 +195,10 @@
self.assertEqual(s, 'abcde')
self.assertEqual(type(s), str)
- # This cStringIO/StringIO difference seems CPython specific to me...
- if not test_support.is_jython:
+ if not test_support.is_jython: # FIXME re-enable in a future release
+ # On Jython, this should raise UnicodeEncodeError, however, we
+ # have to do more work on preventing inadvertent mixing of Unicode
+ # into String-supporting objects like StringBuilder
self.assertRaises(UnicodeEncodeError, self.MODULE.StringIO, u'\xf4')
diff --git a/Lib/test/test_StringIO_jy.py b/Lib/test/test_StringIO_jy.py
--- a/Lib/test/test_StringIO_jy.py
+++ b/Lib/test/test_StringIO_jy.py
@@ -28,6 +28,17 @@
f.write("uvwxyz")
self.assertEqual(f.getvalue(), 'abcdef\x00\x00\x00\x00uvwxyz')
+ def test_write_seek_back_then_write(self):
+ # http://bugs.jython.org/issue2324
+ s = "abcdef"
+ for i in xrange(len(s)):
+ f = cStringIO.StringIO()
+ f.write(s)
+ f.seek(i)
+ f.write("x" * 47)
+ self.assertEqual(f.getvalue(), s[:i] + ("x" * 47))
+
+
class TestGetValueAfterClose(unittest.TestCase):
# This test, or something like it, should be really be pushed upstream
diff --git a/src/org/python/modules/cStringIO.java b/src/org/python/modules/cStringIO.java
--- a/src/org/python/modules/cStringIO.java
+++ b/src/org/python/modules/cStringIO.java
@@ -372,8 +372,8 @@
if (spos < slen) {
if (newpos > slen) {
- buf.replace(spos, slen - spos, s);
- buf.append(s.substring(slen));
+ buf.replace(spos, slen, s);
+ buf.append(s.substring(slen - spos));
slen = newpos;
} else {
buf.replace(spos, spos + s.length(), s);
--
Repository URL: https://hg.python.org/jython
More information about the Jython-checkins
mailing list