[pygobject] move to using richcompare slot instead of compare
- From: John Palmieri <johnp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] move to using richcompare slot instead of compare
- Date: Fri, 13 Aug 2010 16:14:44 +0000 (UTC)
commit 0dc3656070f496431829c6e8441ca17129c569f8
Author: John (J5) Palmieri <johnp redhat com>
Date: Mon Aug 9 16:11:55 2010 -0400
move to using richcompare slot instead of compare
https://bugzilla.gnome.org/show_bug.cgi?id=615872
glib/pygiochannel.c | 18 +++++++---
glib/pyglib.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++
glib/pyglib.h | 3 ++
glib/pygmaincontext.c | 17 ++++++---
glib/pygmainloop.c | 17 ++++++---
glib/pygoptioncontext.c | 18 ++++++----
glib/pygoptiongroup.c | 22 +++++++-----
gobject/pygboxed.c | 18 +++++++---
gobject/pygobject.c | 44 +++++++++++++++++-------
gobject/pygparamspec.c | 19 +++++++---
gobject/pygpointer.c | 17 ++++++---
gobject/pygtype.c | 26 +++++++++++---
12 files changed, 233 insertions(+), 71 deletions(-)
---
diff --git a/glib/pygiochannel.c b/glib/pygiochannel.c
index 4c935e8..97eb8e0 100644
--- a/glib/pygiochannel.c
+++ b/glib/pygiochannel.c
@@ -44,12 +44,18 @@ py_io_channel_next(PyGIOChannel *self)
return ret_obj;
}
-static int
-py_io_channel_compare(PyGIOChannel *self, PyGIOChannel *v)
+static PyObject*
+py_io_channel_richcompare(PyObject *self, PyObject *other, int op)
{
- if (self->channel == v->channel) return 0;
- if (self->channel > v->channel) return -1;
- return 1;
+ if (Py_TYPE(self) == Py_TYPE(other) &&
+ Py_TYPE(self) == &PyGIOChannel_Type) {
+ return _pyglib_generic_ptr_richcompare(((PyGIOChannel*)self)->channel,
+ ((PyGIOChannel*)other)->channel,
+ op);
+ } else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
}
static PyObject*
@@ -732,7 +738,7 @@ pyglib_iochannel_register_types(PyObject *d)
PyGIOChannel_Type.tp_members = py_io_channel_members;
PyGIOChannel_Type.tp_methods = py_io_channel_methods;
PyGIOChannel_Type.tp_hash = (hashfunc)py_io_channel_hash;
- PyGIOChannel_Type.tp_compare = (cmpfunc)py_io_channel_compare;
+ PyGIOChannel_Type.tp_richcompare = (richcmpfunc)py_io_channel_richcompare;
PyGIOChannel_Type.tp_iter = (getiterfunc)py_io_channel_get_iter;
PyGIOChannel_Type.tp_iternext = (iternextfunc)py_io_channel_next;
diff --git a/glib/pyglib.c b/glib/pyglib.c
index 01da551..ffaae7a 100644
--- a/glib/pyglib.c
+++ b/glib/pyglib.c
@@ -574,4 +574,89 @@ _pyglib_handler_marshal(gpointer user_data)
return res;
}
+PyObject*
+_pyglib_generic_ptr_richcompare(void* a, void *b, int op)
+{
+ PyObject *res;
+
+ switch (op) {
+
+ case Py_EQ:
+ res = (a == b) ? Py_True : Py_False;
+ break;
+
+ case Py_NE:
+ res = (a != b) ? Py_True : Py_False;
+ break;
+
+ case Py_LT:
+ break;
+
+ case Py_LE:
+ res = (a <= b) ? Py_True : Py_False;
+ break;
+
+ case Py_GT:
+ res = (a > b) ? Py_True : Py_False;
+ break;
+
+ case Py_GE:
+ res = (a >= b) ? Py_True : Py_False;
+ break;
+
+ default:
+ res = Py_NotImplemented;
+ break;
+ }
+
+ Py_INCREF(res);
+ return res;
+}
+
+PyObject*
+_pyglib_generic_long_richcompare(long a, long b, int op)
+{
+ PyObject *res;
+
+ switch (op) {
+
+ case Py_EQ:
+ res = (a == b) ? Py_True : Py_False;
+ Py_INCREF(res);
+ break;
+
+ case Py_NE:
+ res = (a != b) ? Py_True : Py_False;
+ Py_INCREF(res);
+ break;
+
+
+ case Py_LT:
+ res = (a < b) ? Py_True : Py_False;
+ Py_INCREF(res);
+ break;
+
+ case Py_LE:
+ res = (a <= b) ? Py_True : Py_False;
+ Py_INCREF(res);
+ break;
+
+ case Py_GT:
+ res = (a > b) ? Py_True : Py_False;
+ Py_INCREF(res);
+ break;
+
+ case Py_GE:
+ res = (a >= b) ? Py_True : Py_False;
+ Py_INCREF(res);
+ break;
+
+ default:
+ res = Py_NotImplemented;
+ Py_INCREF(res);
+ break;
+ }
+
+ return res;
+}
diff --git a/glib/pyglib.h b/glib/pyglib.h
index 84bb36c..d72b179 100644
--- a/glib/pyglib.h
+++ b/glib/pyglib.h
@@ -53,6 +53,8 @@ PyObject * pyglib_float_from_timeval(GTimeVal timeval);
/* Private: for gobject <-> glib interaction only. */
void _pyglib_notify_on_enabling_threads(PyGLibThreadsEnabledFunc callback);
+PyObject* _pyglib_generic_ptr_richcompare(void* a, void *b, int op);
+PyObject* _pyglib_generic_long_richcompare(long a, long b, int op);
#define pyglib_begin_allow_threads \
G_STMT_START { \
@@ -88,6 +90,7 @@ PyTypeObject symbol = { \
return; \
PyDict_SetItemString(d, name, (PyObject *)&type);
+
G_END_DECLS
#endif /* __PYGLIB_H__ */
diff --git a/glib/pygmaincontext.c b/glib/pygmaincontext.c
index 186215a..43ca84e 100644
--- a/glib/pygmaincontext.c
+++ b/glib/pygmaincontext.c
@@ -51,12 +51,17 @@ pyg_main_context_dealloc(PyGMainContext *self)
PyObject_Del(self);
}
-static int
-pyg_main_context_compare(PyGMainContext *self, PyGMainContext *v)
+static PyObject*
+pyg_main_context_richcompare(PyObject *self, PyObject *other, int op)
{
- if (self->context == v->context) return 0;
- if (self->context > v->context) return -1;
- return 1;
+ if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGMainContext_Type)
+ return _pyglib_generic_ptr_richcompare(((PyGMainContext*)self)->context,
+ ((PyGMainContext*)other)->context,
+ op);
+ else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
}
static PyObject *
@@ -91,7 +96,7 @@ void
pyglib_maincontext_register_types(PyObject *d)
{
PyGMainContext_Type.tp_dealloc = (destructor)pyg_main_context_dealloc;
- PyGMainContext_Type.tp_compare = (cmpfunc)pyg_main_context_compare;
+ PyGMainContext_Type.tp_richcompare = pyg_main_context_richcompare;
PyGMainContext_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
PyGMainContext_Type.tp_methods = _PyGMainContext_methods;
PyGMainContext_Type.tp_init = (initproc)pyg_main_context_init;
diff --git a/glib/pygmainloop.c b/glib/pygmainloop.c
index d9f048c..de74971 100644
--- a/glib/pygmainloop.c
+++ b/glib/pygmainloop.c
@@ -285,12 +285,17 @@ pyg_main_loop_dealloc(PyGMainLoop *self)
PyObject_Del(self);
}
-static int
-pyg_main_loop_compare(PyGMainLoop *self, PyGMainLoop *v)
+static PyObject*
+pyg_main_loop_richcompare(PyObject *self, PyObject *other, int op)
{
- if (self->loop == v->loop) return 0;
- if (self->loop > v->loop) return -1;
- return 1;
+ if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGMainLoop_Type)
+ return _pyglib_generic_ptr_richcompare(((PyGMainLoop*)self)->loop,
+ ((PyGMainLoop*)other)->loop,
+ op);
+ else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
}
static PyObject *
@@ -346,7 +351,7 @@ void
pyglib_mainloop_register_types(PyObject *d)
{
PyGMainLoop_Type.tp_dealloc = (destructor)pyg_main_loop_dealloc;
- PyGMainLoop_Type.tp_compare = (cmpfunc)pyg_main_loop_compare;
+ PyGMainLoop_Type.tp_richcompare = pyg_main_loop_richcompare;
PyGMainLoop_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
PyGMainLoop_Type.tp_methods = _PyGMainLoop_methods;
PyGMainLoop_Type.tp_init = (initproc)pyg_main_loop_init;
diff --git a/glib/pygoptioncontext.c b/glib/pygoptioncontext.c
index 92ba901..b93026b 100644
--- a/glib/pygoptioncontext.c
+++ b/glib/pygoptioncontext.c
@@ -272,13 +272,17 @@ pyg_option_context_add_group(PyGOptionContext *self,
return Py_None;
}
-static int
-pyg_option_context_compare(PyGOptionContext *self, PyGOptionContext *context)
+static PyObject*
+pyg_option_context_richcompare(PyObject *self, PyObject *other, int op)
{
- if (self->context == context->context) return 0;
- if (self->context > context->context)
- return 1;
- return -1;
+ if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGOptionContext_Type)
+ return _pyglib_generic_ptr_richcompare(((PyGOptionContext*)self)->context,
+ ((PyGOptionContext*)other)->context,
+ op);
+ else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
}
static PyObject *
@@ -304,7 +308,7 @@ void
pyglib_option_context_register_types(PyObject *d)
{
PyGOptionContext_Type.tp_dealloc = (destructor)pyg_option_context_dealloc;
- PyGOptionContext_Type.tp_compare = (cmpfunc)pyg_option_context_compare;
+ PyGOptionContext_Type.tp_richcompare = pyg_option_context_richcompare;
PyGOptionContext_Type.tp_flags = Py_TPFLAGS_DEFAULT;
PyGOptionContext_Type.tp_methods = pyg_option_context_methods;
PyGOptionContext_Type.tp_init = (initproc)pyg_option_context_init;
diff --git a/glib/pygoptiongroup.c b/glib/pygoptiongroup.c
index 70e4529..9345869 100644
--- a/glib/pygoptiongroup.c
+++ b/glib/pygoptiongroup.c
@@ -240,16 +240,18 @@ pyg_option_group_set_translation_domain(PyGOptionGroup *self,
return Py_None;
}
-static int
-pyg_option_group_compare(PyGOptionGroup *self, PyGOptionGroup *group)
+static PyObject*
+pyg_option_group_richcompare(PyObject *self, PyObject *other, int op)
{
- if (self->group == group->group)
- return 0;
-
- if (self->group > group->group)
- return 1;
-
- return -1;
+ if (Py_TYPE(self) == Py_TYPE(other) &&
+ Py_TYPE(self) == &PyGOptionGroup_Type) {
+ return _pyglib_generic_ptr_richcompare(((PyGOptionGroup*)self)->group,
+ ((PyGOptionGroup*)other)->group,
+ op);
+ } else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
}
static PyMethodDef pyg_option_group_methods[] = {
@@ -262,7 +264,7 @@ void
pyglib_option_group_register_types(PyObject *d)
{
PyGOptionGroup_Type.tp_dealloc = (destructor)pyg_option_group_dealloc;
- PyGOptionGroup_Type.tp_compare = (cmpfunc)pyg_option_group_compare;
+ PyGOptionGroup_Type.tp_richcompare = pyg_option_group_richcompare;
PyGOptionGroup_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
PyGOptionGroup_Type.tp_methods = pyg_option_group_methods;
PyGOptionGroup_Type.tp_init = (initproc)pyg_option_group_init;
diff --git a/gobject/pygboxed.c b/gobject/pygboxed.c
index 7bc8e8e..9a71afe 100644
--- a/gobject/pygboxed.c
+++ b/gobject/pygboxed.c
@@ -47,14 +47,20 @@ pyg_boxed_dealloc(PyGBoxed *self)
Py_TYPE(self)->tp_free((PyObject *)self);
}
-static int
-pyg_boxed_compare(PyGBoxed *self, PyGBoxed *v)
+static PyObject*
+pyg_boxed_richcompare(PyObject *self, PyObject *other, int op)
{
- if (self->boxed == v->boxed) return 0;
- if (self->boxed > v->boxed) return -1;
- return 1;
+ if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGBoxed_Type)
+ return _pyglib_generic_ptr_richcompare(((PyGBoxed*)self)->boxed,
+ ((PyGBoxed*)other)->boxed,
+ op);
+ else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
}
+
static long
pyg_boxed_hash(PyGBoxed *self)
{
@@ -216,7 +222,7 @@ pygobject_boxed_register_types(PyObject *d)
pygboxed_marshal_key = g_quark_from_static_string("PyGBoxed::marshal");
PyGBoxed_Type.tp_dealloc = (destructor)pyg_boxed_dealloc;
- PyGBoxed_Type.tp_compare = (cmpfunc)pyg_boxed_compare;
+ PyGBoxed_Type.tp_richcompare = pyg_boxed_richcompare;
PyGBoxed_Type.tp_repr = (reprfunc)pyg_boxed_repr;
PyGBoxed_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
PyGBoxed_Type.tp_methods = pygboxed_methods;
diff --git a/gobject/pygobject.c b/gobject/pygobject.c
index 804f392..46db8e1 100644
--- a/gobject/pygobject.c
+++ b/gobject/pygobject.c
@@ -809,12 +809,15 @@ static void
pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, gboolean check_for_present)
{
static int slot_offsets[] = { offsetof(PyTypeObject, tp_richcompare),
- offsetof(PyTypeObject, tp_compare),
- offsetof(PyTypeObject, tp_hash),
- offsetof(PyTypeObject, tp_iter),
- offsetof(PyTypeObject, tp_repr),
- offsetof(PyTypeObject, tp_str),
- offsetof(PyTypeObject, tp_print) };
+#if PY_VERSION_HEX < 0x03000000
+ offsetof(PyTypeObject, tp_compare),
+#endif
+ offsetof(PyTypeObject, tp_richcompare),
+ offsetof(PyTypeObject, tp_hash),
+ offsetof(PyTypeObject, tp_iter),
+ offsetof(PyTypeObject, tp_repr),
+ offsetof(PyTypeObject, tp_str),
+ offsetof(PyTypeObject, tp_print) };
int i;
/* Happens when registering gobject.GObject itself, at least. */
@@ -1035,12 +1038,29 @@ pygobject_dealloc(PyGObject *self)
PyObject_GC_Del(self);
}
-static int
-pygobject_compare(PyGObject *self, PyGObject *v)
+static PyObject*
+pygobject_richcompare(PyObject *self, PyObject *other, int op)
{
- if (self->obj == v->obj) return 0;
- if (self->obj > v->obj) return -1;
- return 1;
+ int isinst;
+
+ isinst = PyObject_IsInstance(self, (PyObject*)&PyGObject_Type);
+ if (isinst == -1)
+ return NULL;
+ if (!isinst) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ isinst = PyObject_IsInstance(other, (PyObject*)&PyGObject_Type);
+ if (isinst == -1)
+ return NULL;
+ if (!isinst) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ return _pyglib_generic_ptr_richcompare(((PyGObject*)self)->obj,
+ ((PyGObject*)other)->obj,
+ op);
}
static long
@@ -2273,7 +2293,7 @@ pygobject_object_register_types(PyObject *d)
pyobject_copy,
pyobject_free);
PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc;
- PyGObject_Type.tp_compare = (cmpfunc)pygobject_compare;
+ PyGObject_Type.tp_richcompare = pygobject_richcompare;
PyGObject_Type.tp_repr = (reprfunc)pygobject_repr;
PyGObject_Type.tp_hash = (hashfunc)pygobject_hash;
PyGObject_Type.tp_setattro = (setattrofunc)pygobject_setattro;
diff --git a/gobject/pygparamspec.c b/gobject/pygparamspec.c
index be3840b..97910b1 100644
--- a/gobject/pygparamspec.c
+++ b/gobject/pygparamspec.c
@@ -32,12 +32,17 @@
PYGLIB_DEFINE_TYPE("gobject.GParamSpec", PyGParamSpec_Type, PyGParamSpec);
-static int
-pyg_param_spec_compare(PyGParamSpec *self, PyGParamSpec *v)
+static PyObject*
+pyg_param_spec_richcompare(PyObject *self, PyObject *other, int op)
{
- if (self->pspec == v->pspec) return 0;
- if (self->pspec > v->pspec) return -1;
- return 1;
+ if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGParamSpec_Type)
+ return _pyglib_generic_ptr_richcompare(((PyGParamSpec*)self)->pspec,
+ ((PyGParamSpec*)other)->pspec,
+ op);
+ else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
}
static long
@@ -387,10 +392,12 @@ pygobject_paramspec_register_types(PyObject *d)
Py_TYPE(&PyGParamSpec_Type) = &PyType_Type;
PyGParamSpec_Type.tp_dealloc = (destructor)pyg_param_spec_dealloc;
PyGParamSpec_Type.tp_getattr = (getattrfunc)pyg_param_spec_getattr;
- PyGParamSpec_Type.tp_compare = (cmpfunc)pyg_param_spec_compare;
+ PyGParamSpec_Type.tp_richcompare = pyg_param_spec_richcompare;
+ PyGParamSpec_Type.tp_flags = Py_TPFLAGS_DEFAULT;
PyGParamSpec_Type.tp_repr = (reprfunc)pyg_param_spec_repr;
PyGParamSpec_Type.tp_hash = (hashfunc)pyg_param_spec_hash;
+
if (PyType_Ready(&PyGParamSpec_Type))
return;
PyDict_SetItemString(d, "GParamSpec", (PyObject *)&PyGParamSpec_Type);
diff --git a/gobject/pygpointer.c b/gobject/pygpointer.c
index 95bfae9..a894351 100644
--- a/gobject/pygpointer.c
+++ b/gobject/pygpointer.c
@@ -41,12 +41,17 @@ pyg_pointer_dealloc(PyGPointer *self)
Py_TYPE(self)->tp_free((PyObject *)self);
}
-static int
-pyg_pointer_compare(PyGPointer *self, PyGPointer *v)
+static PyObject*
+pyg_pointer_richcompare(PyObject *self, PyObject *other, int op)
{
- if (self->pointer == v->pointer) return 0;
- if (self->pointer > v->pointer) return -1;
- return 1;
+ if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGPointer_Type)
+ return _pyglib_generic_ptr_richcompare(((PyGPointer*)self)->pointer,
+ ((PyGPointer*)other)->pointer,
+ op);
+ else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
}
static long
@@ -183,7 +188,7 @@ pygobject_pointer_register_types(PyObject *d)
pygpointer_class_key = g_quark_from_static_string("PyGPointer::class");
PyGPointer_Type.tp_dealloc = (destructor)pyg_pointer_dealloc;
- PyGPointer_Type.tp_compare = (cmpfunc)pyg_pointer_compare;
+ PyGPointer_Type.tp_richcompare = pyg_pointer_richcompare;
PyGPointer_Type.tp_repr = (reprfunc)pyg_pointer_repr;
PyGPointer_Type.tp_hash = (hashfunc)pyg_pointer_hash;
PyGPointer_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
diff --git a/gobject/pygtype.c b/gobject/pygtype.c
index 5550ce8..2e78ffb 100644
--- a/gobject/pygtype.c
+++ b/gobject/pygtype.c
@@ -47,6 +47,20 @@ pyg_type_wrapper_compare(PyGTypeWrapper *self, PyGTypeWrapper *v)
return 1;
}
+
+static PyObject*
+pyg_type_wrapper_richcompare(PyObject *self, PyObject *other, int op)
+{
+ if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGTypeWrapper_Type)
+ return _pyglib_generic_long_richcompare(((PyGTypeWrapper*)self)->type,
+ ((PyGTypeWrapper*)other)->type,
+ op);
+ else {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+}
+
static long
pyg_type_wrapper_hash(PyGTypeWrapper *self)
{
@@ -1372,13 +1386,13 @@ gclosure_from_pyfunc(PyGObject *object, PyObject *func)
GSList *l;
PyGObjectData *inst_data;
inst_data = pyg_object_peek_inst_data(object->obj);
- if (inst_data)
- {
+ if (inst_data) {
for (l = inst_data->closures; l; l = l->next) {
PyGClosure *pyclosure = l->data;
- int res;
- PyObject_Cmp(pyclosure->callback, func, &res);
- if (!res) {
+ int res = PyObject_RichCompareBool(pyclosure->callback, func, Py_EQ);
+ if (res == -1) {
+ PyErr_Clear(); // Is there anything else to do?
+ } else if (res) {
return (GClosure*)pyclosure;
}
}
@@ -1759,7 +1773,7 @@ void
pygobject_type_register_types(PyObject *d)
{
PyGTypeWrapper_Type.tp_dealloc = (destructor)pyg_type_wrapper_dealloc;
- PyGTypeWrapper_Type.tp_compare = (cmpfunc)pyg_type_wrapper_compare;
+ PyGTypeWrapper_Type.tp_richcompare = pyg_type_wrapper_richcompare;
PyGTypeWrapper_Type.tp_repr = (reprfunc)pyg_type_wrapper_repr;
PyGTypeWrapper_Type.tp_hash = (hashfunc)pyg_type_wrapper_hash;
PyGTypeWrapper_Type.tp_flags = Py_TPFLAGS_DEFAULT;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]