]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-44110: Improve string's __getitem__ error message (GH-26042)
authorMiguel Brito <5544985+miguendes@users.noreply.github.com>
Sun, 27 Jun 2021 12:04:57 +0000 (13:04 +0100)
committerGitHub <noreply@github.com>
Sun, 27 Jun 2021 12:04:57 +0000 (15:04 +0300)
Lib/test/string_tests.py
Lib/test/test_userstring.py
Misc/NEWS.d/next/Core and Builtins/2021-05-11-21-52-44.bpo-44110.VqbAsB.rst [new file with mode: 0644]
Objects/unicodeobject.c

index 840d7bb7550f71b7ac3db4f3c78583a8da8815c5..089701c983a1467340fd6ff2f13d044e9f4edb18 100644 (file)
@@ -80,12 +80,14 @@ class BaseTest:
                 self.assertIsNot(obj, realresult)
 
     # check that obj.method(*args) raises exc
-    def checkraises(self, exc, obj, methodname, *args):
+    def checkraises(self, exc, obj, methodname, *args, expected_msg=None):
         obj = self.fixtype(obj)
         args = self.fixtype(args)
         with self.assertRaises(exc) as cm:
             getattr(obj, methodname)(*args)
         self.assertNotEqual(str(cm.exception), '')
+        if expected_msg is not None:
+            self.assertEqual(str(cm.exception), expected_msg)
 
     # call obj.method(*args) without any checks
     def checkcall(self, obj, methodname, *args):
@@ -1195,6 +1197,10 @@ class MixinStrUnicodeUserStringTest:
 
         self.checkraises(TypeError, 'abc', '__getitem__', 'def')
 
+        for idx_type in ('def', object()):
+            expected_msg = "string indices must be integers, not '{}'".format(type(idx_type).__name__)
+            self.checkraises(TypeError, 'abc', '__getitem__', idx_type, expected_msg=expected_msg)
+
     def test_slice(self):
         self.checkequal('abc', 'abc', '__getitem__', slice(0, 1000))
         self.checkequal('abc', 'abc', '__getitem__', slice(0, 3))
index 4d1d8b6b6fe2d951d2899e9931ab95b42051d4ca..51b4f6041e49bfdf5ab24ff8d244cedfb63ca53b 100644 (file)
@@ -27,12 +27,14 @@ class UserStringTest(
             realresult
         )
 
-    def checkraises(self, exc, obj, methodname, *args):
+    def checkraises(self, exc, obj, methodname, *args, expected_msg=None):
         obj = self.fixtype(obj)
         # we don't fix the arguments, because UserString can't cope with it
         with self.assertRaises(exc) as cm:
             getattr(obj, methodname)(*args)
         self.assertNotEqual(str(cm.exception), '')
+        if expected_msg is not None:
+            self.assertEqual(str(cm.exception), expected_msg)
 
     def checkcall(self, object, methodname, *args):
         object = self.fixtype(object)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-05-11-21-52-44.bpo-44110.VqbAsB.rst b/Misc/NEWS.d/next/Core and Builtins/2021-05-11-21-52-44.bpo-44110.VqbAsB.rst
new file mode 100644 (file)
index 0000000..3b82e42
--- /dev/null
@@ -0,0 +1 @@
+Improve :func:`str.__getitem__` error message
index c316cafdc7ffc5303504e6c42c369f8b94293145..3e6b70bf4b6f5498fd28926b0cc9dd1ac026b47a 100644 (file)
@@ -14279,7 +14279,8 @@ unicode_subscript(PyObject* self, PyObject* item)
         assert(_PyUnicode_CheckConsistency(result, 1));
         return result;
     } else {
-        PyErr_SetString(PyExc_TypeError, "string indices must be integers");
+        PyErr_Format(PyExc_TypeError, "string indices must be integers, not '%.200s'",
+                     Py_TYPE(item)->tp_name);
         return NULL;
     }
 }