summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2023-03-31 13:45:22 +0200
committerStefan Behnel <stefan_ml@behnel.de>2023-04-02 12:21:08 +0200
commit74573879df24fc23202ddcebc6501cae6f881c18 (patch)
treebcf9494054d07fb27000320c885c694b8d69432a
parent4c42949b47eff1bce921fae71ed93ec359dd32a4 (diff)
downloadcython-74573879df24fc23202ddcebc6501cae6f881c18.tar.gz
Add an explicit (although unnecessary) "noexcept" marker to the "PyCapsule_Destructor" function type to document explicitly that it must not emit exceptions.
See https://github.com/scipy/scipy/issues/17234
-rw-r--r--Cython/Includes/cpython/pycapsule.pxd2
-rw-r--r--tests/run/pycapsule.pyx33
2 files changed, 34 insertions, 1 deletions
diff --git a/Cython/Includes/cpython/pycapsule.pxd b/Cython/Includes/cpython/pycapsule.pxd
index c3d12c749..08062da85 100644
--- a/Cython/Includes/cpython/pycapsule.pxd
+++ b/Cython/Includes/cpython/pycapsule.pxd
@@ -13,7 +13,7 @@ cdef extern from "Python.h":
# access C APIs defined in dynamically loaded modules.
- ctypedef void (*PyCapsule_Destructor)(object o)
+ ctypedef void (*PyCapsule_Destructor)(object o) noexcept
# The type of a destructor callback for a capsule.
#
# See PyCapsule_New() for the semantics of PyCapsule_Destructor
diff --git a/tests/run/pycapsule.pyx b/tests/run/pycapsule.pyx
new file mode 100644
index 000000000..3bba08d88
--- /dev/null
+++ b/tests/run/pycapsule.pyx
@@ -0,0 +1,33 @@
+# mode: run
+
+import gc
+from cpython cimport pycapsule
+
+cdef int value = 5
+cdef bint destructed = False
+
+cdef void destructor(object obj) noexcept:
+ # PyPy's GC does not guarantee immediate execution.
+ global destructed
+ destructed = True
+
+
+def was_destructed():
+ return destructed
+
+
+def test_capsule():
+ """
+ >>> test_capsule()
+ True
+ >>> _ = gc.collect()
+ >>> was_destructed() # let's assume that gc.collect() is enough to assert this
+ True
+ """
+ capsule = pycapsule.PyCapsule_New(&value, b"simple value", &destructor)
+
+ assert pycapsule.PyCapsule_GetName(capsule) == b"simple value"
+ assert pycapsule.PyCapsule_GetPointer(capsule, b"simple value") is &value
+ assert pycapsule.PyCapsule_GetDestructor(capsule) is &destructor
+
+ return pycapsule.PyCapsule_IsValid(capsule, b"simple value")