GNOME Bugzilla – Bug 527212
types with well-defined equality semantics are not properly comparable
Last modified: 2018-08-17 13:35:25 UTC
>>> a = gtk.gdk.Color (0, 0, 0) >>> b = gtk.gdk.Color (0, 0, 0) >>> a == b False To me this looks like a bug, but I file it with 'enhancement' severity. Likely applies to some other types like rectangles as well.
Created attachment 109083 [details] [review] patch for gtk.gdk.Color, gtk.gdk.Region and gtk.gdk.Rectangle Adds __eq__/__ne__ for 3 types in gtk.gdk. Returns NotImplemented for ordering comparison. That yields weird results in Python 2.x, but I believe we should follow suit. AFAIK in Python 3.0 it becomes more strict and I suspect NotImplemented will get transformed into an exception there (obviously cannot test PyGTK on 3.0, too lazy to test with anything else.)
One unfortunate thing: now these objects compare by identity and are hashable. In this case hashing is fine, though comparison by identity is quite meaningless anyway. However, if we switch to comparing by contents (as would make sense), by Python rules the objects _must_ become unhashable, because they are mutable. So, we have quite significant backward incompatibility here... Alternatively, we can make rectangles and colors immutable, but that is probably even more of a compatibility break.
One more idea is to have gtk.gdk.Rectangle and gtk.gdk.FrozenRectangle, much as built-in 'set' and 'frozenset' in Python. First would be like the current type, except that it would be properly comparable and (hence) non-hashable. Second would be like plain rectangles, except that immutable and (hence) hashable. (I'm speaking about rectangles here, but we can generalize this to other types as well.) Note that in Python 'set' and 'frozenset' are not a superclass of each other. This is, strictly speaking, correct as neither provides all functionality of the other. However, this makes writing isinstance() checks more difficult: you should write isinstance (foo, (set, frozenset)) to catch both cases.
Created attachment 113935 [details] example, demonstrating why mutable classes must not be hashable This is just a demonstration why mutable classes (in which mutations can affect equality result, I mean) must not be hashable. While you'd expect it output True 4 times, it only does it 2 times. After the mutation, set becomes broken.
Created attachment 115640 [details] [review] patch for gtk.gdk.Color, gtk.gdk.Region and gtk.gdk.Rectangle + tests and docs The same (functionally) patch, with tests for gtk.gdk.Color and gtk.gdk.Rectnagle and documentation changes for all three classes added. I also moved misplaced test for gtk.gdk.Color constructor.
Created attachment 115641 [details] [review] patch for gtk.gdk.Color, gtk.gdk.Region and gtk.gdk.Rectangle + tests and docs Forgot to remove chunk disabling the now-failing treeview test (must be a bug in GTK+).
Committed the first patch (approved by Johan on IRC). I keep the bug open for now, as there are probably more types in need of similar changes. Sending ChangeLog Sending docs/reference/ChangeLog Sending docs/reference/pygtk-gdkcolor.xml Sending docs/reference/pygtk-gdkrectangle.xml Sending docs/reference/pygtk-gdkregion.xml Sending gtk/gdk.override Sending gtk/gdkcolor.override Sending gtk/gdkrectangle.override Sending tests/Makefile.am Adding tests/test_color.py Sending tests/test_conversion.py Adding tests/test_rectangle.py Transmitting file data ............ Committed revision 3014.
pygtk is not under active development anymore and had its last code changes in 2013. Its codebase has been archived: https://gitlab.gnome.org/Archive/pygtk/commits/master PyGObject at https://gitlab.gnome.org/GNOME/pygobject is its successor. See https://pygobject.readthedocs.io/en/latest/guide/porting.html for porting info. Closing this report as WONTFIX as part of Bugzilla Housekeeping to reflect reality. Feel free to open a task in GNOME Gitlab if the issue described in this task still applies to a recent version of PyGObject. Thanks!