summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/internal/pycore_pystate.h8
-rw-r--r--Lib/test/test_capi/test_mem.py9
-rw-r--r--Lib/test/test_capi/test_misc.py17
-rw-r--r--Misc/NEWS.d/next/C_API/2024-11-26-22-06-10.gh-issue-127314.SsRrIu.rst2
-rw-r--r--Objects/obmalloc.c7
5 files changed, 36 insertions, 7 deletions
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index 54d8803..1e73e54 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -190,10 +190,18 @@ static inline void
_Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate)
{
if (tstate == NULL) {
+#ifndef Py_GIL_DISABLED
_Py_FatalErrorFunc(func,
"the function must be called with the GIL held, "
"after Python initialization and before Python finalization, "
"but the GIL is released (the current Python thread state is NULL)");
+#else
+ _Py_FatalErrorFunc(func,
+ "the function must be called with an active thread state, "
+ "after Python initialization and before Python finalization, "
+ "but it was called without an active thread state. "
+ "Are you trying to call the C API inside of a Py_BEGIN_ALLOW_THREADS block?");
+#endif
}
}
diff --git a/Lib/test/test_capi/test_mem.py b/Lib/test/test_capi/test_mem.py
index 6ab7b68..5035b2b 100644
--- a/Lib/test/test_capi/test_mem.py
+++ b/Lib/test/test_capi/test_mem.py
@@ -68,8 +68,13 @@ class PyMemDebugTests(unittest.TestCase):
def check_malloc_without_gil(self, code):
out = self.check(code)
- expected = ('Fatal Python error: _PyMem_DebugMalloc: '
- 'Python memory allocator called without holding the GIL')
+ if not support.Py_GIL_DISABLED:
+ expected = ('Fatal Python error: _PyMem_DebugMalloc: '
+ 'Python memory allocator called without holding the GIL')
+ else:
+ expected = ('Fatal Python error: _PyMem_DebugMalloc: '
+ 'Python memory allocator called without an active thread state. '
+ 'Are you trying to call it inside of a Py_BEGIN_ALLOW_THREADS block?')
self.assertIn(expected, out)
def test_pymem_malloc_without_gil(self):
diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py
index 8e02719..61512e6 100644
--- a/Lib/test/test_capi/test_misc.py
+++ b/Lib/test/test_capi/test_misc.py
@@ -100,11 +100,18 @@ class CAPITest(unittest.TestCase):
_rc, out, err = run_result
self.assertEqual(out, b'')
# This used to cause an infinite loop.
- msg = ("Fatal Python error: PyThreadState_Get: "
- "the function must be called with the GIL held, "
- "after Python initialization and before Python finalization, "
- "but the GIL is released "
- "(the current Python thread state is NULL)").encode()
+ if not support.Py_GIL_DISABLED:
+ msg = ("Fatal Python error: PyThreadState_Get: "
+ "the function must be called with the GIL held, "
+ "after Python initialization and before Python finalization, "
+ "but the GIL is released "
+ "(the current Python thread state is NULL)").encode()
+ else:
+ msg = ("Fatal Python error: PyThreadState_Get: "
+ "the function must be called with an active thread state, "
+ "after Python initialization and before Python finalization, "
+ "but it was called without an active thread state. "
+ "Are you trying to call the C API inside of a Py_BEGIN_ALLOW_THREADS block?").encode()
self.assertTrue(err.rstrip().startswith(msg),
err)
diff --git a/Misc/NEWS.d/next/C_API/2024-11-26-22-06-10.gh-issue-127314.SsRrIu.rst b/Misc/NEWS.d/next/C_API/2024-11-26-22-06-10.gh-issue-127314.SsRrIu.rst
new file mode 100644
index 0000000..8ea3c4e
--- /dev/null
+++ b/Misc/NEWS.d/next/C_API/2024-11-26-22-06-10.gh-issue-127314.SsRrIu.rst
@@ -0,0 +1,2 @@
+Improve error message when calling the C API without an active thread state
+on the :term:`free-threaded <free threading>` build.
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index 2cc0377..b103deb 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -2910,9 +2910,16 @@ static inline void
_PyMem_DebugCheckGIL(const char *func)
{
if (!PyGILState_Check()) {
+#ifndef Py_GIL_DISABLED
_Py_FatalErrorFunc(func,
"Python memory allocator called "
"without holding the GIL");
+#else
+ _Py_FatalErrorFunc(func,
+ "Python memory allocator called "
+ "without an active thread state. "
+ "Are you trying to call it inside of a Py_BEGIN_ALLOW_THREADS block?");
+#endif
}
}