summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2014-05-26 01:22:35 (GMT)
committerRaymond Hettinger <python@rcn.com>2014-05-26 01:22:35 (GMT)
commit62f4dad81607d8d0a70223ef3feacdfd3aa5e898 (patch)
tree5e4c3b7ccb6ab56240b77da3946c4e0a301c72f3
parentfa4ed0c145f2e17ccd59c2180cbf7be07c8c872d (diff)
downloadcpython-62f4dad81607d8d0a70223ef3feacdfd3aa5e898.zip
cpython-62f4dad81607d8d0a70223ef3feacdfd3aa5e898.tar.gz
cpython-62f4dad81607d8d0a70223ef3feacdfd3aa5e898.tar.bz2
Issue 21137: Better repr for threading.Lock()
-rw-r--r--Lib/_dummy_thread.py8
-rw-r--r--Lib/test/lock_tests.py8
-rw-r--r--Lib/test/test_importlib/test_locks.py3
-rw-r--r--Lib/threading.py10
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/_threadmodule.c15
6 files changed, 41 insertions, 6 deletions
diff --git a/Lib/_dummy_thread.py b/Lib/_dummy_thread.py
index b67cfb9..36e5f38 100644
--- a/Lib/_dummy_thread.py
+++ b/Lib/_dummy_thread.py
@@ -140,6 +140,14 @@ class LockType(object):
def locked(self):
return self.locked_status
+ def __repr__(self):
+ return "<%s %s.%s object at %s>" % (
+ "locked" if self.locked_status else "unlocked",
+ self.__class__.__module__,
+ self.__class__.__qualname__,
+ hex(id(self))
+ )
+
# Used to signal that interrupt_main was called in a "thread"
_interrupt = False
# True when not executing in a "thread"
diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py
index 1cbcea2..136f1c3 100644
--- a/Lib/test/lock_tests.py
+++ b/Lib/test/lock_tests.py
@@ -82,7 +82,13 @@ class BaseLockTests(BaseTestCase):
def test_repr(self):
lock = self.locktype()
- repr(lock)
+ self.assertRegex(repr(lock), "<unlocked .* object (.*)?at .*>")
+ del lock
+
+ def test_locked_repr(self):
+ lock = self.locktype()
+ lock.acquire()
+ self.assertRegex(repr(lock), "<locked .* object (.*)?at .*>")
del lock
def test_acquire_destroy(self):
diff --git a/Lib/test/test_importlib/test_locks.py b/Lib/test/test_importlib/test_locks.py
index 0805054..4c01177 100644
--- a/Lib/test/test_importlib/test_locks.py
+++ b/Lib/test/test_importlib/test_locks.py
@@ -31,6 +31,9 @@ if threading is not None:
test_timeout = None
# _release_save() unsupported
test_release_save_unacquired = None
+ # lock status in repr unsupported
+ test_repr = None
+ test_locked_repr = None
LOCK_TYPES = {kind: splitinit._bootstrap._ModuleLock
for kind, splitinit in init.items()}
diff --git a/Lib/threading.py b/Lib/threading.py
index 3407083..c7c4478 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -106,8 +106,14 @@ class _RLock:
owner = _active[owner].name
except KeyError:
pass
- return "<%s owner=%r count=%d>" % (
- self.__class__.__name__, owner, self._count)
+ return "<%s %s.%s object owner=%r count=%d at %s>" % (
+ "locked" if self._block.locked() else "unlocked",
+ self.__class__.__module__,
+ self.__class__.__qualname__,
+ owner,
+ self._count,
+ hex(id(self))
+ )
def acquire(self, blocking=True, timeout=-1):
"""Acquire a lock, blocking or non-blocking.
diff --git a/Misc/NEWS b/Misc/NEWS
index 83fbeb8..ce98087 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -97,6 +97,9 @@ Library
- Issue #21513: Speedup some properties of IP addresses (IPv4Address,
IPv6Address) such as .is_private or .is_multicast.
+- Issue #21137: Improve the repr for threading.Lock() and its variants
+ by showing the "locked" or "unlocked" status. Patch by Berker Peksag.
+
- Issue #21538: The plistlib module now supports loading of binary plist files
when reference or offset size is not a power of two.
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index 9925b0e..b68c177 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -192,6 +192,13 @@ PyDoc_STRVAR(locked_doc,
\n\
Return whether the lock is in the locked state.");
+static PyObject *
+lock_repr(lockobject *self)
+{
+ return PyUnicode_FromFormat("<%s %s object at %p>",
+ self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
+}
+
static PyMethodDef lock_methods[] = {
{"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
METH_VARARGS | METH_KEYWORDS, acquire_doc},
@@ -223,7 +230,7 @@ static PyTypeObject Locktype = {
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_reserved*/
- 0, /*tp_repr*/
+ (reprfunc)lock_repr, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
@@ -475,8 +482,10 @@ rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyObject *
rlock_repr(rlockobject *self)
{
- return PyUnicode_FromFormat("<%s owner=%ld count=%lu>",
- Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count);
+ return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
+ self->rlock_count ? "locked" : "unlocked",
+ Py_TYPE(self)->tp_name, self->rlock_owner,
+ self->rlock_count, self);
}