Skip to content

Commit c5b9e4f

Browse files
committed
add abstract interface
1 parent 5cfb598 commit c5b9e4f

14 files changed

+1086
-5
lines changed

Include/internal/pycore_global_objects_fini_generated.h

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ struct _Py_global_strings {
298298
STRUCT_FOR_ID(authorizer_callback)
299299
STRUCT_FOR_ID(autocommit)
300300
STRUCT_FOR_ID(b)
301+
STRUCT_FOR_ID(backread)
302+
STRUCT_FOR_ID(backreadinto)
301303
STRUCT_FOR_ID(backtick)
302304
STRUCT_FOR_ID(base)
303305
STRUCT_FOR_ID(before)

Include/internal/pycore_runtime_init_generated.h

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_unicodeobject_generated.h

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/_io/bufferedio.c

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
112149
static PyObject *
113150
bufferediobase_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+
10771163
static 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

11881288
static 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+
23372457
static PyObject *
23382458
bufferedrwpair_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+
23552481
static PyObject *
23562482
bufferedrwpair_readinto1(rwpair *self, PyObject *args)
23572483
{
@@ -2486,6 +2612,8 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
24862612
#undef clinic_state
24872613

24882614
static 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

Modules/_io/bytesio.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,25 @@ _io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size)
460460
return _io_BytesIO_read_impl(self, size);
461461
}
462462

463+
/*[clinic input]
464+
_io.BytesIO.backread
465+
size: Py_ssize_t(accept={int, NoneType}) = -1
466+
/
467+
468+
Read backwards at most size bytes, returned as a bytes object.
469+
470+
If the size argument is negative, read until EOF is reached.
471+
Return an empty bytes object at EOF.
472+
[clinic start generated code]*/
473+
474+
static PyObject *
475+
_io_BytesIO_backread_impl(bytesio *self, Py_ssize_t size)
476+
/*[clinic end generated code: output=d3bccd201010ec0a input=3277833a962d0635]*/
477+
{
478+
PyErr_Format(PyExc_NotImplementedError, "TODO");
479+
return NULL;
480+
}
481+
463482
/*[clinic input]
464483
_io.BytesIO.readline
465484
size: Py_ssize_t(accept={int, NoneType}) = -1
@@ -485,6 +504,26 @@ _io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size)
485504
return read_bytes(self, n);
486505
}
487506

507+
/*[clinic input]
508+
_io.BytesIO.backreadline
509+
size: Py_ssize_t(accept={int, NoneType}) = -1
510+
/
511+
512+
Next line from the end of the file, as a bytes object.
513+
514+
Retain newline. A non-negative size argument limits the maximum
515+
number of bytes to return (an incomplete line may be returned then).
516+
Return an empty bytes object at BOF.
517+
[clinic start generated code]*/
518+
519+
static PyObject *
520+
_io_BytesIO_backreadline_impl(bytesio *self, Py_ssize_t size)
521+
/*[clinic end generated code: output=cf53cd21c22e0a4d input=c11ce93b188a03d9]*/
522+
{
523+
PyErr_Format(PyExc_NotImplementedError, "TODO");
524+
return NULL;
525+
}
526+
488527
/*[clinic input]
489528
_io.BytesIO.readlines
490529
size as arg: object = None
@@ -586,6 +625,25 @@ _io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
586625
return PyLong_FromSsize_t(len);
587626
}
588627

628+
/*[clinic input]
629+
_io.BytesIO.backreadinto
630+
buffer: Py_buffer(accept={rwbuffer})
631+
/
632+
633+
Read backwards bytes into buffer.
634+
635+
Returns number of bytes read (0 for BOF), or None if the object
636+
is set not to block and has no data to read.
637+
[clinic start generated code]*/
638+
639+
static PyObject *
640+
_io_BytesIO_backreadinto_impl(bytesio *self, Py_buffer *buffer)
641+
/*[clinic end generated code: output=42f2ca676ab55937 input=6ac72ceee21684f3]*/
642+
{
643+
PyErr_Format(PyExc_NotImplementedError, "TODO");
644+
return NULL;
645+
}
646+
589647
/*[clinic input]
590648
_io.BytesIO.truncate
591649
size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None
@@ -1016,9 +1074,12 @@ static struct PyMethodDef bytesio_methods[] = {
10161074
_IO_BYTESIO_WRITELINES_METHODDEF
10171075
_IO_BYTESIO_READ1_METHODDEF
10181076
_IO_BYTESIO_READINTO_METHODDEF
1077+
_IO_BYTESIO_BACKREADINTO_METHODDEF
10191078
_IO_BYTESIO_READLINE_METHODDEF
1079+
_IO_BYTESIO_BACKREADLINE_METHODDEF
10201080
_IO_BYTESIO_READLINES_METHODDEF
10211081
_IO_BYTESIO_READ_METHODDEF
1082+
_IO_BYTESIO_BACKREAD_METHODDEF
10221083
_IO_BYTESIO_GETBUFFER_METHODDEF
10231084
_IO_BYTESIO_GETVALUE_METHODDEF
10241085
_IO_BYTESIO_SEEK_METHODDEF

0 commit comments

Comments
 (0)