@@ -109,6 +109,43 @@ _io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
109109 return _bufferediobase_readinto_generic (self , buffer , 1 );
110110}
111111
112+ /*[clinic input]
113+ @critical_section
114+ _io._BufferedIOBase.backreadinto
115+ buffer: Py_buffer(accept={rwbuffer})
116+ /
117+ [clinic start generated code]*/
118+
119+ static PyObject *
120+ _io__BufferedIOBase_backreadinto_impl (PyObject * self , Py_buffer * buffer )
121+ /*[clinic end generated code: output=089fdcf2b4b15522 input=8240e5a3d7c8fe26]*/
122+ {
123+ Py_ssize_t len ;
124+ PyObject * data ;
125+ PyObject * attr = & _Py_ID (backread );
126+ data = _PyObject_CallMethod (self , attr , "n" , buffer -> len );
127+ if (data == NULL ) {
128+ return NULL ;
129+ }
130+ if (!PyBytes_Check (data )) {
131+ Py_DECREF (data );
132+ PyErr_SetString (PyExc_TypeError , "backread() should return bytes" );
133+ return NULL ;
134+ }
135+ len = PyBytes_GET_SIZE (data );
136+ if (len > buffer -> len ) {
137+ PyErr_Format (PyExc_ValueError ,
138+ "backread() returned too much data: "
139+ "%zd bytes requested, %zd returned" ,
140+ buffer -> len , len );
141+ Py_DECREF (data );
142+ return NULL ;
143+ }
144+ memcpy (buffer -> buf , PyBytes_AS_STRING (data ), len );
145+ Py_DECREF (data );
146+ return PyLong_FromSsize_t (len );
147+ }
148+
112149static PyObject *
113150bufferediobase_unsupported (_PyIO_State * state , const char * message )
114151{
@@ -192,6 +229,40 @@ _io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls,
192229 return bufferediobase_unsupported (state , "read1" );
193230}
194231
232+ /*[clinic input]
233+ _io._BufferedIOBase.backread
234+
235+ cls: defining_class
236+ size: int(unused=True) = -1
237+ /
238+
239+ Read backwards and return up to n bytes.
240+
241+ If the size argument is omitted, None, or negative, read and
242+ return all data until BOF.
243+
244+ If the size argument is positive, and the underlying raw stream is
245+ not 'interactive', multiple raw reads may be issued to satisfy
246+ the byte count (unless BOF is reached first).
247+ However, for interactive raw streams (as well as sockets and pipes),
248+ at most one raw read will be issued, and a short result does not
249+ imply that EOF is imminent.
250+
251+ Return an empty bytes object on BOF.
252+
253+ Return None if the underlying raw stream was open in non-blocking
254+ mode and no data is available at the moment.
255+ [clinic start generated code]*/
256+
257+ static PyObject *
258+ _io__BufferedIOBase_backread_impl (PyObject * self , PyTypeObject * cls ,
259+ int Py_UNUSED (size ))
260+ /*[clinic end generated code: output=e2aa0f9e2adc3edc input=fa5dff8791c1db97]*/
261+ {
262+ _PyIO_State * state = get_io_state_by_cls (cls );
263+ return bufferediobase_unsupported (state , "backread" );
264+ }
265+
195266/*[clinic input]
196267_io._BufferedIOBase.write
197268
@@ -1074,6 +1145,21 @@ _io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
10741145 return res ;
10751146}
10761147
1148+ /*[clinic input]
1149+ @critical_section
1150+ _io._Buffered.backread
1151+ size as n: Py_ssize_t(accept={int, NoneType}) = -1
1152+ /
1153+ [clinic start generated code]*/
1154+
1155+ static PyObject *
1156+ _io__Buffered_backread_impl (buffered * self , Py_ssize_t n )
1157+ /*[clinic end generated code: output=1d9419484778ae01 input=e0459b8a28c1bc41]*/
1158+ {
1159+ _PyIO_State * state = get_io_state_by_cls (Py_TYPE (self ));
1160+ return bufferediobase_unsupported (state , "backread" );
1161+ }
1162+
10771163static PyObject *
10781164_buffered_readinto_generic (buffered * self , Py_buffer * buffer , char readinto1 )
10791165{
@@ -1184,6 +1270,20 @@ _io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
11841270 return _buffered_readinto_generic (self , buffer , 1 );
11851271}
11861272
1273+ /*[clinic input]
1274+ @critical_section
1275+ _io._Buffered.backreadinto
1276+ buffer: Py_buffer(accept={rwbuffer})
1277+ /
1278+ [clinic start generated code]*/
1279+
1280+ static PyObject *
1281+ _io__Buffered_backreadinto_impl (buffered * self , Py_buffer * buffer )
1282+ /*[clinic end generated code: output=740fec02a2357570 input=d596047fa0898560]*/
1283+ {
1284+ _PyIO_State * state = get_io_state_by_cls (Py_TYPE (self ));
1285+ return bufferediobase_unsupported (state , "backreadinto" );
1286+ }
11871287
11881288static PyObject *
11891289_buffered_readline (buffered * self , Py_ssize_t limit )
@@ -1308,6 +1408,20 @@ _io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
13081408 return _buffered_readline (self , size );
13091409}
13101410
1411+ /*[clinic input]
1412+ @critical_section
1413+ _io._Buffered.backreadline
1414+ size: Py_ssize_t(accept={int, NoneType}) = -1
1415+ /
1416+ [clinic start generated code]*/
1417+
1418+ static PyObject *
1419+ _io__Buffered_backreadline_impl (buffered * self , Py_ssize_t size )
1420+ /*[clinic end generated code: output=dab0e1127f375a53 input=bfaa97db6dc41727]*/
1421+ {
1422+ _PyIO_State * state = get_io_state_by_cls (Py_TYPE (self ));
1423+ return bufferediobase_unsupported (state , "backreadline" );
1424+ }
13111425
13121426/*[clinic input]
13131427@critical_section
@@ -2334,6 +2448,12 @@ bufferedrwpair_read(rwpair *self, PyObject *args)
23342448 return _forward_call (self -> reader , & _Py_ID (read ), args );
23352449}
23362450
2451+ static PyObject *
2452+ bufferedrwpair_backread (rwpair * self , PyObject * args )
2453+ {
2454+ return _forward_call (self -> reader , & _Py_ID (backread ), args );
2455+ }
2456+
23372457static PyObject *
23382458bufferedrwpair_peek (rwpair * self , PyObject * args )
23392459{
@@ -2352,6 +2472,12 @@ bufferedrwpair_readinto(rwpair *self, PyObject *args)
23522472 return _forward_call (self -> reader , & _Py_ID (readinto ), args );
23532473}
23542474
2475+ static PyObject *
2476+ bufferedrwpair_backreadinto (rwpair * self , PyObject * args )
2477+ {
2478+ return _forward_call (self -> reader , & _Py_ID (backreadinto ), args );
2479+ }
2480+
23552481static PyObject *
23562482bufferedrwpair_readinto1 (rwpair * self , PyObject * args )
23572483{
@@ -2486,6 +2612,8 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
24862612#undef clinic_state
24872613
24882614static PyMethodDef bufferediobase_methods [] = {
2615+ _IO__BUFFEREDIOBASE_BACKREAD_METHODDEF
2616+ _IO__BUFFEREDIOBASE_BACKREADINTO_METHODDEF
24892617 _IO__BUFFEREDIOBASE_DETACH_METHODDEF
24902618 _IO__BUFFEREDIOBASE_READ_METHODDEF
24912619 _IO__BUFFEREDIOBASE_READ1_METHODDEF
@@ -2523,9 +2651,12 @@ static PyMethodDef bufferedreader_methods[] = {
25232651 _IO__BUFFERED_READ_METHODDEF
25242652 _IO__BUFFERED_PEEK_METHODDEF
25252653 _IO__BUFFERED_READ1_METHODDEF
2654+ _IO__BUFFERED_BACKREAD_METHODDEF
25262655 _IO__BUFFERED_READINTO_METHODDEF
25272656 _IO__BUFFERED_READINTO1_METHODDEF
2657+ _IO__BUFFERED_BACKREADINTO_METHODDEF
25282658 _IO__BUFFERED_READLINE_METHODDEF
2659+ _IO__BUFFERED_BACKREADLINE_METHODDEF
25292660 _IO__BUFFERED_SEEK_METHODDEF
25302661 _IO__BUFFERED_TELL_METHODDEF
25312662 _IO__BUFFERED_TRUNCATE_METHODDEF
@@ -2637,7 +2768,9 @@ static PyMethodDef bufferedrwpair_methods[] = {
26372768 {"read" , (PyCFunction )bufferedrwpair_read , METH_VARARGS },
26382769 {"peek" , (PyCFunction )bufferedrwpair_peek , METH_VARARGS },
26392770 {"read1" , (PyCFunction )bufferedrwpair_read1 , METH_VARARGS },
2771+ {"backread" , (PyCFunction )bufferedrwpair_backread , METH_VARARGS },
26402772 {"readinto" , (PyCFunction )bufferedrwpair_readinto , METH_VARARGS },
2773+ {"backreadinto" , (PyCFunction )bufferedrwpair_backreadinto , METH_VARARGS },
26412774 {"readinto1" , (PyCFunction )bufferedrwpair_readinto1 , METH_VARARGS },
26422775
26432776 {"write" , (PyCFunction )bufferedrwpair_write , METH_VARARGS },
@@ -2702,9 +2835,12 @@ static PyMethodDef bufferedrandom_methods[] = {
27022835 _IO__BUFFERED_TRUNCATE_METHODDEF
27032836 _IO__BUFFERED_READ_METHODDEF
27042837 _IO__BUFFERED_READ1_METHODDEF
2838+ _IO__BUFFERED_BACKREAD_METHODDEF
27052839 _IO__BUFFERED_READINTO_METHODDEF
27062840 _IO__BUFFERED_READINTO1_METHODDEF
2841+ _IO__BUFFERED_BACKREADINTO_METHODDEF
27072842 _IO__BUFFERED_READLINE_METHODDEF
2843+ _IO__BUFFERED_BACKREADLINE_METHODDEF
27082844 _IO__BUFFERED_PEEK_METHODDEF
27092845 _IO_BUFFEREDWRITER_WRITE_METHODDEF
27102846 _IO__BUFFERED___SIZEOF___METHODDEF
0 commit comments