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/