@@ -396,6 +396,8 @@ def __exit__(self, type, value, tb):
396396
397397class StreamReader (Codec ):
398398
399+ charbuffertype = str
400+
399401 def __init__ (self , stream , errors = 'strict' ):
400402
401403 """ Creates a StreamReader instance.
@@ -417,9 +419,8 @@ def __init__(self, stream, errors='strict'):
417419 self .stream = stream
418420 self .errors = errors
419421 self .bytebuffer = b""
420- # For str->str decoding this will stay a str
421- # For str->unicode decoding the first read will promote it to unicode
422- self .charbuffer = ""
422+ self ._empty_charbuffer = self .charbuffertype ()
423+ self .charbuffer = self ._empty_charbuffer
423424 self .linebuffer = None
424425
425426 def decode (self , input , errors = 'strict' ):
@@ -455,7 +456,7 @@ def read(self, size=-1, chars=-1, firstline=False):
455456 """
456457 # If we have lines cached, first merge them back into characters
457458 if self .linebuffer :
458- self .charbuffer = "" .join (self .linebuffer )
459+ self .charbuffer = self . _empty_charbuffer .join (self .linebuffer )
459460 self .linebuffer = None
460461
461462 # read until we get the required number of characters (if available)
@@ -498,7 +499,7 @@ def read(self, size=-1, chars=-1, firstline=False):
498499 if chars < 0 :
499500 # Return everything we've got
500501 result = self .charbuffer
501- self .charbuffer = ""
502+ self .charbuffer = self . _empty_charbuffer
502503 else :
503504 # Return the first chars characters
504505 result = self .charbuffer [:chars ]
@@ -529,15 +530,16 @@ def readline(self, size=None, keepends=True):
529530 return line
530531
531532 readsize = size or 72
532- line = ""
533+ line = self . _empty_charbuffer
533534 # If size is given, we call read() only once
534535 while True :
535536 data = self .read (readsize , firstline = True )
536537 if data :
537538 # If we're at a "\r" read one extra character (which might
538539 # be a "\n") to get a proper line ending. If the stream is
539540 # temporarily exhausted we return the wrong line ending.
540- if data .endswith ("\r " ):
541+ if (isinstance (data , str ) and data .endswith ("\r " )) or \
542+ (isinstance (data , bytes ) and data .endswith (b"\r " )):
541543 data += self .read (size = 1 , chars = 1 )
542544
543545 line += data
@@ -563,7 +565,8 @@ def readline(self, size=None, keepends=True):
563565 line0withoutend = lines [0 ].splitlines (False )[0 ]
564566 if line0withend != line0withoutend : # We really have a line end
565567 # Put the rest back together and keep it until the next call
566- self .charbuffer = "" .join (lines [1 :]) + self .charbuffer
568+ self .charbuffer = self ._empty_charbuffer .join (lines [1 :]) + \
569+ self .charbuffer
567570 if keepends :
568571 line = line0withend
569572 else :
@@ -574,7 +577,7 @@ def readline(self, size=None, keepends=True):
574577 if line and not keepends :
575578 line = line .splitlines (False )[0 ]
576579 break
577- if readsize < 8000 :
580+ if readsize < 8000 :
578581 readsize *= 2
579582 return line
580583
@@ -603,7 +606,7 @@ def reset(self):
603606
604607 """
605608 self .bytebuffer = b""
606- self .charbuffer = ""
609+ self .charbuffer = self . _empty_charbuffer
607610 self .linebuffer = None
608611
609612 def seek (self , offset , whence = 0 ):
0 commit comments