@@ -653,10 +653,12 @@ typedef struct
653653 PyObject * errors ;
654654 const char * writenl ; /* utf-8 encoded, NULL stands for \n */
655655 char line_buffering ;
656+ char write_through ;
656657 char readuniversal ;
657658 char readtranslate ;
658659 char writetranslate ;
659660 char seekable ;
661+ char has_read1 ;
660662 char telling ;
661663 char deallocating ;
662664 /* Specialized encoding func (see below) */
@@ -813,23 +815,23 @@ static int
813815textiowrapper_init (textio * self , PyObject * args , PyObject * kwds )
814816{
815817 char * kwlist [] = {"buffer" , "encoding" , "errors" ,
816- "newline" , "line_buffering" ,
818+ "newline" , "line_buffering" , "write_through" ,
817819 NULL };
818820 PyObject * buffer , * raw ;
819821 char * encoding = NULL ;
820822 char * errors = NULL ;
821823 char * newline = NULL ;
822- int line_buffering = 0 ;
824+ int line_buffering = 0 , write_through = 0 ;
823825 _PyIO_State * state = IO_STATE ;
824826
825827 PyObject * res ;
826828 int r ;
827829
828830 self -> ok = 0 ;
829831 self -> detached = 0 ;
830- if (!PyArg_ParseTupleAndKeywords (args , kwds , "O|zzzi :fileio" ,
832+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "O|zzzii :fileio" ,
831833 kwlist , & buffer , & encoding , & errors ,
832- & newline , & line_buffering ))
834+ & newline , & line_buffering , & write_through ))
833835 return -1 ;
834836
835837 if (newline && newline [0 ] != '\0'
@@ -935,6 +937,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
935937 self -> chunk_size = 8192 ;
936938 self -> readuniversal = (newline == NULL || newline [0 ] == '\0' );
937939 self -> line_buffering = line_buffering ;
940+ self -> write_through = write_through ;
938941 self -> readtranslate = (newline == NULL );
939942 if (newline ) {
940943 self -> readnl = PyUnicode_FromString (newline );
@@ -1044,6 +1047,8 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
10441047 self -> seekable = self -> telling = PyObject_IsTrue (res );
10451048 Py_DECREF (res );
10461049
1050+ self -> has_read1 = PyObject_HasAttrString (buffer , "read1" );
1051+
10471052 self -> encoding_start_of_stream = 0 ;
10481053 if (self -> seekable && self -> encoder ) {
10491054 PyObject * cookieObj ;
@@ -1287,7 +1292,9 @@ textiowrapper_write(textio *self, PyObject *args)
12871292 text = newtext ;
12881293 }
12891294
1290- if (self -> line_buffering &&
1295+ if (self -> write_through )
1296+ needflush = 1 ;
1297+ else if (self -> line_buffering &&
12911298 (haslf ||
12921299 findchar (PyUnicode_AS_UNICODE (text ),
12931300 PyUnicode_GET_SIZE (text ), '\r' )))
@@ -1435,7 +1442,8 @@ textiowrapper_read_chunk(textio *self)
14351442 if (chunk_size == NULL )
14361443 goto fail ;
14371444 input_chunk = PyObject_CallMethodObjArgs (self -> buffer ,
1438- _PyIO_str_read1 , chunk_size , NULL );
1445+ (self -> has_read1 ? _PyIO_str_read1 : _PyIO_str_read ),
1446+ chunk_size , NULL );
14391447 Py_DECREF (chunk_size );
14401448 if (input_chunk == NULL )
14411449 goto fail ;
0 commit comments