diff options
-rw-r--r-- | Lib/codecs.py | 13 | ||||
-rw-r--r-- | Lib/encodings/utf_16.py | 20 | ||||
-rw-r--r-- | Lib/encodings/utf_32.py | 20 | ||||
-rw-r--r-- | Lib/test/test_codecs.py | 42 | ||||
-rw-r--r-- | Misc/NEWS | 5 |
5 files changed, 78 insertions, 22 deletions
diff --git a/Lib/codecs.py b/Lib/codecs.py index e903f2e..f4cd60a 100644 --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -370,6 +370,11 @@ class StreamWriter(Codec): """ pass + def seek(self, offset, whence=0): + self.stream.seek(offset, whence) + if whence == 0 and offset == 0: + self.reset() + def __getattr__(self, name, getattr=getattr): @@ -601,8 +606,8 @@ class StreamReader(Codec): Resets the codec buffers used for keeping state. """ - self.reset() self.stream.seek(offset, whence) + self.reset() def next(self): @@ -695,8 +700,10 @@ class StreamReaderWriter: self.writer.reset() def seek(self, offset, whence=0): - self.reader.seek(offset, whence) - self.writer.seek(offset, whence) + self.stream.seek(offset, whence) + self.reader.reset() + if whence == 0 and offset == 0: + self.writer.reset() def __getattr__(self, name, getattr=getattr): diff --git a/Lib/encodings/utf_16.py b/Lib/encodings/utf_16.py index eff08f3..61bb041 100644 --- a/Lib/encodings/utf_16.py +++ b/Lib/encodings/utf_16.py @@ -58,17 +58,23 @@ class IncrementalDecoder(codecs.BufferedIncrementalDecoder): class StreamWriter(codecs.StreamWriter): def __init__(self, stream, errors='strict'): - self.bom_written = False codecs.StreamWriter.__init__(self, stream, errors) + self.encoder = None + + def reset(self): + codecs.StreamWriter.reset(self) + self.encoder = None def encode(self, input, errors='strict'): - self.bom_written = True - result = codecs.utf_16_encode(input, errors) - if sys.byteorder == 'little': - self.encode = codecs.utf_16_le_encode + if self.encoder is None: + result = codecs.utf_16encoder(input, errors) + if sys.byteorder == 'little': + self.encoder = codecs.utf_16_leencoder + else: + self.encoder = codecs.utf_16_beencoder + return result else: - self.encode = codecs.utf_16_be_encode - return result + return self.encoder(input, errors) class StreamReader(codecs.StreamReader): diff --git a/Lib/encodings/utf_32.py b/Lib/encodings/utf_32.py index 4bbd22a..ed73809 100644 --- a/Lib/encodings/utf_32.py +++ b/Lib/encodings/utf_32.py @@ -98,17 +98,23 @@ class IncrementalDecoder(codecs.BufferedIncrementalDecoder): class StreamWriter(codecs.StreamWriter): def __init__(self, stream, errors='strict'): - self.bom_written = False + self.encoder = None codecs.StreamWriter.__init__(self, stream, errors) + def reset(self): + codecs.StreamWriter.reset(self) + self.encoder = None + def encode(self, input, errors='strict'): - self.bom_written = True - result = codecs.utf_32_encode(input, errors) - if sys.byteorder == 'little': - self.encode = codecs.utf_32_le_encode + if self.encoder is None: + result = codecs.utf_32encoder(input, errors) + if sys.byteorder == 'little': + self.encoder = codecs.utf_32_leencoder + else: + self.encoder = codecs.utf_32_beencoder + return result else: - self.encode = codecs.utf_32_be_encode - return result + return self.encoder(input, errors) class StreamReader(codecs.StreamReader): diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 306a3b2..ff91ce4 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -1498,7 +1498,7 @@ class WithStmtTest(unittest.TestCase): class BomTest(unittest.TestCase): def test_seek0(self): - data = "1234567890" + data = u"1234567890" tests = ("utf-16", "utf-16-le", "utf-16-be", @@ -1506,8 +1506,8 @@ class BomTest(unittest.TestCase): "utf-32-le", "utf-32-be") for encoding in tests: - with codecs.open('foo', 'wt+', encoding=encoding) as f: - # Check if the BOM is written only once + # Check if the BOM is written only once + with codecs.open(test_support.TESTFN, 'w+', encoding=encoding) as f: f.write(data) f.write(data) f.seek(0) @@ -1515,6 +1515,42 @@ class BomTest(unittest.TestCase): f.seek(0) self.assertEquals(f.read(), data * 2) + # Check that the BOM is written after a seek(0) + with codecs.open(test_support.TESTFN, 'w+', encoding=encoding) as f: + f.write(data[0]) + self.assertNotEquals(f.tell(), 0) + f.seek(0) + f.write(data) + f.seek(0) + self.assertEquals(f.read(), data) + + # (StreamWriter) Check that the BOM is written after a seek(0) + with codecs.open(test_support.TESTFN, 'w+', encoding=encoding) as f: + f.writer.write(data[0]) + self.assertNotEquals(f.writer.tell(), 0) + f.writer.seek(0) + f.writer.write(data) + f.seek(0) + self.assertEquals(f.read(), data) + + # Check that the BOM is not written after a seek() at a position + # different than the start + with codecs.open(test_support.TESTFN, 'w+', encoding=encoding) as f: + f.write(data) + f.seek(f.tell()) + f.write(data) + f.seek(0) + self.assertEquals(f.read(), data * 2) + + # (StreamWriter) Check that the BOM is not written after a seek() + # at a position different than the start + with codecs.open(test_support.TESTFN, 'w+', encoding=encoding) as f: + f.writer.write(data) + f.writer.seek(f.writer.tell()) + f.writer.write(data) + f.seek(0) + self.assertEquals(f.read(), data * 2) + def test_main(): test_support.run_unittest( @@ -31,8 +31,9 @@ Library - Issue #3924: Ignore cookies with invalid "version" field in cookielib. -- Issue #6268: Fix seek() method of codecs.open(), don't read the BOM twice - after seek(0) +- Issue #6268: Fix seek() method of codecs.open(), don't read or write the BOM + twice after seek(0). Fix also reset() method of codecs, UTF-16, UTF-32 and + StreamWriter classes. - Issue #5640: Fix Shift-JIS incremental encoder for error handlers different than strict |