https://github.com/python/cpython/commit/ced49a196f0e1ea06ba892b875f18e7b11ed26b7
commit: ced49a196f0e1ea06ba892b875f18e7b11ed26b7
branch: 3.14
author: Miss Islington (bot) <[email protected]>
committer: vstinner <[email protected]>
date: 2025-05-22T14:14:53Z
summary:

[3.14] gh-134323: Fix the new `threading.RLock.locked` method (GH-134368) 
(#134510)

gh-134323: Fix the new `threading.RLock.locked` method (GH-134368)
(cherry picked from commit 3effede97cc13fc0c5ab5dcde26cc319f388e84c)

Co-authored-by: Duprat <[email protected]>
Co-authored-by: Kumar Aditya <[email protected]>

files:
A Misc/NEWS.d/next/Library/2025-05-20-19-16-30.gh-issue-134323.ZQZGvw.rst
M Lib/test/lock_tests.py
M Lib/threading.py
M Modules/_threadmodule.c

diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py
index 009e04e9c0b522..0e8c75ff5c4994 100644
--- a/Lib/test/lock_tests.py
+++ b/Lib/test/lock_tests.py
@@ -365,6 +365,24 @@ def test_locked(self):
         lock.release()
         self.assertFalse(lock.locked())
 
+    def test_locked_with_2threads(self):
+        # see gh-134323: check that a rlock which
+        # is acquired in a different thread,
+        # is still locked in the main thread.
+        result = []
+        rlock = self.locktype()
+        self.assertFalse(rlock.locked())
+        def acquire():
+            result.append(rlock.locked())
+            rlock.acquire()
+            result.append(rlock.locked())
+
+        with Bunch(acquire, 1):
+            pass
+        self.assertTrue(rlock.locked())
+        self.assertFalse(result[0])
+        self.assertTrue(result[1])
+
     def test_release_save_unacquired(self):
         # Cannot _release_save an unacquired lock
         lock = self.locktype()
diff --git a/Lib/threading.py b/Lib/threading.py
index fa290d17c635ab..2a65f9a7aa3028 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -165,7 +165,7 @@ def __repr__(self):
         except KeyError:
             pass
         return "<%s %s.%s object owner=%r count=%d at %s>" % (
-            "locked" if self._block.locked() else "unlocked",
+            "locked" if self.locked() else "unlocked",
             self.__class__.__module__,
             self.__class__.__qualname__,
             owner,
@@ -244,7 +244,7 @@ def __exit__(self, t, v, tb):
 
     def locked(self):
         """Return whether this object is locked."""
-        return self._count > 0
+        return self._block.locked()
 
     # Internal methods used by condition variables
 
diff --git 
a/Misc/NEWS.d/next/Library/2025-05-20-19-16-30.gh-issue-134323.ZQZGvw.rst 
b/Misc/NEWS.d/next/Library/2025-05-20-19-16-30.gh-issue-134323.ZQZGvw.rst
new file mode 100644
index 00000000000000..7982b52f77a172
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-05-20-19-16-30.gh-issue-134323.ZQZGvw.rst
@@ -0,0 +1 @@
+Fix the :meth:`threading.RLock.locked` method.
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index 9776a32755db68..8bd59fffa66f88 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -1011,6 +1011,11 @@ rlock_traverse(PyObject *self, visitproc visit, void 
*arg)
     return 0;
 }
 
+static int
+rlock_locked_impl(rlockobject *self)
+{
+    return PyMutex_IsLocked(&self->lock.mutex);
+}
 
 static void
 rlock_dealloc(PyObject *self)
@@ -1100,7 +1105,7 @@ static PyObject *
 rlock_locked(PyObject *op, PyObject *Py_UNUSED(ignored))
 {
     rlockobject *self = rlockobject_CAST(op);
-    int is_locked = _PyRecursiveMutex_IsLockedByCurrentThread(&self->lock);
+    int is_locked = rlock_locked_impl(self);
     return PyBool_FromLong(is_locked);
 }
 
@@ -1202,10 +1207,11 @@ rlock_repr(PyObject *op)
 {
     rlockobject *self = rlockobject_CAST(op);
     PyThread_ident_t owner = self->lock.thread;
+    int locked = rlock_locked_impl(self);
     size_t count = self->lock.level + 1;
     return PyUnicode_FromFormat(
         "<%s %s object owner=%" PY_FORMAT_THREAD_IDENT_T " count=%zu at %p>",
-        owner ? "locked" : "unlocked",
+        locked ? "locked" : "unlocked",
         Py_TYPE(self)->tp_name, owner,
         count, self);
 }

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to