[Python-checkins] bpo-33361: Fix bug with seeking in StreamRecoders (GH-8278)
Berker Peksag
webhook-mailer at python.org
Fri May 31 15:44:17 EDT 2019
https://github.com/python/cpython/commit/a6ec1ce1ac05b1258931422e96eac215b6a05459
commit: a6ec1ce1ac05b1258931422e96eac215b6a05459
branch: master
author: Ammar Askar <ammar_askar at hotmail.com>
committer: Berker Peksag <berker.peksag at gmail.com>
date: 2019-05-31T22:44:00+03:00
summary:
bpo-33361: Fix bug with seeking in StreamRecoders (GH-8278)
files:
A Misc/NEWS.d/next/Library/2018-07-13-20-17-17.bpo-33361.dx2NVn.rst
M Lib/codecs.py
M Lib/test/test_codecs.py
diff --git a/Lib/codecs.py b/Lib/codecs.py
index 884be0b2c02e..21c45a7d10a4 100644
--- a/Lib/codecs.py
+++ b/Lib/codecs.py
@@ -847,6 +847,12 @@ def reset(self):
self.reader.reset()
self.writer.reset()
+ def seek(self, offset, whence=0):
+ # Seeks must be propagated to both the readers and writers
+ # as they might need to reset their internal buffers.
+ self.reader.seek(offset, whence)
+ self.writer.seek(offset, whence)
+
def __getattr__(self, name,
getattr=getattr):
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
index f665febfc90a..47df88cedaaf 100644
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -3166,6 +3166,31 @@ def test_write(self):
sr.write(text.encode('latin1'))
self.assertEqual(bio.getvalue(), text.encode('utf-8'))
+ def test_seeking_read(self):
+ bio = io.BytesIO('line1\nline2\nline3\n'.encode('utf-16-le'))
+ sr = codecs.EncodedFile(bio, 'utf-8', 'utf-16-le')
+
+ self.assertEqual(sr.readline(), b'line1\n')
+ sr.seek(0)
+ self.assertEqual(sr.readline(), b'line1\n')
+ self.assertEqual(sr.readline(), b'line2\n')
+ self.assertEqual(sr.readline(), b'line3\n')
+ self.assertEqual(sr.readline(), b'')
+
+ def test_seeking_write(self):
+ bio = io.BytesIO('123456789\n'.encode('utf-16-le'))
+ sr = codecs.EncodedFile(bio, 'utf-8', 'utf-16-le')
+
+ # Test that seek() only resets its internal buffer when offset
+ # and whence are zero.
+ sr.seek(2)
+ sr.write(b'\nabc\n')
+ self.assertEqual(sr.readline(), b'789\n')
+ sr.seek(0)
+ self.assertEqual(sr.readline(), b'1\n')
+ self.assertEqual(sr.readline(), b'abc\n')
+ self.assertEqual(sr.readline(), b'789\n')
+
@unittest.skipIf(_testcapi is None, 'need _testcapi module')
class LocaleCodecTest(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Library/2018-07-13-20-17-17.bpo-33361.dx2NVn.rst b/Misc/NEWS.d/next/Library/2018-07-13-20-17-17.bpo-33361.dx2NVn.rst
new file mode 100644
index 000000000000..2b71095984a0
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-07-13-20-17-17.bpo-33361.dx2NVn.rst
@@ -0,0 +1,2 @@
+Fix a bug in :class:`codecs.StreamRecoder` where seeking might leave old data in a
+buffer and break subsequent read calls. Patch by Ammar Askar.
More information about the Python-checkins
mailing list