Skip to content

Commit

Permalink
gh-129766: Fix crash on calling warnings._release_lock with no lock (
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn authored Feb 7, 2025
1 parent e2064d6 commit ae132ed
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 3 deletions.
11 changes: 11 additions & 0 deletions Lib/test/test_warnings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1432,6 +1432,17 @@ class PyEnvironmentVariableTests(EnvironmentVariableTests, unittest.TestCase):
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()."""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix crash in :mod:`warnings`, when calling ``_release_lock()`` with no
existing lock.
9 changes: 6 additions & 3 deletions Python/_warnings.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,12 @@ warnings_lock(PyInterpreterState *interp)
_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
Expand Down Expand Up @@ -284,7 +284,10 @@ warnings_release_lock_impl(PyObject *module)
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;
}

Expand Down

0 comments on commit ae132ed

Please sign in to comment.