diff options
author | Ammar Askar <ammar_askar@hotmail.com> | 2019-05-31 19:44:01 (GMT) |
---|---|---|
committer | Berker Peksag <berker.peksag@gmail.com> | 2019-05-31 19:44:00 (GMT) |
commit | a6ec1ce1ac05b1258931422e96eac215b6a05459 (patch) | |
tree | 55a15df467b1e34a37f408524035495e4572c502 /Lib | |
parent | aac4d0342c3e692731c189d003dbd73a8c681a34 (diff) | |
download | cpython-a6ec1ce1ac05b1258931422e96eac215b6a05459.zip cpython-a6ec1ce1ac05b1258931422e96eac215b6a05459.tar.gz cpython-a6ec1ce1ac05b1258931422e96eac215b6a05459.tar.bz2 |
bpo-33361: Fix bug with seeking in StreamRecoders (GH-8278)
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/codecs.py | 6 | ||||
-rw-r--r-- | Lib/test/test_codecs.py | 25 |
2 files changed, 31 insertions, 0 deletions
diff --git a/Lib/codecs.py b/Lib/codecs.py index 884be0b..21c45a7 100644 --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -847,6 +847,12 @@ class StreamRecoder: 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 f665feb..47df88c 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -3166,6 +3166,31 @@ class StreamRecoderTest(unittest.TestCase): 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): |