bpo-29741: Clean up C implementations of BytesIO and StringIO. (#606)
Some BytesIO methods now accept not just int subclasses but other int-like types.
This commit is contained in:
parent
7e52c3e7ae
commit
740025478d
|
@ -8,6 +8,13 @@ class _io.BytesIO "bytesio *" "&PyBytesIO_Type"
|
|||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7f50ec034f5c0b26]*/
|
||||
|
||||
/*[python input]
|
||||
class io_ssize_t_converter(CConverter):
|
||||
type = 'Py_ssize_t'
|
||||
converter = '_PyIO_ConvertSsize_t'
|
||||
[python start generated code]*/
|
||||
/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *buf;
|
||||
|
@ -374,7 +381,7 @@ read_bytes(bytesio *self, Py_ssize_t size)
|
|||
|
||||
/*[clinic input]
|
||||
_io.BytesIO.read
|
||||
size as arg: object = None
|
||||
size: io_ssize_t = -1
|
||||
/
|
||||
|
||||
Read at most size bytes, returned as a bytes object.
|
||||
|
@ -384,28 +391,13 @@ Return an empty bytes object at EOF.
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_io_BytesIO_read_impl(bytesio *self, PyObject *arg)
|
||||
/*[clinic end generated code: output=85dacb535c1e1781 input=cc7ba4a797bb1555]*/
|
||||
_io_BytesIO_read_impl(bytesio *self, Py_ssize_t size)
|
||||
/*[clinic end generated code: output=9cc025f21c75bdd2 input=c81ec53b8f2cc3cf]*/
|
||||
{
|
||||
Py_ssize_t size, n;
|
||||
Py_ssize_t n;
|
||||
|
||||
CHECK_CLOSED(self);
|
||||
|
||||
if (PyLong_Check(arg)) {
|
||||
size = PyLong_AsSsize_t(arg);
|
||||
if (size == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
}
|
||||
else if (arg == Py_None) {
|
||||
/* Read until EOF is reached, by default. */
|
||||
size = -1;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
|
||||
Py_TYPE(arg)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* adjust invalid sizes */
|
||||
n = self->string_size - self->pos;
|
||||
if (size < 0 || size > n) {
|
||||
|
@ -420,7 +412,7 @@ _io_BytesIO_read_impl(bytesio *self, PyObject *arg)
|
|||
|
||||
/*[clinic input]
|
||||
_io.BytesIO.read1
|
||||
size: object(c_default="Py_None") = -1
|
||||
size: io_ssize_t = -1
|
||||
/
|
||||
|
||||
Read at most size bytes, returned as a bytes object.
|
||||
|
@ -430,15 +422,15 @@ Return an empty bytes object at EOF.
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_io_BytesIO_read1_impl(bytesio *self, PyObject *size)
|
||||
/*[clinic end generated code: output=a60d80c84c81a6b8 input=0951874bafee8e80]*/
|
||||
_io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size)
|
||||
/*[clinic end generated code: output=d0f843285aa95f1c input=67cf18b142111664]*/
|
||||
{
|
||||
return _io_BytesIO_read_impl(self, size);
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
_io.BytesIO.readline
|
||||
size as arg: object = None
|
||||
size: io_ssize_t = -1
|
||||
/
|
||||
|
||||
Next line from the file, as a bytes object.
|
||||
|
@ -449,28 +441,13 @@ Return an empty bytes object at EOF.
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_io_BytesIO_readline_impl(bytesio *self, PyObject *arg)
|
||||
/*[clinic end generated code: output=1c2115534a4f9276 input=ca31f06de6eab257]*/
|
||||
_io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size)
|
||||
/*[clinic end generated code: output=4bff3c251df8ffcd input=7c95bd3f9e9d1646]*/
|
||||
{
|
||||
Py_ssize_t size, n;
|
||||
Py_ssize_t n;
|
||||
|
||||
CHECK_CLOSED(self);
|
||||
|
||||
if (PyLong_Check(arg)) {
|
||||
size = PyLong_AsSsize_t(arg);
|
||||
if (size == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
}
|
||||
else if (arg == Py_None) {
|
||||
/* No size limit, by default. */
|
||||
size = -1;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
|
||||
Py_TYPE(arg)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n = scan_eol(self, size);
|
||||
|
||||
return read_bytes(self, n);
|
||||
|
@ -597,19 +574,15 @@ _io_BytesIO_truncate_impl(bytesio *self, PyObject *arg)
|
|||
CHECK_CLOSED(self);
|
||||
CHECK_EXPORTS(self);
|
||||
|
||||
if (PyLong_Check(arg)) {
|
||||
size = PyLong_AsSsize_t(arg);
|
||||
if (size == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
}
|
||||
else if (arg == Py_None) {
|
||||
if (arg == Py_None) {
|
||||
/* Truncate to current position if no argument is passed. */
|
||||
size = self->pos;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
|
||||
Py_TYPE(arg)->tp_name);
|
||||
return NULL;
|
||||
size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
|
||||
if (size == -1 && PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (size < 0) {
|
||||
|
|
|
@ -149,7 +149,7 @@ _io_BytesIO_tell(bytesio *self, PyObject *Py_UNUSED(ignored))
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(_io_BytesIO_read__doc__,
|
||||
"read($self, size=None, /)\n"
|
||||
"read($self, size=-1, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Read at most size bytes, returned as a bytes object.\n"
|
||||
|
@ -161,24 +161,23 @@ PyDoc_STRVAR(_io_BytesIO_read__doc__,
|
|||
{"read", (PyCFunction)_io_BytesIO_read, METH_FASTCALL, _io_BytesIO_read__doc__},
|
||||
|
||||
static PyObject *
|
||||
_io_BytesIO_read_impl(bytesio *self, PyObject *arg);
|
||||
_io_BytesIO_read_impl(bytesio *self, Py_ssize_t size);
|
||||
|
||||
static PyObject *
|
||||
_io_BytesIO_read(bytesio *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyObject *arg = Py_None;
|
||||
Py_ssize_t size = -1;
|
||||
|
||||
if (!_PyArg_UnpackStack(args, nargs, "read",
|
||||
0, 1,
|
||||
&arg)) {
|
||||
if (!_PyArg_ParseStack(args, nargs, "|O&:read",
|
||||
_PyIO_ConvertSsize_t, &size)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!_PyArg_NoStackKeywords("read", kwnames)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = _io_BytesIO_read_impl(self, arg);
|
||||
return_value = _io_BytesIO_read_impl(self, size);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
|
@ -197,17 +196,16 @@ PyDoc_STRVAR(_io_BytesIO_read1__doc__,
|
|||
{"read1", (PyCFunction)_io_BytesIO_read1, METH_FASTCALL, _io_BytesIO_read1__doc__},
|
||||
|
||||
static PyObject *
|
||||
_io_BytesIO_read1_impl(bytesio *self, PyObject *size);
|
||||
_io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size);
|
||||
|
||||
static PyObject *
|
||||
_io_BytesIO_read1(bytesio *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyObject *size = Py_None;
|
||||
Py_ssize_t size = -1;
|
||||
|
||||
if (!_PyArg_UnpackStack(args, nargs, "read1",
|
||||
0, 1,
|
||||
&size)) {
|
||||
if (!_PyArg_ParseStack(args, nargs, "|O&:read1",
|
||||
_PyIO_ConvertSsize_t, &size)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
@ -221,7 +219,7 @@ exit:
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(_io_BytesIO_readline__doc__,
|
||||
"readline($self, size=None, /)\n"
|
||||
"readline($self, size=-1, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Next line from the file, as a bytes object.\n"
|
||||
|
@ -234,24 +232,23 @@ PyDoc_STRVAR(_io_BytesIO_readline__doc__,
|
|||
{"readline", (PyCFunction)_io_BytesIO_readline, METH_FASTCALL, _io_BytesIO_readline__doc__},
|
||||
|
||||
static PyObject *
|
||||
_io_BytesIO_readline_impl(bytesio *self, PyObject *arg);
|
||||
_io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size);
|
||||
|
||||
static PyObject *
|
||||
_io_BytesIO_readline(bytesio *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyObject *arg = Py_None;
|
||||
Py_ssize_t size = -1;
|
||||
|
||||
if (!_PyArg_UnpackStack(args, nargs, "readline",
|
||||
0, 1,
|
||||
&arg)) {
|
||||
if (!_PyArg_ParseStack(args, nargs, "|O&:readline",
|
||||
_PyIO_ConvertSsize_t, &size)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!_PyArg_NoStackKeywords("readline", kwnames)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = _io_BytesIO_readline_impl(self, arg);
|
||||
return_value = _io_BytesIO_readline_impl(self, size);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
|
@ -472,4 +469,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=138ee6ad6951bc84 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=74a856733a5d55b0 input=a9049054013a1b77]*/
|
||||
|
|
|
@ -39,7 +39,7 @@ _io_StringIO_tell(stringio *self, PyObject *Py_UNUSED(ignored))
|
|||
}
|
||||
|
||||
PyDoc_STRVAR(_io_StringIO_read__doc__,
|
||||
"read($self, size=None, /)\n"
|
||||
"read($self, size=-1, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Read at most size characters, returned as a string.\n"
|
||||
|
@ -51,31 +51,30 @@ PyDoc_STRVAR(_io_StringIO_read__doc__,
|
|||
{"read", (PyCFunction)_io_StringIO_read, METH_FASTCALL, _io_StringIO_read__doc__},
|
||||
|
||||
static PyObject *
|
||||
_io_StringIO_read_impl(stringio *self, PyObject *arg);
|
||||
_io_StringIO_read_impl(stringio *self, Py_ssize_t size);
|
||||
|
||||
static PyObject *
|
||||
_io_StringIO_read(stringio *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyObject *arg = Py_None;
|
||||
Py_ssize_t size = -1;
|
||||
|
||||
if (!_PyArg_UnpackStack(args, nargs, "read",
|
||||
0, 1,
|
||||
&arg)) {
|
||||
if (!_PyArg_ParseStack(args, nargs, "|O&:read",
|
||||
_PyIO_ConvertSsize_t, &size)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!_PyArg_NoStackKeywords("read", kwnames)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = _io_StringIO_read_impl(self, arg);
|
||||
return_value = _io_StringIO_read_impl(self, size);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(_io_StringIO_readline__doc__,
|
||||
"readline($self, size=None, /)\n"
|
||||
"readline($self, size=-1, /)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Read until newline or EOF.\n"
|
||||
|
@ -86,24 +85,23 @@ PyDoc_STRVAR(_io_StringIO_readline__doc__,
|
|||
{"readline", (PyCFunction)_io_StringIO_readline, METH_FASTCALL, _io_StringIO_readline__doc__},
|
||||
|
||||
static PyObject *
|
||||
_io_StringIO_readline_impl(stringio *self, PyObject *arg);
|
||||
_io_StringIO_readline_impl(stringio *self, Py_ssize_t size);
|
||||
|
||||
static PyObject *
|
||||
_io_StringIO_readline(stringio *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
PyObject *arg = Py_None;
|
||||
Py_ssize_t size = -1;
|
||||
|
||||
if (!_PyArg_UnpackStack(args, nargs, "readline",
|
||||
0, 1,
|
||||
&arg)) {
|
||||
if (!_PyArg_ParseStack(args, nargs, "|O&:readline",
|
||||
_PyIO_ConvertSsize_t, &size)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!_PyArg_NoStackKeywords("readline", kwnames)) {
|
||||
goto exit;
|
||||
}
|
||||
return_value = _io_StringIO_readline_impl(self, arg);
|
||||
return_value = _io_StringIO_readline_impl(self, size);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
|
@ -305,4 +303,4 @@ _io_StringIO_seekable(stringio *self, PyObject *Py_UNUSED(ignored))
|
|||
{
|
||||
return _io_StringIO_seekable_impl(self);
|
||||
}
|
||||
/*[clinic end generated code: output=ce8018ec29def422 input=a9049054013a1b77]*/
|
||||
/*[clinic end generated code: output=965fe9cb0d11511a input=a9049054013a1b77]*/
|
||||
|
|
|
@ -17,6 +17,13 @@ class _io.StringIO "stringio *" "&PyStringIO_Type"
|
|||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c17bc0f42165cd7d]*/
|
||||
|
||||
/*[python input]
|
||||
class io_ssize_t_converter(CConverter):
|
||||
type = 'Py_ssize_t'
|
||||
converter = '_PyIO_ConvertSsize_t'
|
||||
[python start generated code]*/
|
||||
/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
Py_UCS4 *buf;
|
||||
|
@ -301,7 +308,7 @@ _io_StringIO_tell_impl(stringio *self)
|
|||
|
||||
/*[clinic input]
|
||||
_io.StringIO.read
|
||||
size as arg: object = None
|
||||
size: io_ssize_t = -1
|
||||
/
|
||||
|
||||
Read at most size characters, returned as a string.
|
||||
|
@ -311,30 +318,15 @@ is reached. Return an empty string at EOF.
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_io_StringIO_read_impl(stringio *self, PyObject *arg)
|
||||
/*[clinic end generated code: output=3676864773746f68 input=9a319015f6f3965c]*/
|
||||
_io_StringIO_read_impl(stringio *self, Py_ssize_t size)
|
||||
/*[clinic end generated code: output=ae8cf6002f71626c input=bbd84248eb4ab957]*/
|
||||
{
|
||||
Py_ssize_t size, n;
|
||||
Py_ssize_t n;
|
||||
Py_UCS4 *output;
|
||||
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_CLOSED(self);
|
||||
|
||||
if (PyNumber_Check(arg)) {
|
||||
size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
|
||||
if (size == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
}
|
||||
else if (arg == Py_None) {
|
||||
/* Read until EOF is reached, by default. */
|
||||
size = -1;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
|
||||
Py_TYPE(arg)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* adjust invalid sizes */
|
||||
n = self->string_size - self->pos;
|
||||
if (size < 0 || size > n) {
|
||||
|
@ -388,7 +380,7 @@ _stringio_readline(stringio *self, Py_ssize_t limit)
|
|||
|
||||
/*[clinic input]
|
||||
_io.StringIO.readline
|
||||
size as arg: object = None
|
||||
size: io_ssize_t = -1
|
||||
/
|
||||
|
||||
Read until newline or EOF.
|
||||
|
@ -397,26 +389,14 @@ Returns an empty string if EOF is hit immediately.
|
|||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
_io_StringIO_readline_impl(stringio *self, PyObject *arg)
|
||||
/*[clinic end generated code: output=99fdcac03a3dee81 input=e0e0ed4042040176]*/
|
||||
_io_StringIO_readline_impl(stringio *self, Py_ssize_t size)
|
||||
/*[clinic end generated code: output=cabd6452f1b7e85d input=04de7535f732cb3d]*/
|
||||
{
|
||||
Py_ssize_t limit = -1;
|
||||
|
||||
CHECK_INITIALIZED(self);
|
||||
CHECK_CLOSED(self);
|
||||
ENSURE_REALIZED(self);
|
||||
|
||||
if (PyNumber_Check(arg)) {
|
||||
limit = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
|
||||
if (limit == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
}
|
||||
else if (arg != Py_None) {
|
||||
PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
|
||||
Py_TYPE(arg)->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
return _stringio_readline(self, limit);
|
||||
return _stringio_readline(self, size);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
|
Loading…
Reference in New Issue