GNOME Bugzilla – Bug 403212
wrap pygobject_get|set for multiple properties manipulation
Last modified: 2007-04-23 14:29:56 UTC
wrap g_object_get, g_object_set in order to get|set multiple properties in one go, following the patch, docs and a simple example.
Created attachment 81659 [details] [review] the patch
Created attachment 81660 [details] [review] docs
Created attachment 81661 [details] simple example
Should we not wait until bug 338024 is resolved before including this? The implementation and wrapper of bug 338024 is going to be faster than this one. (In reply to comment #1) > Created an attachment (id=81659) [edit] > the patch > You should probably freeze property notifications before and release them afterwards. Can you write up a simple test too?
I would like to support also properties as **kwargs: win.set_properties(resizable=False, title="My Window", urgency_hint=True)
(In reply to comment #5) > I would like to support also properties as **kwargs: > win.set_properties(resizable=False, title="My Window", urgency_hint=True) > Ditto. I'd like to add /only/ support kwargs. I didn't look to closely at the patch. Gian: look at _wrap_gtk_cell_layout_set_attributes in gtk.override for an example how to wrap that.
(In reply to comment #6) > Ditto. I'd like to add /only/ support kwargs. > I didn't look to closely at the patch. sure, I also prefer kwargs, I just followed (mistaking) another method. > Gian: look at _wrap_gtk_cell_layout_set_attributes in gtk.override for an > example how to wrap that. I have used the same approach that I have already have used in the past with goocanvas, I hope you will like it. new patch, docs, example and test will follow.
Created attachment 81696 [details] [review] new with kwargs
Created attachment 81697 [details] [review] new docs with kwargs
Created attachment 81698 [details] update example with kwargs
I agree that keyword args are the way to go. Just wanted to note that properties for some widgets need to be set in a particular order and that people should use multiple set calls in these cases.
Created attachment 81707 [details] unit test
Comment on attachment 81696 [details] [review] new with kwargs >Index: gobject/pygobject.c >=================================================================== >--- gobject/pygobject.c (revision 637) >+++ gobject/pygobject.c (working copy) >@@ -1113,6 +1113,63 @@ > } > > static PyObject * >+pygobject_get_properties(PyGObject *self, PyObject *args) >+{ >+ GObjectClass *class; >+ int len, i; >+ PyObject *tuple; >+ >+ if ((len = PyTuple_Size(args)) < 1) { >+ PyErr_SetString(PyExc_TypeError, "requires at least one argument"); >+ return NULL; >+ } >+ >+ tuple = PyTuple_New(len); >+ class = G_OBJECT_GET_CLASS(self->obj); >+ for (i = 0; i < len; i++) { >+ PyObject *py_property = PyTuple_GetItem(args, i); >+ gchar *property_name; >+ GParamSpec *pspec; >+ GValue value = { 0 }; >+ PyObject *item; >+ >+ if (!PyString_Check(py_property)) { >+ PyErr_SetString(PyExc_TypeError, >+ "Expected string argument for property."); >+ return NULL; >+ } >+ >+ property_name = PyString_AsString(py_property); >+ >+ pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(self->obj), >+ property_name); >+ if (!pspec) { >+ PyErr_Format(PyExc_TypeError, >+ "object of type `%s' does not have property `%s'", >+ g_type_name(G_OBJECT_TYPE(self->obj)), property_name); >+ return NULL; >+ } >+ if (!(pspec->flags & G_PARAM_READABLE)) { >+ PyErr_Format(PyExc_TypeError, "property %s is not readable", >+ property_name); >+ return NULL; >+ } >+ g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); >+ >+ g_object_get_property(self->obj, property_name, &value); >+ >+ item = pyg_value_as_pyobject(&value, TRUE); >+ PyTuple_SetItem(tuple, i, item); >+ Py_INCREF(item); Excessive INCREF, memleak. >+ >+ g_value_unset(&value); >+ } >+ >+ Py_INCREF(tuple); This INCREF is too much, causes mem leak. >+ return tuple; >+} >+ >+static PyObject * > pygobject_set_property(PyGObject *self, PyObject *args) > { > gchar *param_name; >@@ -1142,6 +1199,56 @@ > } > > static PyObject * >+pygobject_set_properties(PyGObject *self, PyObject *args, PyObject *kwargs) >+{ >+ GObjectClass *class; >+ int pos; This is not Python 2.5 + 64-bit ready. Should be "Py_ssize_t pos;".
(In reply to comment #11) > I agree that keyword args are the way to go. Just wanted to note that > properties for some widgets need to be set in a particular order and that > people should use multiple set calls in these cases. > Good point, I didn't think of that. Not sure how often you actually need to set properties in a particular order.
Created attachment 81825 [details] [review] after gjc comments
Committed revision 646.