GNOME Bugzilla – Bug 705291
Python 3 int type is coerced into TYPE_INT instead of TYPE_LONG for GValues
Last modified: 2013-09-12 08:39:34 UTC
Python3 introduced a change where ints now hold long values. When attempting to store a long in a TreeStore/ListStore, it overflows as an int. This does work correctly when using a long in Python2. Sample output:
+ Trace 232324
return self._do_insert(-1, row)
row, columns = self._convert_row(row)
result.append(self._convert_value(cur_col, value))
return GObject.Value(self.get_column_type(column), value)
self.set_value(py_value)
self.set_int(py_value)
Well that would be correct -- 19304808448 indeed by far doesn't fit into an int. So I rather think that it's the Python 2 version that is faulty here because it does *not* raise the OverflowError. Which version of pygobject are you running? The latest 3.9.5 fixes quite a lot in the area of overflow detection. Do you have a more complete code example, i. e. do you actually initialize that TreeView colum with type "int"?
Hello Martin. In Python 2, I specifically use a long. Since longs are no longer available in Python 3 (ints are now long by default), I use int, but the value is not correctly stored (it's converted back into an int). I wonder if the introspection uses a C integer instead of a long and if that is causing the problem? Below is an example of the code being used for the liststore. if python3: model = Gtk.ListStore(GdkPixbuf.Pixbuf, str, int, str, float, str, bool, bool, int) else: #python2 model = Gtk.ListStore(GdkPixbuf.Pixbuf, str, long, str, float, str, bool, bool, int) The column is using gchar, I use a function to convert the long value to a human-readable file size. I am using python-gi 3.9.5 in Ubuntu 13.10.
The issue looks to be in how Python type objects are coerced into GTypes: https://git.gnome.org/browse/pygobject/tree/gi/_gobject/pygtype.c?id=3.9.5#n382 PYGLIB_PyLong_Type is defined as PyLong_Type in Python 3. Since it is the first item in the dispatch, we always get a G_TYPE_INT even though there is an explicit test for PyLong_Type later on (which returns G_TYPE_LONG). This is an easy fix but there might be fallout (at least I've verified in unittests). In the meantime you should be able to work around this by using GObject.TYPE_LONG explicitly as the ListStore column argument (should also work the same in both Python 2 and 3).
Unfortunately this is looking like "won't fix" territory. While the fix is simple, a whole lot of our tests break which makes me think there will be fallout. If an API expects a GValue of type G_TYPE_INT and people have been using raw numbers in Python, the call would break because the API would be receiving GValues of type G_TYPE_LONG. If you need to store numbers bigger than G_TYPE_INT, it can be done explicitly (which also guarantees size on 32 bit machines where I think GObject.TYPE_LONG might be 32 bits): model = Gtk.ListStore(GObject.TYPE_INT64) model.append([GObject.G_MAXINT64])
*** Bug 683775 has been marked as a duplicate of this bug. ***
As mentioned I don't see a way of fixing this without the potential to cause regressions. Python int must always translate to GObject.TYPE_INT. If you need bigger storage, use one of the various GObject.TYPE_* types explicitly.