diff -r 51dc9b2a5b35 Lib/codecs.py --- a/Lib/codecs.py Fri Jan 10 15:08:07 2014 +0200 +++ b/Lib/codecs.py Fri Jan 10 21:40:19 2014 +0200 @@ -475,14 +475,11 @@ # read until we get the required number of characters (if available) while True: # can the request be satisfied from the character buffer? - if chars < 0: - if size < 0: - if self.charbuffer: - break - elif len(self.charbuffer) >= size: + if chars >= 0: + if len(self.charbuffer) >= chars: break - else: - if len(self.charbuffer) >= chars: + elif size >= 0: + if len(self.charbuffer) >= size: break # we need more data if size < 0: @@ -491,6 +488,8 @@ newdata = self.stream.read(size) # decode bytes (those remaining from the last call included) data = self.bytebuffer + newdata + if not data: + break try: newchars, decodedbytes = self.decode(data, self.errors) except UnicodeDecodeError as exc: diff -r 51dc9b2a5b35 Lib/test/test_codecs.py --- a/Lib/test/test_codecs.py Fri Jan 10 15:08:07 2014 +0200 +++ b/Lib/test/test_codecs.py Fri Jan 10 21:40:19 2014 +0200 @@ -175,6 +175,40 @@ size*"a", ) + def test_mixed_readline_and_read(self): + lines = ["Humpty Dumpty sat on a wall,\n", + "Humpty Dumpty had a great fall.\r\n", + "All the king's horses and all the king's men\r", + "Couldn't put Humpty together again."] + data = ''.join(lines) + def getreader(): + stream = io.BytesIO(data.encode(self.encoding)) + return codecs.getreader(self.encoding)(stream) + + # Issue #8260: Test readline() followed by read() + f = getreader() + self.assertEqual(f.readline(), lines[0]) + self.assertEqual(f.read(), ''.join(lines[1:])) + self.assertEqual(f.read(), '') + + # Issue #16636: Test readline() followed by readlines() + f = getreader() + self.assertEqual(f.readline(), lines[0]) + self.assertEqual(f.readlines(), lines[1:]) + self.assertEqual(f.read(), '') + + # Test read() followed by read() + f = getreader() + self.assertEqual(f.read(size=40, chars=5), data[:5]) + self.assertEqual(f.read(), data[5:]) + self.assertEqual(f.read(), '') + + # Issue #12446: Test read() followed by readlines() + f = getreader() + self.assertEqual(f.read(size=40, chars=5), data[:5]) + self.assertEqual(f.readlines(), [lines[0][5:]] + lines[1:]) + self.assertEqual(f.read(), '') + def test_bug1175396(self): s = [ '<%!--===================================================\r\n',