module = py_warnings
+class LocksTest(unittest.TestCase):
+ @support.cpython_only
+ @unittest.skipUnless(c_warnings, 'C module is required')
+ def test_release_lock_no_lock(self):
+ with self.assertRaisesRegex(
+ RuntimeError,
+ 'cannot release un-acquired lock',
+ ):
+ c_warnings._release_lock()
+
+
class _DeprecatedTest(BaseTest, unittest.TestCase):
"""Test _deprecated()."""
--- /dev/null
+Fix crash in :mod:`warnings`, when calling ``_release_lock()`` with no
+existing lock.
_PyRecursiveMutex_Lock(&st->lock);
}
-static inline void
+static inline int
warnings_unlock(PyInterpreterState *interp)
{
WarningsState *st = warnings_get_state(interp);
assert(st != NULL);
- _PyRecursiveMutex_Unlock(&st->lock);
+ return _PyRecursiveMutex_TryUnlock(&st->lock);
}
static inline bool
if (interp == NULL) {
return NULL;
}
- warnings_unlock(interp);
+ if (warnings_unlock(interp) < 0) {
+ PyErr_SetString(PyExc_RuntimeError, "cannot release un-acquired lock");
+ return NULL;
+ }
Py_RETURN_NONE;
}