]> granicus.if.org Git - python/commitdiff
bpo-29730: replace some calls to PyNumber_Check and improve some error messages ...
authorOren Milman <orenmn@gmail.com>
Sun, 12 Mar 2017 22:37:05 +0000 (00:37 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 12 Mar 2017 22:37:05 +0000 (00:37 +0200)
Modules/_io/_iomodule.c
Modules/_io/bytesio.c
Modules/_io/stringio.c
Modules/mmapmodule.c
Objects/bytes_methods.c

index 8f0b72a55bd03c5ea2530be0a228f383b6371a27..5d804ece79f44c4dd1c2d510298d26ae5c9e4a3f 100644 (file)
@@ -549,14 +549,15 @@ _PyIO_ConvertSsize_t(PyObject *obj, void *result) {
     if (obj == Py_None) {
         limit = -1;
     }
-    else if (PyNumber_Check(obj)) {
+    else if (PyIndex_Check(obj)) {
         limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError);
-        if (limit == -1 && PyErr_Occurred())
+        if (limit == -1 && PyErr_Occurred()) {
             return 0;
+        }
     }
     else {
         PyErr_Format(PyExc_TypeError,
-                     "integer argument expected, got '%.200s'",
+                     "argument should be integer or None, not '%.200s'",
                      Py_TYPE(obj)->tp_name);
         return 0;
     }
index 0a0e5e72d7e4d92db226e5a0ad4210e00a51b17a..59b917d0bdaaa16469c3aa1c3cc77bfe9fdb911c 100644 (file)
@@ -578,12 +578,18 @@ _io_BytesIO_truncate_impl(bytesio *self, PyObject *arg)
         /* Truncate to current position if no argument is passed. */
         size = self->pos;
     }
-    else {
+    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,
index 788dcb198458963bac6cf84826a66b9e00a864b1..a73171fd8f602c899fc8bde89747a4260e63ce05 100644 (file)
@@ -458,17 +458,19 @@ _io_StringIO_truncate_impl(stringio *self, PyObject *arg)
     CHECK_INITIALIZED(self);
     CHECK_CLOSED(self);
 
-    if (PyNumber_Check(arg)) {
+    if (PyIndex_Check(arg)) {
         size = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
-        if (size == -1 && PyErr_Occurred())
+        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, "integer argument expected, got '%s'",
+        PyErr_Format(PyExc_TypeError,
+                     "argument should be integer or None, not '%.200s'",
                      Py_TYPE(arg)->tp_name);
         return NULL;
     }
index 7a94464e7b227d26ca29327f35d7ab2d734dc043..7c15d377cfdf4eeafb3a359b06de69ee503768ec 100644 (file)
@@ -247,14 +247,15 @@ mmap_convert_ssize_t(PyObject *obj, void *result) {
     if (obj == Py_None) {
         limit = -1;
     }
-    else if (PyNumber_Check(obj)) {
+    else if (PyIndex_Check(obj)) {
         limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError);
-        if (limit == -1 && PyErr_Occurred())
+        if (limit == -1 && PyErr_Occurred()) {
             return 0;
+        }
     }
     else {
         PyErr_Format(PyExc_TypeError,
-                     "integer argument expected, got '%.200s'",
+                     "argument should be integer or None, not '%.200s'",
                      Py_TYPE(obj)->tp_name);
         return 0;
     }
index d5c4fe6346fc53a984babb3b91870e2a7dbe2d68..85d9ceea52dd49b5c750dca1a3be27bfc8db9e66 100644 (file)
@@ -399,12 +399,15 @@ _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to)
 #include "stringlib/find.h"
 
 /*
-Wraps stringlib_parse_args_finds() and additionally checks whether the
-first argument is an integer in range(0, 256).
+Wraps stringlib_parse_args_finds() and additionally checks the first
+argument type.
 
-If this is the case, writes the integer value to the byte parameter
-and sets subobj to NULL. Otherwise, sets the first argument to subobj
-and doesn't touch byte. The other parameters are similar to those of
+In case the first argument is a bytes-like object, sets it to subobj,
+and doesn't touch the byte parameter.
+In case it is an integer in range(0, 256), writes the integer value
+to byte, and sets subobj to NULL.
+
+The other parameters are similar to those of
 stringlib_parse_args_finds().
 */
 
@@ -415,27 +418,28 @@ parse_args_finds_byte(const char *function_name, PyObject *args,
 {
     PyObject *tmp_subobj;
     Py_ssize_t ival;
-    PyObject *err;
 
     if(!stringlib_parse_args_finds(function_name, args, &tmp_subobj,
                                    start, end))
         return 0;
 
-    if (!PyNumber_Check(tmp_subobj)) {
+    if (PyObject_CheckBuffer(tmp_subobj)) {
         *subobj = tmp_subobj;
         return 1;
     }
 
-    ival = PyNumber_AsSsize_t(tmp_subobj, PyExc_OverflowError);
-    if (ival == -1) {
-        err = PyErr_Occurred();
-        if (err && !PyErr_GivenExceptionMatches(err, PyExc_OverflowError)) {
-            PyErr_Clear();
-            *subobj = tmp_subobj;
-            return 1;
-        }
+    if (!PyIndex_Check(tmp_subobj)) {
+        PyErr_Format(PyExc_TypeError,
+                     "argument should be integer or bytes-like object, "
+                     "not '%.200s'",
+                     Py_TYPE(tmp_subobj)->tp_name);
+        return 0;
     }
 
+    ival = PyNumber_AsSsize_t(tmp_subobj, NULL);
+    if (ival == -1 && PyErr_Occurred()) {
+        return 0;
+    }
     if (ival < 0 || ival > 255) {
         PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
         return 0;