bpo-29730: replace some calls to PyNumber_Check and improve some error messages (#650)

diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c
index 8f0b72a..5d804ec 100644
--- a/Modules/_io/_iomodule.c
+++ b/Modules/_io/_iomodule.c
@@ -549,14 +549,15 @@
     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;
     }
diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c
index 0a0e5e7..59b917d 100644
--- a/Modules/_io/bytesio.c
+++ b/Modules/_io/bytesio.c
@@ -578,12 +578,18 @@
         /* 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,
diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c
index 788dcb1..a73171f 100644
--- a/Modules/_io/stringio.c
+++ b/Modules/_io/stringio.c
@@ -458,17 +458,19 @@
     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;
     }
diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c
index 7a94464..7c15d37 100644
--- a/Modules/mmapmodule.c
+++ b/Modules/mmapmodule.c
@@ -247,14 +247,15 @@
     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;
     }