@@ -415,8 +415,8 @@ class BufferedIOBase(IOBase):
415415 def read (self , n : int = - 1 ) -> bytes :
416416 """read(n: int = -1) -> bytes. Read and return up to n bytes.
417417
418- If the argument is omitted, or negative, reads and returns all
419- data until EOF.
418+ If the argument is omitted, None, or negative, reads and
419+ returns all data until EOF.
420420
421421 If the argument is positive, and the underlying raw stream is
422422 not 'interactive', multiple raw reads may be issued to satisfy
@@ -450,6 +450,20 @@ def readinto(self, b: bytes) -> int:
450450 b [:n ] = data
451451 return n
452452
453+ def readline (self , sizehint : int = - 1 ) -> bytes :
454+ """For backwards compatibility, a (slow) readline()."""
455+ if sizehint is None :
456+ sizehint = - 1
457+ res = b""
458+ while sizehint < 0 or len (res ) < sizehint :
459+ b = self .read (1 )
460+ if not b :
461+ break
462+ res += b
463+ if b == b"\n " :
464+ break
465+ return res
466+
453467 def write (self , b : bytes ) -> int :
454468 """write(b: bytes) -> int. Write the given buffer to the IO stream.
455469
@@ -518,26 +532,35 @@ def isatty(self):
518532 return self .raw .isatty ()
519533
520534
521- class _MemoryIOMixin (BufferedIOBase ):
535+ class BytesIO (BufferedIOBase ):
522536
523- # XXX docstring
537+ """Buffered I/O implementation using an in-memory bytes buffer."""
524538
525- def __init__ (self , buffer ):
539+ # XXX More docs
540+
541+ def __init__ (self , initial_bytes = None ):
542+ buffer = b""
543+ if initial_bytes is not None :
544+ buffer += initial_bytes
526545 self ._buffer = buffer
527546 self ._pos = 0
528547
529548 def getvalue (self ):
530549 return self ._buffer
531550
532- def read (self , n = - 1 ):
533- assert n is not None
551+ def read (self , n = None ):
552+ if n is None :
553+ n = - 1
534554 if n < 0 :
535555 n = len (self ._buffer )
536556 newpos = min (len (self ._buffer ), self ._pos + n )
537557 b = self ._buffer [self ._pos : newpos ]
538558 self ._pos = newpos
539559 return b
540560
561+ def read1 (self , n ):
562+ return self .read (n )
563+
541564 def write (self , b ):
542565 n = len (b )
543566 newpos = self ._pos + n
@@ -575,65 +598,6 @@ def seekable(self):
575598 return True
576599
577600
578- class BytesIO (_MemoryIOMixin ):
579-
580- """Buffered I/O implementation using a bytes buffer, like StringIO."""
581-
582- # XXX More docs
583-
584- def __init__ (self , initial_bytes = None ):
585- buffer = b""
586- if initial_bytes is not None :
587- buffer += initial_bytes
588- _MemoryIOMixin .__init__ (self , buffer )
589-
590-
591- # XXX This should inherit from TextIOBase
592- class StringIO (_MemoryIOMixin ):
593-
594- """Buffered I/O implementation using a string buffer, like StringIO."""
595-
596- # XXX More docs
597-
598- # Reuses the same code as BytesIO, but encode strings on the way in
599- # and decode them on the way out.
600-
601- charsize = len ("!" .encode ("unicode-internal" ))
602-
603- def __init__ (self , initial_string = None ):
604- if initial_string is not None :
605- buffer = initial_string .encode ("unicode-internal" )
606- else :
607- buffer = b""
608- _MemoryIOMixin .__init__ (self , buffer )
609-
610- def getvalue (self ):
611- return self ._buffer .encode ("unicode-internal" )
612-
613- def read (self , n = - 1 ):
614- return super (StringIO , self ).read (n * self .charsize ) \
615- .decode ("unicode-internal" )
616-
617- def write (self , s ):
618- return super (StringIO , self ).write (s .encode ("unicode-internal" )) \
619- // self .charsize
620-
621- def seek (self , pos , whence = 0 ):
622- return super (StringIO , self ).seek (self .charsize * pos , whence ) \
623- // self .charsize
624-
625- def tell (self ):
626- return super (StringIO , self ).tell ()// self .charsize
627-
628- def truncate (self , pos = None ):
629- if pos is not None :
630- pos *= self .charsize
631- return super (StringIO , self ).truncate (pos )// self .charsize
632-
633- def readinto (self , b : bytes ) -> int :
634- self ._unsupported ("readinto" )
635-
636-
637601class BufferedReader (_BufferedIOMixin ):
638602
639603 """Buffer for a readable sequential RawIO object."""
@@ -646,15 +610,16 @@ def __init__(self, raw, buffer_size=DEFAULT_BUFFER_SIZE):
646610 self ._read_buf = b""
647611 self .buffer_size = buffer_size
648612
649- def read (self , n = - 1 ):
613+ def read (self , n = None ):
650614 """Read n bytes.
651615
652616 Returns exactly n bytes of data unless the underlying raw IO
653617 stream reaches EOF of if the call would block in non-blocking
654618 mode. If n is negative, read until EOF or until read() would
655619 block.
656620 """
657- assert n is not None
621+ if n is None :
622+ n = - 1
658623 nodata_val = b""
659624 while n < 0 or len (self ._read_buf ) < n :
660625 to_read = max (self .buffer_size ,
@@ -801,7 +766,9 @@ def __init__(self, reader, writer,
801766 self .reader = BufferedReader (reader , buffer_size )
802767 self .writer = BufferedWriter (writer , buffer_size , max_buffer_size )
803768
804- def read (self , n = - 1 ):
769+ def read (self , n = None ):
770+ if n is None :
771+ n = - 1
805772 return self .reader .read (n )
806773
807774 def readinto (self , b ):
@@ -861,7 +828,9 @@ def tell(self):
861828 else :
862829 return self .raw .tell () - len (self ._read_buf )
863830
864- def read (self , n = - 1 ):
831+ def read (self , n = None ):
832+ if n is None :
833+ n = - 1
865834 self .flush ()
866835 return BufferedReader .read (self , n )
867836
@@ -1129,7 +1098,9 @@ def _simplify(self, u):
11291098 except UnicodeEncodeError :
11301099 return u
11311100
1132- def read (self , n : int = - 1 ):
1101+ def read (self , n = None ):
1102+ if n is None :
1103+ n = - 1
11331104 decoder = self ._decoder or self ._get_decoder ()
11341105 res = self ._pending
11351106 if n < 0 :
@@ -1146,7 +1117,7 @@ def read(self, n: int = -1):
11461117 self ._pending = res [n :]
11471118 return self ._simplify (res [:n ])
11481119
1149- def __next__ (self ) -> str :
1120+ def __next__ (self ):
11501121 self ._telling = False
11511122 line = self .readline ()
11521123 if not line :
@@ -1218,3 +1189,17 @@ def readline(self, limit=None):
12181189 return self ._simplify (line [:endpos ] + "\n " )
12191190 else :
12201191 return self ._simplify (line [:nextpos ])
1192+
1193+
1194+ class StringIO (TextIOWrapper ):
1195+
1196+ # XXX This is really slow, but fully functional
1197+
1198+ def __init__ (self , initial_value = "" ):
1199+ super (StringIO , self ).__init__ (BytesIO (), "utf-8" )
1200+ if initial_value :
1201+ self .write (initial_value )
1202+ self .seek (0 )
1203+
1204+ def getvalue (self ):
1205+ return self .buffer .getvalue ().decode ("utf-8" )
0 commit comments