Skip to content

Commit 262520b

Browse files
author
cxzhong
committed
Fix Python 3.14t free-threaded build: use Py_REFCNT() instead of ob_refcnt
- Declare Py_REFCNT() as external C function from Python.h - Replace direct ob_refcnt access with Py_REFCNT() macro (2 occurrences) - Add NULL checks before calling Py_REFCNT() to prevent null pointer dereference - This fixes compilation errors in Python 3.14t (free-threaded/nogil) build where ob_refcnt is not directly accessible in PyObject structure - All 66 tests pass
1 parent 19c9434 commit 262520b

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

src/cysignals/signals.pyx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ cdef extern from *:
4848
"""
4949
pass
5050

51+
# Declare Py_REFCNT for Python 3.14t free-threaded build compatibility
52+
cdef extern from "Python.h":
53+
Py_ssize_t Py_REFCNT(PyObject *ob)
54+
5155
cdef extern from "implementation.c":
5256
cysigs_t cysigs
5357
int _set_debug_level(int) nogil
@@ -361,7 +365,7 @@ cdef void verify_exc_value() noexcept:
361365
Check that ``cysigs.exc_value`` is still the exception being raised.
362366
Clear ``cysigs.exc_value`` if not.
363367
"""
364-
if cysigs.exc_value.ob_refcnt == 1:
368+
if cysigs.exc_value != NULL and Py_REFCNT(cysigs.exc_value) == 1:
365369
# No other references => exception is certainly gone
366370
Py_CLEAR(cysigs.exc_value)
367371
return
@@ -409,5 +413,5 @@ cdef void verify_exc_value() noexcept:
409413
# Make sure we still have cysigs.exc_value at all; if this function was
410414
# called again during garbage collection it might have already been set
411415
# to NULL; see https://github.com/sagemath/cysignals/issues/126
412-
if cysigs.exc_value != NULL and cysigs.exc_value.ob_refcnt == 1:
416+
if cysigs.exc_value != NULL and Py_REFCNT(cysigs.exc_value) == 1:
413417
Py_CLEAR(cysigs.exc_value)

0 commit comments

Comments
 (0)