@@ -24,6 +24,7 @@ _Py_IDENTIFIER(read);
2424_Py_IDENTIFIER (read1 );
2525_Py_IDENTIFIER (readable );
2626_Py_IDENTIFIER (readinto );
27+ _Py_IDENTIFIER (readinto1 );
2728_Py_IDENTIFIER (writable );
2829_Py_IDENTIFIER (write );
2930
@@ -47,17 +48,21 @@ PyDoc_STRVAR(bufferediobase_doc,
4748 );
4849
4950static PyObject *
50- bufferediobase_readinto (PyObject * self , PyObject * args )
51+ _bufferediobase_readinto_generic (PyObject * self , PyObject * args , char readinto1 )
5152{
5253 Py_buffer buf ;
5354 Py_ssize_t len ;
5455 PyObject * data ;
5556
56- if (!PyArg_ParseTuple (args , "w*:readinto" , & buf )) {
57+ if (!PyArg_ParseTuple (args ,
58+ readinto1 ? "w*:readinto1" : "w*:readinto" ,
59+ & buf )) {
5760 return NULL ;
5861 }
5962
60- data = _PyObject_CallMethodId (self , & PyId_read , "n" , buf .len );
63+ data = _PyObject_CallMethodId (self ,
64+ readinto1 ? & PyId_read1 : & PyId_read ,
65+ "n" , buf .len );
6166 if (data == NULL )
6267 goto error ;
6368
@@ -88,6 +93,18 @@ bufferediobase_readinto(PyObject *self, PyObject *args)
8893 return NULL ;
8994}
9095
96+ static PyObject *
97+ bufferediobase_readinto (PyObject * self , PyObject * args )
98+ {
99+ return _bufferediobase_readinto_generic (self , args , 0 );
100+ }
101+
102+ static PyObject *
103+ bufferediobase_readinto1 (PyObject * self , PyObject * args )
104+ {
105+ return _bufferediobase_readinto_generic (self , args , 1 );
106+ }
107+
91108static PyObject *
92109bufferediobase_unsupported (const char * message )
93110{
@@ -167,6 +184,7 @@ static PyMethodDef bufferediobase_methods[] = {
167184 {"read" , bufferediobase_read , METH_VARARGS , bufferediobase_read_doc },
168185 {"read1" , bufferediobase_read1 , METH_VARARGS , bufferediobase_read1_doc },
169186 {"readinto" , bufferediobase_readinto , METH_VARARGS , NULL },
187+ {"readinto1" , bufferediobase_readinto1 , METH_VARARGS , NULL },
170188 {"write" , bufferediobase_write , METH_VARARGS , bufferediobase_write_doc },
171189 {NULL , NULL }
172190};
@@ -988,15 +1006,17 @@ buffered_read1(buffered *self, PyObject *args)
9881006}
9891007
9901008static PyObject *
991- buffered_readinto (buffered * self , PyObject * args )
1009+ _buffered_readinto_generic (buffered * self , PyObject * args , char readinto1 )
9921010{
9931011 Py_buffer buf ;
9941012 Py_ssize_t n , written = 0 , remaining ;
9951013 PyObject * res = NULL ;
9961014
9971015 CHECK_INITIALIZED (self )
9981016
999- if (!PyArg_ParseTuple (args , "w * :readinto ", & buf ))
1017+ if (!PyArg_ParseTuple (args ,
1018+ readinto1 ? "w * :readinto1 " : "w*:readinto" ,
1019+ & buf ))
10001020 return NULL ;
10011021
10021022 n = Py_SAFE_DOWNCAST (READAHEAD (self ), Py_off_t , Py_ssize_t );
@@ -1034,7 +1054,10 @@ buffered_readinto(buffered *self, PyObject *args)
10341054 n = _bufferedreader_raw_read (self , (char * ) buf .buf + written ,
10351055 remaining );
10361056 }
1037- else {
1057+
1058+ /* In readinto1 mode, we do not want to fill the internal
1059+ buffer if we already have some data to return */
1060+ else if (!(readinto1 && written )) {
10381061 n = _bufferedreader_fill_buffer (self );
10391062 if (n > 0 ) {
10401063 if (n > remaining )
@@ -1045,6 +1068,10 @@ buffered_readinto(buffered *self, PyObject *args)
10451068 continue ; /* short circuit */
10461069 }
10471070 }
1071+ else {
1072+ n = 0 ;
1073+ }
1074+
10481075 if (n == 0 || (n == -2 && written > 0 ))
10491076 break ;
10501077 if (n < 0 ) {
@@ -1054,6 +1081,12 @@ buffered_readinto(buffered *self, PyObject *args)
10541081 }
10551082 goto end ;
10561083 }
1084+
1085+ /* At most one read in readinto1 mode */
1086+ if (readinto1 ) {
1087+ written += n ;
1088+ break ;
1089+ }
10571090 }
10581091 res = PyLong_FromSsize_t (written );
10591092
@@ -1064,6 +1097,19 @@ buffered_readinto(buffered *self, PyObject *args)
10641097 return res ;
10651098}
10661099
1100+ static PyObject *
1101+ buffered_readinto (buffered * self , PyObject * args )
1102+ {
1103+ return _buffered_readinto_generic (self , args , 0 );
1104+ }
1105+
1106+ static PyObject *
1107+ buffered_readinto1 (buffered * self , PyObject * args )
1108+ {
1109+ return _buffered_readinto_generic (self , args , 1 );
1110+ }
1111+
1112+
10671113static PyObject *
10681114_buffered_readline (buffered * self , Py_ssize_t limit )
10691115{
@@ -1749,6 +1795,7 @@ static PyMethodDef bufferedreader_methods[] = {
17491795 {"peek" , (PyCFunction )buffered_peek , METH_VARARGS },
17501796 {"read1" , (PyCFunction )buffered_read1 , METH_VARARGS },
17511797 {"readinto" , (PyCFunction )buffered_readinto , METH_VARARGS },
1798+ {"readinto1" , (PyCFunction )buffered_readinto1 , METH_VARARGS },
17521799 {"readline" , (PyCFunction )buffered_readline , METH_VARARGS },
17531800 {"seek" , (PyCFunction )buffered_seek , METH_VARARGS },
17541801 {"tell" , (PyCFunction )buffered_tell , METH_NOARGS },
@@ -2347,6 +2394,12 @@ bufferedrwpair_readinto(rwpair *self, PyObject *args)
23472394 return _forward_call (self -> reader , & PyId_readinto , args );
23482395}
23492396
2397+ static PyObject *
2398+ bufferedrwpair_readinto1 (rwpair * self , PyObject * args )
2399+ {
2400+ return _forward_call (self -> reader , & PyId_readinto1 , args );
2401+ }
2402+
23502403static PyObject *
23512404bufferedrwpair_write (rwpair * self , PyObject * args )
23522405{
@@ -2412,6 +2465,7 @@ static PyMethodDef bufferedrwpair_methods[] = {
24122465 {"peek" , (PyCFunction )bufferedrwpair_peek , METH_VARARGS },
24132466 {"read1" , (PyCFunction )bufferedrwpair_read1 , METH_VARARGS },
24142467 {"readinto" , (PyCFunction )bufferedrwpair_readinto , METH_VARARGS },
2468+ {"readinto1" , (PyCFunction )bufferedrwpair_readinto1 , METH_VARARGS },
24152469
24162470 {"write" , (PyCFunction )bufferedrwpair_write , METH_VARARGS },
24172471 {"flush" , (PyCFunction )bufferedrwpair_flush , METH_NOARGS },
@@ -2560,6 +2614,7 @@ static PyMethodDef bufferedrandom_methods[] = {
25602614 {"read" , (PyCFunction )buffered_read , METH_VARARGS },
25612615 {"read1" , (PyCFunction )buffered_read1 , METH_VARARGS },
25622616 {"readinto" , (PyCFunction )buffered_readinto , METH_VARARGS },
2617+ {"readinto1" , (PyCFunction )buffered_readinto1 , METH_VARARGS },
25632618 {"readline" , (PyCFunction )buffered_readline , METH_VARARGS },
25642619 {"peek" , (PyCFunction )buffered_peek , METH_VARARGS },
25652620 {"write" , (PyCFunction )bufferedwriter_write , METH_VARARGS },
0 commit comments