GNOME Bugzilla – Bug 559746
gtk.Widget.set_sensitive should accept None or ""
Last modified: 2012-02-10 08:22:11 UTC
To do something as: self.ok.set_sensitive( self.name.get_text().strip() and self.architecture.get_text().strip() and file and exists(file)) I need to add bool(). It'd be good to be able to do this without using bool().
set_sensitive() it's a wrapper around the sensitive property od gtk.Widget which accepts a gboolean value, not a bug.
I think I know what Marco means. The generated wrapper looks like this: static PyObject * _wrap_gtk_widget_set_sensitive(PyGObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "sensitive", NULL }; int sensitive; if (!PyArg_ParseTupleAndKeywords(args, kwargs,"i:GtkWidget.set_sensitive", kwlist, &sensitive)) return NULL; gtk_widget_set_sensitive(GTK_WIDGET(self->obj), sensitive); Py_INCREF(Py_None); return Py_None; } While the defs look like: (define-method set_sensitive (of-object "GtkWidget") (c-name "gtk_widget_set_sensitive") (return-type "none") (parameters '("gboolean" "sensitive") ) ) So, codegen is treating gboolean as int, which is wrong. Every object has a boolean value, not just integers. "" is false, and None is false. The generated wrapper should look like this instead: static PyObject * _wrap_gtk_widget_set_sensitive(PyGObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "sensitive", NULL }; PyObject *py_sensitive; if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O:GtkWidget.set_sensitive", kwlist, &sensitive)) return NULL; gtk_widget_set_sensitive(GTK_WIDGET(self->obj), PyObject_IsTrue(py_sensitive)); Py_INCREF(Py_None); return Py_None; } codegen/argtypes.py: class BoolArg(IntArg): def write_return(self, ptype, ownsreturn, info): info.varlist.add('int', 'ret') info.codeafter.append(' return PyBool_FromLong(ret);\n') To fix the bug, a write_param method needs to be written for BoolArg that does the right thing.
Gustavo in my opionion it should accept only True|False and not an emtpy string or None, does GTK+ itself accept an empty string or NULL? (rhetorical question)
It is not a question of gtk+, it is a language issue. A simple 'if' statement in Python accepts any object, not just True|False. For example: if "": print "xxx" else: print "yyyy" This prints yyy. Same with None, (), and [].
I know that True|False are not the only possible choice in this case, we can modify (not fix imho) the method to accept other pseudo boolean objects, I just don't think we should do that, but of course I have nothing against it. I still think it's not a bug :)
It is debatable either way. On one hand, by only allowing int type as boolean you are catching some programming errors. On the other hand, if you do that you are being incoherent with the Python language. I'm +0.5 for aligning gboolean with the Python language (i.e. use PyObject_IsTrue), but also understand if people want to stick to the existing behaviour.
I'm -1 on this. I think it is too error-prone for minor convenience of not requiring bool(). If we go this path, why not make gtk.Window.set_title accept anything and use __str__ on it, and so on?
I'm +1 on this. Comment #7 from Paul Pogonyshev: > If we go this path, why not make gtk.Window.set_title accept > anything and use __str__ on it, and so on? Because that's not how the Python language works in other situations. That would make sense in another languages, but not in Python. I Perl, for instance, you can pass an integer where a string is expected: $ perl -e 'print length "abc"' 3 $ perl -e 'print length 123' 3 On the other way, accepting only bool() makes sense in other languages, but not in Python. In Python, you can pass "" or None when a bool() is expected: Comment #4 from Gustavo Carneiro: > if "": > print "xxx" > else: > print "yyyy" Comment #3 from Gian Mario Tagliaretti: > does GTK+ itself accept an empty string or NULL? GTK+ is written in C, and in this language this behaviour makes sense. In this language, writing 1 for True, and 0 for False, makes sense. In Ruby, for instance, 0 is treated as True, since only nil and false are False. My conclusion is that there's no point in keeping the library exact behaviour in all bindings, specially when this behaviour was defined by something that only makes sense in the language that the library was written, in this case, C. Good night.
I'm +1 on this too. As Marco and Gustavo said, this change will make gtk bindings fit better with python concepts. It is common to call such a thing as "Pythonic". I see a very closer case in the way that GtkListStore is binded [0]. A simple C to python binding can be used to append new entries to a model, like this: iter = model.append() model.set(iter, 0, “foobar”) model.set(iter, 1, 1138) model.set(iter, 2, 3.14) But a more pythonic way was added too: model.append(["foobar", 1138, 3.14]) There are other examples that try to make gtk python bindings more natural to a python programmer. So I think it would be really nice to have another thing to make it closer. [0] http://blogs.gnome.org/johan/2008/05/06/using-gtkliststore-in-python/
OK, I change my vote to +0. I agree that booleans are "special" in that e.g. 'if' and similar operators auto-convert anything with __nonzero__/__bool__, but I don't remember any built-in string auto-conversions. Patches are welcome.
Created attachment 137146 [details] [review] Patch to correct the bug This code was based on the IntArg and the UInt64Arg classes.
codegen and the static bindings are obsolete since pygobject 3.0, which is GI only. Thanks!