Jonathan Blandford wrote:

>Jonathan Blandford <[EMAIL PROTECTED]> writes:
>
>  
>
>>Hi,
>>
>>I spent the weekend taking a look at the pygtk code while trying to
>>write a widget from scratch.  Some comments:
>>    
>>
>
>EEEEK!
>
>I sent the wrong patch!  You were prolly wondering what I was talking
>about.  Here's the real one.
>
>Thanks,
>-Jonathan
>
>  
>
>------------------------------------------------------------------------
>
>? core.13010
>? core.13293
>? core.13706
>? core.14415
>? core.14712
>? pygtk/examples/gobject/core.1209
>? pygtk/examples/gobject/core.4087
>Index: pygtk/ChangeLog
>===================================================================
>RCS file: /cvs/gnome/gnome-python/pygtk/ChangeLog,v
>retrieving revision 1.419
>diff -u -p -r1.419 ChangeLog
>--- pygtk/ChangeLog    20 Jun 2002 03:31:38 -0000      1.419
>+++ pygtk/ChangeLog    21 Jun 2002 13:05:59 -0000
>@@ -1,3 +1,8 @@
>+Mon Jun 17 13:16:26 2002  Jonathan Blandford  <[EMAIL PROTECTED]>
>+
>+      * pygobject.c (pygobject_init): take kwargs so we can pass
>+      construct-only arguments to our initialization function.
>+
> 2002-06-19  Matt Wilson  <[EMAIL PROTECTED]>
> 
>       * gtk/gtk.override (_wrap_gtk_ctree_insert_node): check the
>Index: pygtk/pygboxed.c
>===================================================================
>RCS file: /cvs/gnome/gnome-python/pygtk/pygboxed.c,v
>retrieving revision 1.2
>diff -u -p -r1.2 pygboxed.c
>--- pygtk/pygboxed.c   5 Feb 2002 07:13:20 -0000       1.2
>+++ pygtk/pygboxed.c   21 Jun 2002 13:05:59 -0000
>@@ -61,6 +61,21 @@ pyg_boxed_free(PyObject *op)
>   PyObject_FREE(op);
> }
> 
>+static PyObject *
>+pyg_boxed_copy(PyGBoxed *self)
>+{
>+    return pyg_boxed_new (self->gtype, self->boxed, TRUE, TRUE);
>+}
>+
>+
>+
>+static PyMethodDef pygboxed_methods[] = {
>+    { "copy", (PyCFunction) pyg_boxed_copy, METH_NOARGS },
>+    { NULL, NULL, 0 }
>+};
>+
>+
>+
> PyTypeObject PyGBoxed_Type = {
>     PyObject_HEAD_INIT(NULL)
>     0,                                  /* ob_size */
>@@ -91,7 +106,7 @@ PyTypeObject PyGBoxed_Type = {
>     0,                                        /* tp_weaklistoffset */
>     (getiterfunc)0,                   /* tp_iter */
>     (iternextfunc)0,                  /* tp_iternext */
>-    0,                                        /* tp_methods */
>+    pygboxed_methods,                   /* tp_methods */
>     0,                                        /* tp_members */
>     0,                                        /* tp_getset */
>     (PyTypeObject *)0,                        /* tp_base */
>
This part looks fine.

>Index: pygtk/pygobject.c
>===================================================================
>RCS file: /cvs/gnome/gnome-python/pygtk/pygobject.c,v
>retrieving revision 1.2
>diff -u -p -r1.2 pygobject.c
>--- pygtk/pygobject.c  28 Jan 2002 00:46:55 -0000      1.2
>+++ pygtk/pygobject.c  21 Jun 2002 13:05:59 -0000
>@@ -229,11 +229,26 @@ pygobject_free(PyObject *op)
> 
> /* ---------------- PyGObject methods ----------------- */
> 
>+static void
>+parameter_list_free (GParameter *parameters, guint n_parameters)
>+{
>+      gint i;
>+      for (i = 0; i < n_parameters; i ++){
>+              g_free ((char *)parameters[i].name);
>+              g_value_unset (&(parameters[i].value));
>+      }
>+      g_free (parameters);
>+}
>+
> static int
> pygobject_init(PyGObject *self, PyObject *args, PyObject *kwargs)
> {
>     GType object_type;
>-
>+    guint n_parameters = 0;
>+    GParameter *parameters = NULL;
>+    PyObject *key, *item;
>+    gint pos = 0;
>+    
>     if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
>       return -1;
> 
>@@ -241,7 +256,47 @@ pygobject_init(PyGObject *self, PyObject
>     if (!object_type)
>       return -1;
> 
>-    self->obj = g_object_new(object_type, NULL);
>+    if (kwargs) {
>+        while (PyDict_Next(kwargs, &pos, &key, &item)) {
>+          gchar *param_name;
>+          GParamSpec *pspec;
>+          GValue value = { 0, };
>+          GObjectClass *class;
>+          class = g_type_class_peek (object_type);
>+          param_name = PyString_AsString(key);
>+          pspec = g_object_class_find_property(class, param_name);
>+
>+          if (pspec == NULL) {
>+                  gchar buf[128];
>+                  
>+                  g_snprintf(buf, sizeof(buf),
>+                             "Unknown parameter '%s' used in type initialization 
>arguments",
>+                             param_name);
>+                  PyErr_SetString(PyExc_AttributeError, buf);
>+                  parameter_list_free (parameters, n_parameters);
>+                  return -1;
>+          }
>+          g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
>+          if (pyg_value_from_pyobject(&value, item) < 0) {
>+                  PyErr_SetString(PyExc_TypeError,
>+                      "could not convert argument to correct param type");
>+                  parameter_list_free (parameters, n_parameters);
>+                  return -1;
>+          }
>+
>+          n_parameters ++;
>+          if (parameters == NULL) {
>+                  parameters = g_new (GParameter, 1);
>+          } else {
>+                  parameters = g_renew (GParameter, parameters, n_parameters);
>+          }
>+          parameters[n_parameters - 1].name = g_strdup (param_name);
>+          parameters[n_parameters - 1].value = value;
>+      }
>+    }
>+
>+    self->obj = g_object_newv(object_type, n_parameters, parameters);
>+    parameter_list_free (parameters, n_parameters);
>     if (!self->obj) {
>       PyErr_SetString(PyExc_RuntimeError, "could not create object");
>       return -1;
>
It would probably be better to swipe code from pyg_object_new() in 
gobjectmodule.c for this.  I don't know if g_type_class_peek() is 
guaranteed to work the way you have used it here.  It is probably 
necessary to g_type_class_ref() and then unref() the class struct.

>Index: pygtk/pygtype.c
>===================================================================
>RCS file: /cvs/gnome/gnome-python/pygtk/pygtype.c,v
>retrieving revision 1.11
>diff -u -p -r1.11 pygtype.c
>--- pygtk/pygtype.c    17 Jun 2002 18:28:38 -0000      1.11
>+++ pygtk/pygtype.c    21 Jun 2002 13:06:00 -0000
>@@ -579,7 +579,7 @@ pyg_value_as_pyobject(const GValue *valu
>               return bm->fromvalue(value);
>           else
>               return pyg_boxed_new(G_VALUE_TYPE(value),
>-                                   g_value_get_boxed(value), TRUE, TRUE);
>+                                   g_value_get_boxed(value), FALSE, FALSE);/* How 
>much will this make us leak?? */
>       }
>     case G_TYPE_PARAM:
>       return pyg_param_spec_new(g_value_get_param(value));
>  
>
This will break things.  For instance, it would break 
GObject.get_property() on a boxed property.  The following would happen:
  g_value_init(&value, boxed_type);
  g_object_get_property(instance, "boxed_prop", &value);
  wrapper = pyg_boxed_new(boxed_type, g_value_get_boxed(&value), FALSE, 
FALSE); /* no copy made */
  g_value_unset(&value); /* frees the boxed owned by &value */
  return wrapper;

Which will leave wrapper in an undefined state.  This needs to be 
conditional.

James.

-- 
Email: [EMAIL PROTECTED]              | Linux.conf.au 2003 Call for Papers out
WWW:   http://www.daa.com.au/~james/ |   http://conf.linux.org.au/cfp.html




_______________________________________________
pygtk mailing list   [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to