]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-127190: Fix local_setattro() error handling (#127366)
authorVictor Stinner <vstinner@python.org>
Thu, 28 Nov 2024 16:35:48 +0000 (17:35 +0100)
committerGitHub <noreply@github.com>
Thu, 28 Nov 2024 16:35:48 +0000 (17:35 +0100)
Don't make the assumption that the 'name' argument is a string. Use
repr() to format the 'name' argument instead.

Lib/test/test_threading_local.py
Modules/_threadmodule.c

index f0b829a978feb5c16450448f3fa2a769c3260603..3a58afd8194a32735b38eea57d4a4b6cd1efd93c 100644 (file)
@@ -208,6 +208,21 @@ class BaseLocalTest:
 
         _testcapi.join_temporary_c_thread()
 
+    @support.cpython_only
+    def test_error(self):
+        class Loop(self._local):
+            attr = 1
+
+        # Trick the "if name == '__dict__':" test of __setattr__()
+        # to always be true
+        class NameCompareTrue:
+            def __eq__(self, other):
+                return True
+
+        loop = Loop()
+        with self.assertRaisesRegex(AttributeError, 'Loop.*read-only'):
+            loop.__setattr__(NameCompareTrue(), 2)
+
 
 class ThreadLocalTest(unittest.TestCase, BaseLocalTest):
     _local = _thread._local
index f2a420ac1c589d29805ae15395d9ead27e8b7667..4a45445e2f62db5b23886ef518373f33f7359e0d 100644 (file)
@@ -1624,7 +1624,7 @@ local_setattro(localobject *self, PyObject *name, PyObject *v)
     }
     if (r == 1) {
         PyErr_Format(PyExc_AttributeError,
-                     "'%.100s' object attribute '%U' is read-only",
+                     "'%.100s' object attribute %R is read-only",
                      Py_TYPE(self)->tp_name, name);
         goto err;
     }