Index: Lib/test/test_codecs.py =================================================================== --- Lib/test/test_codecs.py (revision 76622) +++ Lib/test/test_codecs.py (working copy) @@ -3,6 +3,8 @@ import codecs import sys, StringIO, _testcapi +from test.test_support import TESTFN, unlink + class Queue(object): """ queue: write bytes at one end, read bytes from the other end @@ -437,6 +439,21 @@ def test_errors(self): self.assertRaises(UnicodeDecodeError, codecs.utf_16_decode, "\xff", "strict", True) + def test_bug691291(self): + # Files are always opened in binary mode, even if no binary mode was + # specified. This means that no automatic conversion of '\n' is done + # on reading and writing. + s1 = u'Hello\r\nworld\r\n' + + s = s1.encode(self.encoding) + try: + with open(TESTFN, 'wb') as fp: + fp.write(s) + with codecs.open(TESTFN, 'U', encoding=self.encoding) as reader: + self.assertEqual(reader.read(), s1) + finally: + unlink(TESTFN) + class UTF16LETest(ReadTest): encoding = "utf-16-le" Index: Lib/codecs.py =================================================================== --- Lib/codecs.py (revision 76622) +++ Lib/codecs.py (working copy) @@ -861,7 +861,7 @@ if encoding is not None and \ 'b' not in mode: # Force opening of the file in binary mode - mode = mode + 'b' + mode = mode.replace('rU', 'r').replace('U', 'r') + 'b' file = __builtin__.open(filename, mode, buffering) if encoding is None: return file