From 762bf40438a572a398e500c74e38f9894ea20a45 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 30 Mar 2017 09:15:31 +0300 Subject: [PATCH] bpo-29852: Argument Clinic Py_ssize_t converter now supports None (#716) if pass `accept={int, NoneType}`. --- Include/abstract.h | 3 ++ Modules/_io/_iomodule.c | 24 ---------------- Modules/_io/_iomodule.h | 2 -- Modules/_io/bufferedio.c | 15 +++------- Modules/_io/bytesio.c | 44 ++++++----------------------- Modules/_io/clinic/bufferedio.c.h | 6 ++-- Modules/_io/clinic/bytesio.c.h | 19 ++++++------- Modules/_io/clinic/fileio.c.h | 4 +-- Modules/_io/clinic/iobase.c.h | 6 ++-- Modules/_io/clinic/stringio.c.h | 17 ++++++----- Modules/_io/clinic/textio.c.h | 4 +-- Modules/_io/clinic/winconsoleio.c.h | 4 +-- Modules/_io/fileio.c | 11 ++------ Modules/_io/iobase.c | 15 +++------- Modules/_io/stringio.c | 40 +++++--------------------- Modules/_io/textio.c | 11 ++------ Modules/_io/winconsoleio.c | 11 ++------ Modules/mmapmodule.c | 25 +--------------- Python/modsupport.c | 25 ++++++++++++++++ Tools/clinic/clinic.py | 12 ++++++-- 20 files changed, 98 insertions(+), 200 deletions(-) diff --git a/Include/abstract.h b/Include/abstract.h index cd963af4555..fe089dcbb56 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -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 */ diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 0b795c8f22a..bc2fb325976 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -541,30 +541,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) { diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index b5f0f5709ef..c589c389b2c 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -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. diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index b30d229bb6d..24e052bee2d 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -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); @@ -892,13 +885,13 @@ end: /*[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; @@ -1206,13 +1199,13 @@ end_unlocked: /*[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); diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index f78b4475d00..42c7f7933e0 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -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; @@ -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. @@ -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; @@ -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. @@ -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. @@ -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; @@ -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. @@ -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); diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index 4337ecfaa99..c910dcee372 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -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; } @@ -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; } @@ -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]*/ diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index 60b7eaadd02..559971c4a4b 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -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; } @@ -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; } @@ -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; } @@ -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; @@ -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]*/ diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h index 7a8e2c64c35..cd5075db124 100644 --- a/Modules/_io/clinic/fileio.c.h +++ b/Modules/_io/clinic/fileio.c.h @@ -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; } @@ -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]*/ diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h index 045bb3b6991..a6780c27a7f 100644 --- a/Modules/_io/clinic/iobase.c.h +++ b/Modules/_io/clinic/iobase.c.h @@ -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; } @@ -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; } @@ -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]*/ diff --git a/Modules/_io/clinic/stringio.c.h b/Modules/_io/clinic/stringio.c.h index 362d0b9d4cc..2710135e277 100644 --- a/Modules/_io/clinic/stringio.c.h +++ b/Modules/_io/clinic/stringio.c.h @@ -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; } @@ -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; } @@ -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; @@ -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]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index 46b3edafa92..4eab136f772 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -237,7 +237,7 @@ _io_TextIOWrapper_read(textio *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; } @@ -480,4 +480,4 @@ _io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) { return _io_TextIOWrapper_close_impl(self); } -/*[clinic end generated code: output=67eba50449900a96 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8e5c21c88c7c70bc input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/winconsoleio.c.h b/Modules/_io/clinic/winconsoleio.c.h index f568053d63a..f694cd8cc88 100644 --- a/Modules/_io/clinic/winconsoleio.c.h +++ b/Modules/_io/clinic/winconsoleio.c.h @@ -221,7 +221,7 @@ _io__WindowsConsoleIO_read(winconsoleio *self, PyObject **args, Py_ssize_t nargs 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; } @@ -332,4 +332,4 @@ _io__WindowsConsoleIO_isatty(winconsoleio *self, PyObject *Py_UNUSED(ignored)) #ifndef _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #endif /* !defined(_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF) */ -/*[clinic end generated code: output=04dab03363f5e304 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f2a240ec6af12a20 input=a9049054013a1b77]*/ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 60005083ff2..3c0b7529323 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -52,13 +52,6 @@ class _io.FileIO "fileio *" "&PyFileIO_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/ -/*[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 int fd; @@ -770,7 +763,7 @@ _io_FileIO_readall_impl(fileio *self) /*[clinic input] _io.FileIO.read - size: io_ssize_t = -1 + size: Py_ssize_t(accept={int, NoneType}) = -1 / Read at most size bytes, returned as bytes. @@ -782,7 +775,7 @@ Return an empty bytes object at EOF. static PyObject * _io_FileIO_read_impl(fileio *self, Py_ssize_t size) -/*[clinic end generated code: output=42528d39dd0ca641 input=5c6caa5490c13a9b]*/ +/*[clinic end generated code: output=42528d39dd0ca641 input=bec9a2c704ddcbc9]*/ { char *ptr; Py_ssize_t n; diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index b176457e0d9..75cfe59624b 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -20,13 +20,6 @@ class _io._RawIOBase "PyObject *" "&PyRawIOBase_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=d29a4d076c2b211c]*/ -/*[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]*/ - /* * IOBase class, an abstract class */ @@ -488,7 +481,7 @@ _io__IOBase_isatty_impl(PyObject *self) /*[clinic input] _io._IOBase.readline - size as limit: io_ssize_t = -1 + size as limit: Py_ssize_t(accept={int, NoneType}) = -1 / Read and return a line from the stream. @@ -502,7 +495,7 @@ terminator(s) recognized. static PyObject * _io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit) -/*[clinic end generated code: output=4479f79b58187840 input=df4cc8884f553cab]*/ +/*[clinic end generated code: output=4479f79b58187840 input=d0c596794e877bff]*/ { /* For backwards compatibility, a (slowish) readline(). */ @@ -635,7 +628,7 @@ iobase_iternext(PyObject *self) /*[clinic input] _io._IOBase.readlines - hint: io_ssize_t = -1 + hint: Py_ssize_t(accept={int, NoneType}) = -1 / Return a list of lines from the stream. @@ -647,7 +640,7 @@ lines so far exceeds hint. static PyObject * _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) -/*[clinic end generated code: output=2f50421677fa3dea input=1961c4a95e96e661]*/ +/*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/ { Py_ssize_t length = 0; PyObject *result; diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index ef450328fa3..2ec32acfcb8 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -17,13 +17,6 @@ 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; @@ -308,7 +301,7 @@ _io_StringIO_tell_impl(stringio *self) /*[clinic input] _io.StringIO.read - size: io_ssize_t = -1 + size: Py_ssize_t(accept={int, NoneType}) = -1 / Read at most size characters, returned as a string. @@ -319,7 +312,7 @@ is reached. Return an empty string at EOF. static PyObject * _io_StringIO_read_impl(stringio *self, Py_ssize_t size) -/*[clinic end generated code: output=ae8cf6002f71626c input=bbd84248eb4ab957]*/ +/*[clinic end generated code: output=ae8cf6002f71626c input=0921093383dfb92d]*/ { Py_ssize_t n; Py_UCS4 *output; @@ -380,7 +373,7 @@ _stringio_readline(stringio *self, Py_ssize_t limit) /*[clinic input] _io.StringIO.readline - size: io_ssize_t = -1 + size: Py_ssize_t(accept={int, NoneType}) = -1 / Read until newline or EOF. @@ -390,7 +383,7 @@ Returns an empty string if EOF is hit immediately. static PyObject * _io_StringIO_readline_impl(stringio *self, Py_ssize_t size) -/*[clinic end generated code: output=cabd6452f1b7e85d input=04de7535f732cb3d]*/ +/*[clinic end generated code: output=cabd6452f1b7e85d input=a5bd70bf682aa276]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); @@ -439,7 +432,7 @@ stringio_iternext(stringio *self) /*[clinic input] _io.StringIO.truncate - pos as arg: object = None + pos as size: Py_ssize_t(accept={int, NoneType}, c_default="self->pos") = None / Truncate size to pos. @@ -450,31 +443,12 @@ Returns the new absolute position. [clinic start generated code]*/ static PyObject * -_io_StringIO_truncate_impl(stringio *self, PyObject *arg) -/*[clinic end generated code: output=6072439c2b01d306 input=748619a494ba53ad]*/ +_io_StringIO_truncate_impl(stringio *self, Py_ssize_t size) +/*[clinic end generated code: output=eb3aef8e06701365 input=5505cff90ca48b96]*/ { - Py_ssize_t size; - CHECK_INITIALIZED(self); CHECK_CLOSED(self); - if (PyIndex_Check(arg)) { - size = PyNumber_AsSsize_t(arg, PyExc_OverflowError); - if (size == -1 && PyErr_Occurred()) { - return NULL; - } - } - else if (arg == Py_None) { - /* Truncate to current position if no argument is passed. */ - size = self->pos; - } - 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); diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 0211ad95860..5639ad8bfb4 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -18,13 +18,6 @@ class _io.TextIOWrapper "textio *" "&TextIOWrapper_TYpe" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=2097a4fc85670c26]*/ -/*[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(decode); @@ -1529,13 +1522,13 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) /*[clinic input] _io.TextIOWrapper.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_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) -/*[clinic end generated code: output=7e651ce6cc6a25a6 input=8c09398424085cca]*/ +/*[clinic end generated code: output=7e651ce6cc6a25a6 input=123eecbfe214aeb8]*/ { PyObject *result = NULL, *chunks = NULL; diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 4251c202414..814462f7c98 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -140,13 +140,6 @@ class _io._WindowsConsoleIO "winconsoleio *" "&PyWindowsConsoleIO_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=e897fdc1fba4e131]*/ -/*[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 HANDLE handle; @@ -906,7 +899,7 @@ _io__WindowsConsoleIO_readall_impl(winconsoleio *self) /*[clinic input] _io._WindowsConsoleIO.read - size: io_ssize_t = -1 + size: Py_ssize_t(accept={int, NoneType}) = -1 / Read at most size bytes, returned as bytes. @@ -918,7 +911,7 @@ Return an empty bytes object at EOF. static PyObject * _io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size) -/*[clinic end generated code: output=57df68af9f4b22d0 input=6c56fceec460f1dd]*/ +/*[clinic end generated code: output=57df68af9f4b22d0 input=8bc73bc15d0fa072]*/ { PyObject *bytes; Py_ssize_t bytes_size; diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 7c15d377cfd..56f44006704 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -240,29 +240,6 @@ mmap_read_line_method(mmap_object *self, return result; } -/* Basically the "n" format code with the ability to turn None into -1. */ -static int -mmap_convert_ssize_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; -} - static PyObject * mmap_read_method(mmap_object *self, PyObject *args) @@ -271,7 +248,7 @@ mmap_read_method(mmap_object *self, PyObject *result; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "|O&:read", mmap_convert_ssize_t, &num_bytes)) + if (!PyArg_ParseTuple(args, "|O&:read", _Py_convert_optional_to_ssize_t, &num_bytes)) return(NULL); /* silently 'adjust' out-of-range requests */ diff --git a/Python/modsupport.c b/Python/modsupport.c index 9637191feb8..8a77a7b06dc 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -12,6 +12,31 @@ static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_ /* Package context -- the full module name for package imports */ const char *_Py_PackageContext = NULL; + +int +_Py_convert_optional_to_ssize_t(PyObject *obj, void *result) +{ + Py_ssize_t limit; + if (obj == Py_None) { + return 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; +} + + /* Helper for mkvalue() to scan the length of a format */ static Py_ssize_t diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 53108b17eee..1d570f17c35 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -2650,12 +2650,20 @@ class unsigned_long_long_converter(CConverter): if not bitwise: fail("Unsigned long long must be bitwise (for now).") + class Py_ssize_t_converter(CConverter): type = 'Py_ssize_t' - default_type = int - format_unit = 'n' c_ignored_default = "0" + def converter_init(self, *, accept={int}): + if accept == {int}: + self.format_unit = 'n' + self.default_type = int + elif accept == {int, NoneType}: + self.converter = '_Py_convert_optional_to_ssize_t' + else: + fail("Py_ssize_t_converter: illegal 'accept' argument " + repr(accept)) + class slice_index_converter(CConverter): type = 'Py_ssize_t'