Issue 21137: Better repr for threading.Lock()

This commit is contained in:
Raymond Hettinger 2014-05-25 18:22:35 -07:00
parent fa4ed0c145
commit 62f4dad816
6 changed files with 41 additions and 6 deletions

View File

@ -140,6 +140,14 @@ class LockType(object):
def locked(self): def locked(self):
return self.locked_status 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" # Used to signal that interrupt_main was called in a "thread"
_interrupt = False _interrupt = False
# True when not executing in a "thread" # True when not executing in a "thread"

View File

@ -82,7 +82,13 @@ class BaseLockTests(BaseTestCase):
def test_repr(self): def test_repr(self):
lock = self.locktype() 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 del lock
def test_acquire_destroy(self): def test_acquire_destroy(self):

View File

@ -31,6 +31,9 @@ if threading is not None:
test_timeout = None test_timeout = None
# _release_save() unsupported # _release_save() unsupported
test_release_save_unacquired = None test_release_save_unacquired = None
# lock status in repr unsupported
test_repr = None
test_locked_repr = None
LOCK_TYPES = {kind: splitinit._bootstrap._ModuleLock LOCK_TYPES = {kind: splitinit._bootstrap._ModuleLock
for kind, splitinit in init.items()} for kind, splitinit in init.items()}

View File

@ -106,8 +106,14 @@ class _RLock:
owner = _active[owner].name owner = _active[owner].name
except KeyError: except KeyError:
pass pass
return "<%s owner=%r count=%d>" % ( return "<%s %s.%s object owner=%r count=%d at %s>" % (
self.__class__.__name__, owner, self._count) "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): def acquire(self, blocking=True, timeout=-1):
"""Acquire a lock, blocking or non-blocking. """Acquire a lock, blocking or non-blocking.

View File

@ -97,6 +97,9 @@ Library
- Issue #21513: Speedup some properties of IP addresses (IPv4Address, - Issue #21513: Speedup some properties of IP addresses (IPv4Address,
IPv6Address) such as .is_private or .is_multicast. 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 - Issue #21538: The plistlib module now supports loading of binary plist files
when reference or offset size is not a power of two. when reference or offset size is not a power of two.

View File

@ -192,6 +192,13 @@ PyDoc_STRVAR(locked_doc,
\n\ \n\
Return whether the lock is in the locked state."); 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[] = { static PyMethodDef lock_methods[] = {
{"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock, {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
METH_VARARGS | METH_KEYWORDS, acquire_doc}, METH_VARARGS | METH_KEYWORDS, acquire_doc},
@ -223,7 +230,7 @@ static PyTypeObject Locktype = {
0, /*tp_getattr*/ 0, /*tp_getattr*/
0, /*tp_setattr*/ 0, /*tp_setattr*/
0, /*tp_reserved*/ 0, /*tp_reserved*/
0, /*tp_repr*/ (reprfunc)lock_repr, /*tp_repr*/
0, /*tp_as_number*/ 0, /*tp_as_number*/
0, /*tp_as_sequence*/ 0, /*tp_as_sequence*/
0, /*tp_as_mapping*/ 0, /*tp_as_mapping*/
@ -475,8 +482,10 @@ rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyObject * static PyObject *
rlock_repr(rlockobject *self) rlock_repr(rlockobject *self)
{ {
return PyUnicode_FromFormat("<%s owner=%ld count=%lu>", return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count); self->rlock_count ? "locked" : "unlocked",
Py_TYPE(self)->tp_name, self->rlock_owner,
self->rlock_count, self);
} }