Skip to content

bpo-29852: Argument Clinic Py_ssize_t converter now supports None #716

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Include/abstract.h
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,9 @@ PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
const Py_ssize_t *shape);
PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index,
const Py_ssize_t *shape);

/* Convert Python int to Py_ssize_t. Do nothing if the argument is None. */
PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *);
#endif /* !Py_LIMITED_API */


Expand Down
24 changes: 0 additions & 24 deletions Modules/_io/_iomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,30 +542,6 @@ PyNumber_AsOff_t(PyObject *item, PyObject *err)
}


/* Basically the "n" format code with the ability to turn None into -1. */
int
_PyIO_ConvertSsize_t(PyObject *obj, void *result) {
Py_ssize_t limit;
if (obj == Py_None) {
limit = -1;
}
else if (PyIndex_Check(obj)) {
limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError);
if (limit == -1 && PyErr_Occurred()) {
return 0;
}
}
else {
PyErr_Format(PyExc_TypeError,
"argument should be integer or None, not '%.200s'",
Py_TYPE(obj)->tp_name);
return 0;
}
*((Py_ssize_t *)result) = limit;
return 1;
}


_PyIO_State *
_PyIO_get_module_state(void)
{
Expand Down
2 changes: 0 additions & 2 deletions Modules/_io/_iomodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ PyAPI_DATA(PyObject *) _PyWindowsConsoleIO_Type;
#endif /* MS_WINDOWS */
#endif /* Py_LIMITED_API */

extern int _PyIO_ConvertSsize_t(PyObject *, void *);

/* These functions are used as METH_NOARGS methods, are normally called
* with args=NULL, and return a new reference.
* BUT when args=Py_True is passed, they return a borrowed reference.
Expand Down
15 changes: 4 additions & 11 deletions Modules/_io/bufferedio.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,6 @@ class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/

/*[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]*/

_Py_IDENTIFIER(close);
_Py_IDENTIFIER(_dealloc_warn);
_Py_IDENTIFIER(flush);
Expand Down Expand Up @@ -892,13 +885,13 @@ _io__Buffered_peek_impl(buffered *self, Py_ssize_t size)

/*[clinic input]
_io._Buffered.read
size as n: io_ssize_t = -1
size as n: Py_ssize_t(accept={int, NoneType}) = -1
/
[clinic start generated code]*/

static PyObject *
_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
/*[clinic end generated code: output=f41c78bb15b9bbe9 input=c0939ec7f9e9354f]*/
/*[clinic end generated code: output=f41c78bb15b9bbe9 input=7df81e82e08a68a2]*/
{
PyObject *res;

Expand Down Expand Up @@ -1206,13 +1199,13 @@ _buffered_readline(buffered *self, Py_ssize_t limit)

/*[clinic input]
_io._Buffered.readline
size: io_ssize_t = -1
size: Py_ssize_t(accept={int, NoneType}) = -1
/
[clinic start generated code]*/

static PyObject *
_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
/*[clinic end generated code: output=24dd2aa6e33be83c input=ff1e0df821cb4e5c]*/
/*[clinic end generated code: output=24dd2aa6e33be83c input=673b6240e315ef8a]*/
{
CHECK_INITIALIZED(self)
return _buffered_readline(self, size);
Expand Down
44 changes: 9 additions & 35 deletions Modules/_io/bytesio.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ 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;
Expand Down Expand Up @@ -381,7 +374,7 @@ read_bytes(bytesio *self, Py_ssize_t size)

/*[clinic input]
_io.BytesIO.read
size: io_ssize_t = -1
size: Py_ssize_t(accept={int, NoneType}) = -1
/

Read at most size bytes, returned as a bytes object.
Expand All @@ -392,7 +385,7 @@ Return an empty bytes object at EOF.

static PyObject *
_io_BytesIO_read_impl(bytesio *self, Py_ssize_t size)
/*[clinic end generated code: output=9cc025f21c75bdd2 input=c81ec53b8f2cc3cf]*/
/*[clinic end generated code: output=9cc025f21c75bdd2 input=74344a39f431c3d7]*/
{
Py_ssize_t n;

Expand All @@ -412,7 +405,7 @@ _io_BytesIO_read_impl(bytesio *self, Py_ssize_t size)

/*[clinic input]
_io.BytesIO.read1
size: io_ssize_t = -1
size: Py_ssize_t(accept={int, NoneType}) = -1
/

Read at most size bytes, returned as a bytes object.
Expand All @@ -423,14 +416,14 @@ Return an empty bytes object at EOF.

static PyObject *
_io_BytesIO_read1_impl(bytesio *self, Py_ssize_t size)
/*[clinic end generated code: output=d0f843285aa95f1c input=67cf18b142111664]*/
/*[clinic end generated code: output=d0f843285aa95f1c input=440a395bf9129ef5]*/
{
return _io_BytesIO_read_impl(self, size);
}

/*[clinic input]
_io.BytesIO.readline
size: io_ssize_t = -1
size: Py_ssize_t(accept={int, NoneType}) = -1
/

Next line from the file, as a bytes object.
Expand All @@ -442,7 +435,7 @@ Return an empty bytes object at EOF.

static PyObject *
_io_BytesIO_readline_impl(bytesio *self, Py_ssize_t size)
/*[clinic end generated code: output=4bff3c251df8ffcd input=7c95bd3f9e9d1646]*/
/*[clinic end generated code: output=4bff3c251df8ffcd input=e7c3fbd1744e2783]*/
{
Py_ssize_t n;

Expand Down Expand Up @@ -556,7 +549,7 @@ _io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)

/*[clinic input]
_io.BytesIO.truncate
size as arg: object = None
size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None
/

Truncate the file to at most size bytes.
Expand All @@ -566,31 +559,12 @@ The current file position is unchanged. Returns the new size.
[clinic start generated code]*/

static PyObject *
_io_BytesIO_truncate_impl(bytesio *self, PyObject *arg)
/*[clinic end generated code: output=81e6be60e67ddd66 input=11ed1966835462ba]*/
_io_BytesIO_truncate_impl(bytesio *self, Py_ssize_t size)
/*[clinic end generated code: output=9ad17650c15fa09b input=423759dd42d2f7c1]*/
{
Py_ssize_t size;

CHECK_CLOSED(self);
CHECK_EXPORTS(self);

if (arg == Py_None) {
/* Truncate to current position if no argument is passed. */
size = self->pos;
}
else if (PyIndex_Check(arg)) {
size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
if (size == -1 && PyErr_Occurred()) {
return NULL;
}
}
else {
PyErr_Format(PyExc_TypeError,
"argument should be integer or None, not '%.200s'",
Py_TYPE(arg)->tp_name);
return NULL;
}

if (size < 0) {
PyErr_Format(PyExc_ValueError,
"negative size value %zd", size);
Expand Down
6 changes: 3 additions & 3 deletions Modules/_io/clinic/bufferedio.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ _io__Buffered_read(buffered *self, PyObject **args, Py_ssize_t nargs, PyObject *
Py_ssize_t n = -1;

if (!_PyArg_ParseStack(args, nargs, "|O&:read",
_PyIO_ConvertSsize_t, &n)) {
_Py_convert_optional_to_ssize_t, &n)) {
goto exit;
}

Expand Down Expand Up @@ -258,7 +258,7 @@ _io__Buffered_readline(buffered *self, PyObject **args, Py_ssize_t nargs, PyObje
Py_ssize_t size = -1;

if (!_PyArg_ParseStack(args, nargs, "|O&:readline",
_PyIO_ConvertSsize_t, &size)) {
_Py_convert_optional_to_ssize_t, &size)) {
goto exit;
}

Expand Down Expand Up @@ -500,4 +500,4 @@ _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs)
exit:
return return_value;
}
/*[clinic end generated code: output=e37b969b1acaa09c input=a9049054013a1b77]*/
/*[clinic end generated code: output=3cf3262c9b157dc1 input=a9049054013a1b77]*/
19 changes: 9 additions & 10 deletions Modules/_io/clinic/bytesio.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ _io_BytesIO_read(bytesio *self, PyObject **args, Py_ssize_t nargs, PyObject *kwn
Py_ssize_t size = -1;

if (!_PyArg_ParseStack(args, nargs, "|O&:read",
_PyIO_ConvertSsize_t, &size)) {
_Py_convert_optional_to_ssize_t, &size)) {
goto exit;
}

Expand Down Expand Up @@ -205,7 +205,7 @@ _io_BytesIO_read1(bytesio *self, PyObject **args, Py_ssize_t nargs, PyObject *kw
Py_ssize_t size = -1;

if (!_PyArg_ParseStack(args, nargs, "|O&:read1",
_PyIO_ConvertSsize_t, &size)) {
_Py_convert_optional_to_ssize_t, &size)) {
goto exit;
}

Expand Down Expand Up @@ -241,7 +241,7 @@ _io_BytesIO_readline(bytesio *self, PyObject **args, Py_ssize_t nargs, PyObject
Py_ssize_t size = -1;

if (!_PyArg_ParseStack(args, nargs, "|O&:readline",
_PyIO_ConvertSsize_t, &size)) {
_Py_convert_optional_to_ssize_t, &size)) {
goto exit;
}

Expand Down Expand Up @@ -339,24 +339,23 @@ PyDoc_STRVAR(_io_BytesIO_truncate__doc__,
{"truncate", (PyCFunction)_io_BytesIO_truncate, METH_FASTCALL, _io_BytesIO_truncate__doc__},

static PyObject *
_io_BytesIO_truncate_impl(bytesio *self, PyObject *arg);
_io_BytesIO_truncate_impl(bytesio *self, Py_ssize_t size);

static PyObject *
_io_BytesIO_truncate(bytesio *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
PyObject *arg = Py_None;
Py_ssize_t size = self->pos;

if (!_PyArg_UnpackStack(args, nargs, "truncate",
0, 1,
&arg)) {
if (!_PyArg_ParseStack(args, nargs, "|O&:truncate",
_Py_convert_optional_to_ssize_t, &size)) {
goto exit;
}

if (!_PyArg_NoStackKeywords("truncate", kwnames)) {
goto exit;
}
return_value = _io_BytesIO_truncate_impl(self, arg);
return_value = _io_BytesIO_truncate_impl(self, size);

exit:
return return_value;
Expand Down Expand Up @@ -469,4 +468,4 @@ _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs)
exit:
return return_value;
}
/*[clinic end generated code: output=74a856733a5d55b0 input=a9049054013a1b77]*/
/*[clinic end generated code: output=733795434f838b71 input=a9049054013a1b77]*/
4 changes: 2 additions & 2 deletions Modules/_io/clinic/fileio.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ _io_FileIO_read(fileio *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnam
Py_ssize_t size = -1;

if (!_PyArg_ParseStack(args, nargs, "|O&:read",
_PyIO_ConvertSsize_t, &size)) {
_Py_convert_optional_to_ssize_t, &size)) {
goto exit;
}

Expand Down Expand Up @@ -385,4 +385,4 @@ _io_FileIO_isatty(fileio *self, PyObject *Py_UNUSED(ignored))
#ifndef _IO_FILEIO_TRUNCATE_METHODDEF
#define _IO_FILEIO_TRUNCATE_METHODDEF
#endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */
/*[clinic end generated code: output=034d782a0daa82bd input=a9049054013a1b77]*/
/*[clinic end generated code: output=a4044e2d878248d0 input=a9049054013a1b77]*/
6 changes: 3 additions & 3 deletions Modules/_io/clinic/iobase.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ _io__IOBase_readline(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject
Py_ssize_t limit = -1;

if (!_PyArg_ParseStack(args, nargs, "|O&:readline",
_PyIO_ConvertSsize_t, &limit)) {
_Py_convert_optional_to_ssize_t, &limit)) {
goto exit;
}

Expand Down Expand Up @@ -222,7 +222,7 @@ _io__IOBase_readlines(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObjec
Py_ssize_t hint = -1;

if (!_PyArg_ParseStack(args, nargs, "|O&:readlines",
_PyIO_ConvertSsize_t, &hint)) {
_Py_convert_optional_to_ssize_t, &hint)) {
goto exit;
}

Expand Down Expand Up @@ -291,4 +291,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored))
{
return _io__RawIOBase_readall_impl(self);
}
/*[clinic end generated code: output=1bcece367fc7b0cd input=a9049054013a1b77]*/
/*[clinic end generated code: output=d3f59c135231baae input=a9049054013a1b77]*/
17 changes: 8 additions & 9 deletions Modules/_io/clinic/stringio.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ _io_StringIO_read(stringio *self, PyObject **args, Py_ssize_t nargs, PyObject *k
Py_ssize_t size = -1;

if (!_PyArg_ParseStack(args, nargs, "|O&:read",
_PyIO_ConvertSsize_t, &size)) {
_Py_convert_optional_to_ssize_t, &size)) {
goto exit;
}

Expand Down Expand Up @@ -94,7 +94,7 @@ _io_StringIO_readline(stringio *self, PyObject **args, Py_ssize_t nargs, PyObjec
Py_ssize_t size = -1;

if (!_PyArg_ParseStack(args, nargs, "|O&:readline",
_PyIO_ConvertSsize_t, &size)) {
_Py_convert_optional_to_ssize_t, &size)) {
goto exit;
}

Expand All @@ -121,24 +121,23 @@ PyDoc_STRVAR(_io_StringIO_truncate__doc__,
{"truncate", (PyCFunction)_io_StringIO_truncate, METH_FASTCALL, _io_StringIO_truncate__doc__},

static PyObject *
_io_StringIO_truncate_impl(stringio *self, PyObject *arg);
_io_StringIO_truncate_impl(stringio *self, Py_ssize_t size);

static PyObject *
_io_StringIO_truncate(stringio *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
PyObject *arg = Py_None;
Py_ssize_t size = self->pos;

if (!_PyArg_UnpackStack(args, nargs, "truncate",
0, 1,
&arg)) {
if (!_PyArg_ParseStack(args, nargs, "|O&:truncate",
_Py_convert_optional_to_ssize_t, &size)) {
goto exit;
}

if (!_PyArg_NoStackKeywords("truncate", kwnames)) {
goto exit;
}
return_value = _io_StringIO_truncate_impl(self, arg);
return_value = _io_StringIO_truncate_impl(self, size);

exit:
return return_value;
Expand Down Expand Up @@ -303,4 +302,4 @@ _io_StringIO_seekable(stringio *self, PyObject *Py_UNUSED(ignored))
{
return _io_StringIO_seekable_impl(self);
}
/*[clinic end generated code: output=965fe9cb0d11511a input=a9049054013a1b77]*/
/*[clinic end generated code: output=03429d95ed7cd92f input=a9049054013a1b77]*/
Loading