summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog21
-rw-r--r--docs/reference/ChangeLog14
-rw-r--r--docs/reference/pygtk-gdkcolor.xml24
-rw-r--r--docs/reference/pygtk-gdkrectangle.xml12
-rw-r--r--docs/reference/pygtk-gdkregion.xml11
-rw-r--r--gtk/gdk.override31
-rw-r--r--gtk/gdkcolor.override31
-rw-r--r--gtk/gdkrectangle.override33
-rw-r--r--tests/Makefile.am40
-rw-r--r--tests/test_color.py60
-rw-r--r--tests/test_conversion.py29
-rw-r--r--tests/test_rectangle.py28
12 files changed, 286 insertions, 48 deletions
diff --git a/ChangeLog b/ChangeLog
index 729cb323..5c1cdf23 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2008-08-02 Paul Pogonyshev <pogonyshev@gmx.net>
+
+ Bug 527212 – types with well-defined equality semantics are not
+ properly comparable
+
+ * gtk/gdk.override (_wrap_pygdk_region_tp_richcompare): New
+ function.
+
+ * gtk/gdkcolor.override (_wrap_gdk_color_tp_richcompare): New
+ function.
+
+ * gtk/gdkrectangle.override (_wrap_gdk_rectangle_tp_richcompare):
+ New function.
+
+ * tests/test_conversion.py (testColorCreation): Move to thematic
+ test file.
+
+ * tests/Makefile.am:
+ * tests/test_color.py:
+ * tests/test_rectangle.py: Two new test files.
+
2008-07-29 Gian Mario Tagliaretti <gianmt@gnome.org>
* configure.ac: pygobject 2.15.3 is required to compile pygtk 2.14.
diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog
index 0635f42e..00db8482 100644
--- a/docs/reference/ChangeLog
+++ b/docs/reference/ChangeLog
@@ -1,3 +1,17 @@
+2008-08-02 Paul Pogonyshev <pogonyshev@gmx.net>
+
+ Bug 527212 – types with well-defined equality semantics are not
+ properly comparable
+
+ * pygtk-gdkcolor.xml: Document new constructor option. Document
+ proper comparison as of PyGTK 2.14.
+
+ * pygtk-gdkregion.xml: Document proper comparison as of PyGTK
+ 2.14.
+
+ * pygtk-gdkrectangle.xml: Document proper comparison as of PyGTK
+ 2.14.
+
2008-07-26 Paul Pogonyshev <pogonyshev@gmx.net>
* pygtk-gtkbuilder.xml (connect_signals): Fix signature and
diff --git a/docs/reference/pygtk-gdkcolor.xml b/docs/reference/pygtk-gdkcolor.xml
index ccd69e8b..efc21fd6 100644
--- a/docs/reference/pygtk-gdkcolor.xml
+++ b/docs/reference/pygtk-gdkcolor.xml
@@ -109,6 +109,14 @@ objects since these colors will be allocated when an attempt is made to use
the <link linkend="class-gtkstyle"><classname>gtk.Style</classname></link>
object.</para>
+ <para>
+ Starting with PyGTK 2.14 <classname>gtk.gdk.Color</classname> objects are properly
+ comparable. By Python rules, colors (being mutable) are now unhashable. If you
+ need to use them as dictionary keys, use string representation instead. You can
+ convert string representation to <classname>gtk.gdk.Color</classname> objects using
+ the constructor.
+ </para>
+
</refsect1>
<refsect1 id="constructor-gdkcolor">
@@ -128,6 +136,11 @@ object.</para>
<methodparam><parameter
role="keyword">pixel</parameter>
<initializer>0</initializer></methodparam>
+ </constructorsynopsis></programlisting>
+ <programlisting><constructorsynopsis language="python">
+ <methodname>gtk.gdk.Color</methodname>
+ <methodparam><parameter
+ role="keyword">spec</parameter></methodparam>
</constructorsynopsis></programlisting>
<variablelist>
<varlistentry>
@@ -151,6 +164,10 @@ object.</para>
colormap</simpara></listitem>
</varlistentry>
<varlistentry>
+ <term><parameter role="keyword">spec</parameter>&nbsp;:</term>
+ <listitem><simpara>String containing color specification</simpara></listitem>
+ </varlistentry>
+ <varlistentry>
<term><emphasis>Returns</emphasis>&nbsp;:</term>
<listitem><simpara>a new <link
linkend="class-gdkcolor"><classname>gtk.gdk.Color</classname></link>
@@ -158,6 +175,10 @@ object</simpara></listitem>
</varlistentry>
</variablelist>
+ <note>
+ <para>Second form of the constructor is available in PyGTK 2.14 and above.</para>
+ </note>
+
<para>Creates a new <link
linkend="class-gdkcolor"><classname>gtk.gdk.Color</classname></link> object
with the color component values specified by <parameter>red</parameter>,
@@ -166,6 +187,9 @@ with the color component values specified by <parameter>red</parameter>,
value of <parameter>pixel</parameter> will be overwritten when the color is
allocated.</para>
+ <para>Second form of the constructor is analogous to
+ <link linkend="function-gdk--color-parse"><function>gtk.gdk.color_parse</function></link>.</para>
+
</refsect1>
<refsect1>
diff --git a/docs/reference/pygtk-gdkrectangle.xml b/docs/reference/pygtk-gdkrectangle.xml
index 19de9bb3..222ab3f5 100644
--- a/docs/reference/pygtk-gdkrectangle.xml
+++ b/docs/reference/pygtk-gdkrectangle.xml
@@ -101,6 +101,18 @@ holds the position and size of a rectangle. The position is specified by the
"x" and "y" attributes and the size, by the "width" and "height"
attributes.</para>
+ <para>
+ Starting with PyGTK 2.14 <classname>gtk.gdk.Rectangle</classname> objects are
+ properly comparable. By Python rules, rectangles (being mutable) are now
+ unhashable. If you need to use them as dictionary keys, convert rectangle objects
+ to tuples first. You can convert such tuples back
+ to <classname>gtk.gdk.Rectangle</classname> using the following code:
+ </para>
+
+ <programlisting>
+ rectangle = gtk.gdk.Rectangle(*tuple)
+ </programlisting>
+
</refsect1>
<refsect1 id="constructor-gdkrectangle">
diff --git a/docs/reference/pygtk-gdkregion.xml b/docs/reference/pygtk-gdkregion.xml
index d2631743..5cfa1830 100644
--- a/docs/reference/pygtk-gdkregion.xml
+++ b/docs/reference/pygtk-gdkregion.xml
@@ -125,6 +125,12 @@ linkend="function-gdk--region-rectangle">gtk.gdk.region_rectangle</link></method
linkend="method-gdkgc--set-clip-region"><methodname>gtk.gdk.GC.set_clip_region</methodname>()</link>
method).</para>
+ <para>
+ Starting with PyGTK 2.14 <classname>gtk.gdk.Region</classname> objects are
+ properly comparable. By Python rules, regions (being mutable) are now
+ unhashable.
+ </para>
+
</refsect1>
<refsect1 id="constructor-gdkregion">
@@ -228,6 +234,11 @@ object</simpara></listitem>
region specified by <parameter>other</parameter> is equal to this
region.</para>
+ <note>
+ <para>Since PyGTK 2.14 Python comparison operator (<literal>==</literal>) can be
+ used for the same result.</para>
+ </note>
+
</refsect2>
<refsect2 id="method-gdkregion--point-in">
diff --git a/gtk/gdk.override b/gtk/gdk.override
index cba1ea5d..d56d4e2e 100644
--- a/gtk/gdk.override
+++ b/gtk/gdk.override
@@ -534,6 +534,37 @@ _wrap_gdk_region_get_rectangles(PyGObject *self)
return py_rects;
}
%%
+override-slot GdkRegion.tp_richcompare
+static PyObject *
+_wrap_pygdk_region_tp_richcompare(PyObject *self, PyObject *other, int op)
+{
+ PyObject *result;
+
+ if (PyObject_TypeCheck(self, &PyGdkRegion_Type)
+ && PyObject_TypeCheck(other, &PyGdkRegion_Type)) {
+ GdkRegion *region1 = pyg_boxed_get(self, GdkRegion);
+ GdkRegion *region2 = pyg_boxed_get(other, GdkRegion);
+
+ switch (op) {
+ case Py_EQ:
+ result = (gdk_region_equal(region1, region2)
+ ? Py_True : Py_False);
+ break;
+ case Py_NE:
+ result = (!gdk_region_equal(region1, region2)
+ ? Py_True : Py_False);
+ break;
+ default:
+ result = Py_NotImplemented;
+ }
+ }
+ else
+ result = Py_NotImplemented;
+
+ Py_INCREF(result);
+ return result;
+}
+%%
override-attr GdkDevice.axes
static PyObject *
_wrap_gdk_device__get_axes(PyGObject *self, void *closure)
diff --git a/gtk/gdkcolor.override b/gtk/gdkcolor.override
index 98f58ee7..fe995265 100644
--- a/gtk/gdkcolor.override
+++ b/gtk/gdkcolor.override
@@ -190,6 +190,37 @@ _wrap_gdk_color_alloc(PyGObject *self, PyObject *args, PyObject *kwargs)
return _wrap_gdk_colormap_alloc_color(self, args, kwargs);
}
%%
+override-slot GdkColor.tp_richcompare
+static PyObject *
+_wrap_gdk_color_tp_richcompare(PyObject *self, PyObject *other, int op)
+{
+ PyObject *result;
+
+ if (PyObject_TypeCheck(self, &PyGdkColor_Type)
+ && PyObject_TypeCheck(other, &PyGdkColor_Type)) {
+ GdkColor *color1 = pyg_boxed_get(self, GdkColor);
+ GdkColor *color2 = pyg_boxed_get(other, GdkColor);
+
+ switch (op) {
+ case Py_EQ:
+ result = (gdk_color_equal(color1, color2)
+ ? Py_True : Py_False);
+ break;
+ case Py_NE:
+ result = (!gdk_color_equal(color1, color2)
+ ? Py_True : Py_False);
+ break;
+ default:
+ result = Py_NotImplemented;
+ }
+ }
+ else
+ result = Py_NotImplemented;
+
+ Py_INCREF(result);
+ return result;
+}
+%%
override gdk_colormap_query_color kwargs
static PyObject *
_wrap_gdk_colormap_query_color(PyGObject *self, PyObject *args,
diff --git a/gtk/gdkrectangle.override b/gtk/gdkrectangle.override
index e1a0fcf0..06274c42 100644
--- a/gtk/gdkrectangle.override
+++ b/gtk/gdkrectangle.override
@@ -214,3 +214,36 @@ _wrap_gdk_rectangle_union(PyGObject *self, PyObject *args,
return pyg_boxed_new(GDK_TYPE_RECTANGLE, &dest, TRUE, TRUE);
}
+%%
+override-slot GdkRectangle.tp_richcompare
+static PyObject *
+_wrap_gdk_rectangle_tp_richcompare(PyObject *self, PyObject *other, int op)
+{
+ PyObject *result;
+
+ if (PyObject_TypeCheck(self, &PyGdkRectangle_Type)
+ && PyObject_TypeCheck(other, &PyGdkRectangle_Type)) {
+ GdkRectangle *rect1 = pyg_boxed_get(self, GdkRectangle);
+ GdkRectangle *rect2 = pyg_boxed_get(other, GdkRectangle);
+
+ switch (op) {
+ case Py_EQ:
+ result = (rect1->x == rect2->x && rect1->y == rect2->y
+ && rect1->width == rect2->width && rect1->height == rect2->height
+ ? Py_True : Py_False);
+ break;
+ case Py_NE:
+ result = (rect1->x != rect2->x || rect1->y != rect2->y
+ || rect1->width != rect2->width || rect1->height != rect2->height
+ ? Py_True : Py_False);
+ break;
+ default:
+ result = Py_NotImplemented;
+ }
+ }
+ else
+ result = Py_NotImplemented;
+
+ Py_INCREF(result);
+ return result;
+}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e5756f4c..3ca928b9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,24 +1,26 @@
EXTRA_DIST = $(tests) common.py runtests.py testmodule.py leak.glade
-tests = \
- test_actiongroup.py \
- test_api.py \
- test_bin.py \
- test_button.py \
- test_container.py
- test_conversion.py \
- test_dialog.py \
- test_enum.py \
- test_gdk.py \
- test_glade.py \
- test_liststore.py
- test_pango.py \
- test_plug.py \
- test_radiobutton.py \
- test_style.py \
- test_textview.py \
- test_treeview.py \
- test_filechooserdialog.py
+tests = \
+ test_actiongroup.py \
+ test_api.py \
+ test_bin.py \
+ test_button.py \
+ test_color.py \
+ test_container.py \
+ test_conversion.py \
+ test_dialog.py \
+ test_enum.py \
+ test_filechooserdialog.py \
+ test_gdk.py \
+ test_glade.py \
+ test_liststore.py \
+ test_pango.py \
+ test_plug.py \
+ test_radiobutton.py \
+ test_rectangle.py \
+ test_style.py \
+ test_textview.py \
+ test_treeview.py
GTK_PY_FILES = __init__.py _lazyutils.py compat.py deprecation.py keysyms.py
diff --git a/tests/test_color.py b/tests/test_color.py
new file mode 100644
index 00000000..616c716e
--- /dev/null
+++ b/tests/test_color.py
@@ -0,0 +1,60 @@
+# -*- Mode: Python -*-
+
+import unittest
+
+from common import gtk
+
+
+class Tests(unittest.TestCase):
+
+ def test_constructor(self):
+ """ Test GdkColor creation """
+
+ c = gtk.gdk.Color(1, 2, 3)
+ self.assertEqual(c.red, 1)
+ self.assertEqual(c.green, 2)
+ self.assertEqual(c.blue, 3)
+
+ c = gtk.gdk.Color(pixel=0xffff)
+ self.assertEqual(c.pixel, 0xffff)
+
+ c = gtk.gdk.Color(pixel=0xffffL)
+ self.assertEqual(c.pixel, 0xffff)
+
+ c = gtk.gdk.Color(pixel=0xffffffffL)
+ self.assertEqual(c.pixel, 0xffffffffL)
+
+ c = gtk.gdk.Color('red')
+ self.assertEqual(c.red, 65535)
+ self.assertEqual(c.green, 0)
+ self.assertEqual(c.blue, 0)
+
+ c = gtk.gdk.Color('#ff0000')
+ self.assertEqual(c.red, 65535)
+ self.assertEqual(c.green, 0)
+ self.assertEqual(c.blue, 0)
+
+ self.assertRaises(TypeError, lambda: gtk.gdk.Color([]))
+
+ def test_equal(self):
+ self.assertEqual(gtk.gdk.Color(0, 0, 0), gtk.gdk.Color(0, 0, 0))
+ self.assertEqual(gtk.gdk.Color(100, 200, 300), gtk.gdk.Color(100, 200, 300))
+ self.assertEqual(gtk.gdk.Color('#abc'), gtk.gdk.Color('#aabbcc'))
+ self.assertEqual(gtk.gdk.Color('#100020003000'), gtk.gdk.Color(0x1000, 0x2000, 0x3000))
+
+ def test_not_equal(self):
+ self.assertNotEqual(gtk.gdk.Color('red'), gtk.gdk.Color('blue'))
+ self.assertNotEqual(gtk.gdk.Color(1, 0, 0), gtk.gdk.Color(0, 0, 0))
+ self.assertNotEqual(gtk.gdk.Color(0, 1, 0), gtk.gdk.Color(0, 0, 0))
+ self.assertNotEqual(gtk.gdk.Color(0, 0, 1), gtk.gdk.Color(0, 0, 0))
+
+ def test_non_hashable(self):
+ self.assertRaises(TypeError, lambda: hash(gtk.gdk.Color()))
+
+ def dict_key():
+ {} [gtk.gdk.Color()] = 'must raise'
+ self.assertRaises(TypeError, dict_key)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_conversion.py b/tests/test_conversion.py
index a63d7914..2642d11e 100644
--- a/tests/test_conversion.py
+++ b/tests/test_conversion.py
@@ -52,35 +52,6 @@ class Tests(unittest.TestCase):
self.assertEqual(entry.get_property('invisible_char'),
valid_value, valid_value)
- def testColorCreation(self):
- """ Test GdkColor creation """
-
- c = gtk.gdk.Color(1, 2, 3)
- self.assertEqual(c.red, 1)
- self.assertEqual(c.green, 2)
- self.assertEqual(c.blue, 3)
-
- c = gtk.gdk.Color(pixel=0xffff)
- self.assertEqual(c.pixel, 0xffff)
-
- c = gtk.gdk.Color(pixel=0xffffL)
- self.assertEqual(c.pixel, 0xffff)
-
- c = gtk.gdk.Color(pixel=0xffffffffL)
- self.assertEqual(c.pixel, 0xffffffffL)
-
- c = gtk.gdk.Color('red')
- self.assertEqual(c.red, 65535)
- self.assertEqual(c.green, 0)
- self.assertEqual(c.blue, 0)
-
- c = gtk.gdk.Color('#ff0000')
- self.assertEqual(c.red, 65535)
- self.assertEqual(c.green, 0)
- self.assertEqual(c.blue, 0)
-
- self.assertRaises(TypeError, lambda: gtk.gdk.Color([]))
-
def testUIntArg(self):
child = gtk.DrawingArea()
table = gtk.Table(2, 2, False)
diff --git a/tests/test_rectangle.py b/tests/test_rectangle.py
new file mode 100644
index 00000000..ab5b0646
--- /dev/null
+++ b/tests/test_rectangle.py
@@ -0,0 +1,28 @@
+# -*- Mode: Python -*-
+
+import unittest
+
+from common import gtk
+
+
+class Tests(unittest.TestCase):
+
+ def test_equal(self):
+ self.assertEqual(gtk.gdk.Rectangle(0, 0, 1, 1), gtk.gdk.Rectangle(0, 0, 1, 1))
+
+ def test_not_equal(self):
+ self.assertNotEqual(gtk.gdk.Rectangle(1, 0, 10, 10), gtk.gdk.Rectangle(0, 0, 10, 10))
+ self.assertNotEqual(gtk.gdk.Rectangle(0, 1, 10, 10), gtk.gdk.Rectangle(0, 0, 10, 10))
+ self.assertNotEqual(gtk.gdk.Rectangle(0, 0, 11, 10), gtk.gdk.Rectangle(0, 0, 10, 10))
+ self.assertNotEqual(gtk.gdk.Rectangle(0, 0, 10, 11), gtk.gdk.Rectangle(0, 0, 10, 10))
+
+ def test_non_hashable(self):
+ self.assertRaises(TypeError, lambda: hash(gtk.gdk.Rectangle()))
+
+ def dict_key():
+ {} [gtk.gdk.Rectangle()] = 'must raise'
+ self.assertRaises(TypeError, dict_key)
+
+
+if __name__ == '__main__':
+ unittest.main()