[pygobject] Improve setting pointer fields/arguments to NULL using None



commit 4f77c7798563ea436ff5b6306a987f03de50b211
Author: Simon Feltman <s feltman gmail com>
Date:   Fri Sep 7 02:32:15 2012 -0700

    Improve setting pointer fields/arguments to NULL using None
    
    Setting gi pointers will set them to the address of the python object.
    This is good except in the case of None which should be used to NULL
    the pointer out as a special case.
    
    Commit 21b1d17d2a already fixed this. This improved patch
    does that in a cleaner and safer way and adds more comments.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=683150

 gi/pygi-argument.c |    8 +-------
 gi/pygi-info.c     |   14 +++++++++++++-
 2 files changed, 14 insertions(+), 8 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 38af25b..234a229 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -867,13 +867,7 @@ _pygi_argument_from_object (PyObject   *object,
     switch (type_tag) {
         case GI_TYPE_TAG_VOID:
             g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
-            if (object == Py_None) {
-                Py_DECREF(Py_None);
-                arg.v_pointer = NULL;
-            } else {
-                /* This will leak a reference to the python object. */
-                arg.v_pointer = object;
-            }
+            arg.v_pointer = object == Py_None ? NULL : object;
             break;
         case GI_TYPE_TAG_BOOLEAN:
         {
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index 3ca5c8f..dd117ee 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -1430,9 +1430,21 @@ _wrap_g_field_info_set_value (PyGIBaseInfo *self,
         offset = g_field_info_get_offset ((GIFieldInfo *) self->info);
         value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING);
 
+        /* Decrement the previous python object stashed on the void pointer.
+         * This seems somewhat dangerous as the code is blindly assuming any
+         * void pointer field stores a python object pointer and then decrefs it.
+         * This is essentially the same as something like:
+         *  Py_XDECREF(struct->void_ptr); */
         Py_XDECREF(G_STRUCT_MEMBER (gpointer, pointer, offset));
+
+        /* Assign and increment the newly assigned object. At this point the value
+         * arg will hold a pointer the python object "py_value" or NULL.
+         * This is essentially:
+         *  struct->void_ptr = value.v_pointer;
+         *  Py_XINCREF(struct->void_ptr);
+         */
         G_STRUCT_MEMBER (gpointer, pointer, offset) = (gpointer)value.v_pointer;
-        Py_XINCREF(py_value);
+        Py_XINCREF(G_STRUCT_MEMBER (gpointer, pointer, offset));
 
         retval = Py_None;
         goto out;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]