From 66c5899e582bb57be5835c54186cb752d9bc8991 Mon Sep 17 00:00:00 2001
From: Ronald Oussoren <ronaldoussoren@mac.com>
Date: Sun, 14 Jul 2024 21:58:37 +0200
Subject: [PATCH] Set Py_MOD_GIL_NOT_USED for a number of framework extensions

Issue #608
---
 .../Modules/_CoreMedia.m                      |  4 +--
 .../Modules/_SecurityInterface.m              |  4 +--
 .../Modules/_SpriteKit.m                      |  6 +---
 .../Modules/_manual.m                         |  6 +++-
 .../Modules/_VideoToolbox.m                   |  2 +-
 pyobjc-framework-Vision/Modules/_Vision.m     | 29 +++++++++----------
 .../Modules/_libdispatch.m                    | 14 ++-------
 7 files changed, 25 insertions(+), 40 deletions(-)

diff --git a/pyobjc-framework-CoreMedia/Modules/_CoreMedia.m b/pyobjc-framework-CoreMedia/Modules/_CoreMedia.m
index 4557df256..83955c382 100644
--- a/pyobjc-framework-CoreMedia/Modules/_CoreMedia.m
+++ b/pyobjc-framework-CoreMedia/Modules/_CoreMedia.m
@@ -301,9 +301,7 @@ static int mod_exec_module(PyObject* m)
 #pragma clang diagnostic ignored "-Wunguarded-availability-new"
 
     if (&CMVideoFormatDescriptionCreateFromHEVCParameterSets == NULL) {
-        if (PyDict_DelItemString(PyModule_GetDict(m),
-                                 "CMVideoFormatDescriptionCreateFromHEVCParameterSets")
-            == -1) {
+        if (PyObject_DelAttrString(m, "CMVideoFormatDescriptionCreateFromHEVCParameterSets") == -1) {
             return -1;
         }
     }
diff --git a/pyobjc-framework-SecurityInterface/Modules/_SecurityInterface.m b/pyobjc-framework-SecurityInterface/Modules/_SecurityInterface.m
index d488311c1..321d7fff5 100644
--- a/pyobjc-framework-SecurityInterface/Modules/_SecurityInterface.m
+++ b/pyobjc-framework-SecurityInterface/Modules/_SecurityInterface.m
@@ -163,7 +163,7 @@ static int mod_exec_module(PyObject* m)
         return -1;
 
     cls = objc_lookUpClass("SFAuthorizationView");
-    if (cls == NULL) {
+    if (cls == Nil) {
         return 0;
     }
 
@@ -205,7 +205,7 @@ static int mod_exec_module(PyObject* m)
     {
         /* The code in this extension should be safe to use without the GIL */
         .slot = Py_mod_gil,
-        .value = Py_MOD_GIL_USED,
+        .value = Py_MOD_GIL_NOT_USED,
     },
 #endif
     {  /* Sentinel */
diff --git a/pyobjc-framework-SpriteKit/Modules/_SpriteKit.m b/pyobjc-framework-SpriteKit/Modules/_SpriteKit.m
index a155cef77..d7f093df7 100644
--- a/pyobjc-framework-SpriteKit/Modules/_SpriteKit.m
+++ b/pyobjc-framework-SpriteKit/Modules/_SpriteKit.m
@@ -6,9 +6,6 @@
 
 #import <SpriteKit/SpriteKit.h>
 
-/* We include the source code here instead of
- * using the linker due to limitations in pyobjc-api.h
- */
 #include "_SpriteKit_protocols.m"
 
 #if PyObjC_BUILD_RELEASE >= 1012
@@ -36,7 +33,6 @@
     for (i = 0; i < vertexCount; i++) {
         PyObject* item = PySequence_GetItem(value, i);
         if (item == NULL) {
-            Py_DECREF(item);
             PyMem_Free(result);
             return NULL;
         }
@@ -255,7 +251,7 @@ static int mod_exec_module(PyObject* m)
     {
         /* The code in this extension should be safe to use without the GIL */
         .slot = Py_mod_gil,
-        .value = Py_MOD_GIL_USED,
+        .value = Py_MOD_GIL_NOT_USED,
     },
 #endif
     {  /* Sentinel */
diff --git a/pyobjc-framework-SystemConfiguration/Modules/_manual.m b/pyobjc-framework-SystemConfiguration/Modules/_manual.m
index 20004bbc8..d2dafeb28 100644
--- a/pyobjc-framework-SystemConfiguration/Modules/_manual.m
+++ b/pyobjc-framework-SystemConfiguration/Modules/_manual.m
@@ -6,6 +6,10 @@
 
 /*
  * Context definitions
+ *
+ * Note that the use of a tuple object for the context 'info'
+ * is safe because the tuple is fully owned by the context object,
+ * free-threading doesn't change this.
  */
 
 static const void*
@@ -525,7 +529,7 @@ static int mod_exec_module(PyObject* m)
     {
         /* The code in this extension should be safe to use without the GIL */
         .slot = Py_mod_gil,
-        .value = Py_MOD_GIL_USED,
+        .value = Py_MOD_GIL_NOT_USED,
     },
 #endif
     {  /* Sentinel */
diff --git a/pyobjc-framework-VideoToolbox/Modules/_VideoToolbox.m b/pyobjc-framework-VideoToolbox/Modules/_VideoToolbox.m
index b2f5de6a6..d8160335c 100644
--- a/pyobjc-framework-VideoToolbox/Modules/_VideoToolbox.m
+++ b/pyobjc-framework-VideoToolbox/Modules/_VideoToolbox.m
@@ -169,7 +169,7 @@ static int mod_exec_module(PyObject* m)
     {
         /* The code in this extension should be safe to use without the GIL */
         .slot = Py_mod_gil,
-        .value = Py_MOD_GIL_USED,
+        .value = Py_MOD_GIL_NOT_USED,
     },
 #endif
     {  /* Sentinel */
diff --git a/pyobjc-framework-Vision/Modules/_Vision.m b/pyobjc-framework-Vision/Modules/_Vision.m
index 3fe12c694..2114680e6 100644
--- a/pyobjc-framework-Vision/Modules/_Vision.m
+++ b/pyobjc-framework-Vision/Modules/_Vision.m
@@ -35,24 +35,24 @@
     size_t        imageWidth;
     size_t        imageHeight;
 
-    if (args == NULL || !PyTuple_Check(args) || PyTuple_Size(args) != 4) {
+    if (args == NULL || !PyTuple_Check(args) || PyTuple_GET_SIZE(args) != 4) {
         PyErr_SetString(PyExc_TypeError,
                         "Vision.VNNormalizedFaceBoundingBoxPointForLandmarkPoint "
                         "requires 4 arguments");
         return NULL;
     }
-    if (PyObjC_PythonToObjC("<2f>", PyTuple_GetItem(args, 0), &faceLandmarkPoint) == -1) {
+    if (PyObjC_PythonToObjC("<2f>", PyTuple_GET_ITEM(args, 0), &faceLandmarkPoint) == -1) {
         return NULL;
     }
-    if (PyObjC_PythonToObjC(@encode(CGRect), PyTuple_GetItem(args, 1), &faceBoundingBox)
+    if (PyObjC_PythonToObjC(@encode(CGRect), PyTuple_GET_ITEM(args, 1), &faceBoundingBox)
         == -1) {
         return NULL;
     }
-    if (PyObjC_PythonToObjC(@encode(size_t), PyTuple_GetItem(args, 2), &imageWidth)
+    if (PyObjC_PythonToObjC(@encode(size_t), PyTuple_GET_ITEM(args, 2), &imageWidth)
         == -1) {
         return NULL;
     }
-    if (PyObjC_PythonToObjC(@encode(size_t), PyTuple_GetItem(args, 3), &imageHeight)
+    if (PyObjC_PythonToObjC(@encode(size_t), PyTuple_GET_ITEM(args, 3), &imageHeight)
         == -1) {
         return NULL;
     }
@@ -89,23 +89,23 @@
     size_t        imageWidth;
     size_t        imageHeight;
 
-    if (args == NULL || !PyTuple_Check(args) || PyTuple_Size(args) != 4) {
+    if (args == NULL || !PyTuple_Check(args) || PyTuple_GET_SIZE(args) != 4) {
         PyErr_SetString(PyExc_TypeError,
                         "Vision.VNImagePointForFaceLandmarkPoint requires 4 arguments");
         return NULL;
     }
-    if (PyObjC_PythonToObjC("<2f>", PyTuple_GetItem(args, 0), &faceLandmarkPoint) == -1) {
+    if (PyObjC_PythonToObjC("<2f>", PyTuple_GET_ITEM(args, 0), &faceLandmarkPoint) == -1) {
         return NULL;
     }
-    if (PyObjC_PythonToObjC(@encode(CGRect), PyTuple_GetItem(args, 1), &faceBoundingBox)
+    if (PyObjC_PythonToObjC(@encode(CGRect), PyTuple_GET_ITEM(args, 1), &faceBoundingBox)
         == -1) {
         return NULL;
     }
-    if (PyObjC_PythonToObjC(@encode(size_t), PyTuple_GetItem(args, 2), &imageWidth)
+    if (PyObjC_PythonToObjC(@encode(size_t), PyTuple_GET_ITEM(args, 2), &imageWidth)
         == -1) {
         return NULL;
     }
-    if (PyObjC_PythonToObjC(@encode(size_t), PyTuple_GetItem(args, 3), &imageHeight)
+    if (PyObjC_PythonToObjC(@encode(size_t), PyTuple_GET_ITEM(args, 3), &imageHeight)
         == -1) {
         return NULL;
     }
@@ -158,13 +158,10 @@ static int mod_exec_module(PyObject* m)
     if (@available(macOS 10.13, *)) {
         /* pass */
     } else {
-        if (PyDict_DelItemString(PyModule_GetDict(m),
-                                 "VNNormalizedFaceBoundingBoxPointForLandmarkPoint")
-            == -1) {
+        if (PyObject_DelAttrString(m, "VNNormalizedFaceBoundingBoxPointForLandmarkPoint") == -1) {
             return -1;
         }
-        if (PyDict_DelItemString(PyModule_GetDict(m), "VNImagePointForFaceLandmarkPoint")
-            == -1) {
+        if (PyObject_DelAttrString(m, "VNImagePointForFaceLandmarkPoint") == -1) {
             return -1;
         }
     }
@@ -188,7 +185,7 @@ static int mod_exec_module(PyObject* m)
     {
         /* The code in this extension should be safe to use without the GIL */
         .slot = Py_mod_gil,
-        .value = Py_MOD_GIL_USED,
+        .value = Py_MOD_GIL_NOT_USED,
     },
 #endif
     {  /* Sentinel */
diff --git a/pyobjc-framework-libdispatch/Modules/_libdispatch.m b/pyobjc-framework-libdispatch/Modules/_libdispatch.m
index e91e7da54..af1d549c7 100644
--- a/pyobjc-framework-libdispatch/Modules/_libdispatch.m
+++ b/pyobjc-framework-libdispatch/Modules/_libdispatch.m
@@ -41,18 +41,8 @@
         return NULL;
     }
 
-#if Py_MAJOR_VERSION == 3
     py_memview = PyMemoryView_FromMemory(buffer, size, PyBuf_READ)
-#else
-    Py_buffer bufinfo;
-
-    if (PyBuffer_FillInfo(&bufinfo, NULL, (void*)buffer, size, 1, PyBUF_SIMPLE) == -1) {
-        Py_DECREF(py_result);
-        return NULL;
-    }
-    py_memview = PyMemoryView_FromBuffer(&bufinfo);
-#endif
-        if (py_memview == NULL)
+    if (py_memview == NULL)
     {
         Py_DECREF(py_result);
         return NULL;
@@ -222,7 +212,7 @@ static int mod_exec_module(PyObject* m)
     {
         /* The code in this extension should be safe to use without the GIL */
         .slot = Py_mod_gil,
-        .value = Py_MOD_GIL_USED,
+        .value = Py_MOD_GIL_NOT_USED,
     },
 #endif
     {  /* Sentinel */