diff --git a/gobject/propertyhelper.py b/gobject/propertyhelper.py
index 216ceb2..31de103 100644
--- a/gobject/propertyhelper.py
+++ b/gobject/propertyhelper.py
@@ -37,7 +37,17 @@ from gobject.constants import \
      G_MAXULONG
 
 
-class property(object):
+if sys.version_info[0] > 2:
+    long = int
+    basestring = str
+
+class _propertymeta(type):
+    def __repr__(self):
+       return "<class 'gobject.property'>"
+
+propertymeta = _propertymeta('propertymeta', (object, ), {})
+
+class property(propertymeta):
     """
     Creates a new property which in conjunction with GObject subclass will
     create a property proxy:
@@ -61,10 +71,6 @@ class property(object):
     Which will create a read-only property called prop.
     """
 
-    class __metaclass__(type):
-        def __repr__(self):
-            return "<class 'gobject.property'>"
-
     def __init__(self, getter=None, setter=None, type=None, default=None,
                  nick='', blurb='', flags=_gobject.PARAM_READWRITE,
                  minimum=None, maximum=None):
@@ -90,7 +96,7 @@ class property(object):
         @keyword minimum:  minimum allowed value (int, float, long only)
         @keyword maximum:  maximum allowed value (int, float, long only)
         """
-
+        propertymeta.__init__(self)
         if getter and not setter:
             setter = self._readonly_setter
         elif setter and not getter:
@@ -295,3 +301,4 @@ class property(object):
             raise NotImplementedError(ptype)
 
         return (self.type, self.nick, self.blurb) + args + (self.flags,)
+
diff --git a/gobject/pygboxed.c b/gobject/pygboxed.c
index eb274a2..aa81c97 100644
--- a/gobject/pygboxed.c
+++ b/gobject/pygboxed.c
@@ -53,6 +53,33 @@ pyg_boxed_compare(PyGBoxed *self, PyGBoxed *v)
     return 1;
 }
 
+static PyObject*
+pyg_boxed_richcompare(PyGBoxed *self, PyGBoxed *other,
+                      int op)
+{
+    PyObject *res;
+
+    switch (op) {
+
+      case Py_EQ:
+	 res = (self->boxed == other->boxed) ? Py_True : Py_NotImplemented;
+	 Py_INCREF(res);
+	 break;
+
+      case Py_NE:
+	 res = (self->boxed != other->boxed) ? Py_True : Py_NotImplemented;
+	 Py_INCREF(res);
+	 break;
+
+      default:
+	  res = Py_NotImplemented;
+	  Py_INCREF(res);
+	  break;
+    }
+
+    return res;
+}
+
 static long
 pyg_boxed_hash(PyGBoxed *self)
 {
@@ -209,7 +236,8 @@ 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;
+    _PyRegister_Compare_Slot(PyGBoxed_Type, pyg_boxed_compare,
+			     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 b4274e1..6211616 100644
--- a/gobject/pygobject.c
+++ b/gobject/pygobject.c
@@ -781,7 +781,9 @@ static void
 pygobject_inherit_slots(PyTypeObject *type, PyObject *bases, gboolean check_for_present)
 {
     static int slot_offsets[] = { offsetof(PyTypeObject, tp_richcompare),
+#if PY_VERSION_HEX < 0x03000000
 				  offsetof(PyTypeObject, tp_compare),
+#endif
 				  offsetof(PyTypeObject, tp_hash),
 				  offsetof(PyTypeObject, tp_iter),
 				  offsetof(PyTypeObject, tp_repr),
@@ -1011,6 +1013,33 @@ pygobject_compare(PyGObject *self, PyGObject *v)
     return 1;
 }
 
+static PyObject*
+pygobject_richcompare(PyGObject *self, PyGObject *other,
+                      int op)
+{
+    PyObject *res;
+
+    switch (op) {
+
+      case Py_EQ:
+	 res = (self->obj == other->obj) ? Py_True : Py_NotImplemented;
+	 Py_INCREF(res);
+	 break;
+
+      case Py_NE:
+	 res = (self->obj != other->obj) ? Py_True : Py_NotImplemented;
+	 Py_INCREF(res);
+	 break;
+
+      default:
+	  res = Py_NotImplemented;
+	  Py_INCREF(res);
+	  break;
+    }
+
+    return res;
+}
+
 static long
 pygobject_hash(PyGObject *self)
 {
@@ -1995,7 +2024,7 @@ static PyMethodDef pygobject_methods[] = {
     { "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
     { "get_properties", (PyCFunction)pygobject_get_properties, METH_VARARGS },
     { "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
-    { "set_properties", (PyCFunction)pygobject_set_properties, METH_KEYWORDS },
+    { "set_properties", (PyCFunction)pygobject_set_properties, METH_VARARGS|METH_KEYWORDS },
     { "freeze_notify", (PyCFunction)pygobject_freeze_notify, METH_VARARGS },
     { "notify", (PyCFunction)pygobject_notify, METH_VARARGS },
     { "thaw_notify", (PyCFunction)pygobject_thaw_notify, METH_VARARGS },
@@ -2234,7 +2263,8 @@ pygobject_object_register_types(PyObject *d)
 						      pyobject_copy,
 						      pyobject_free);
     PyGObject_Type.tp_dealloc = (destructor)pygobject_dealloc;
-    PyGObject_Type.tp_compare = (cmpfunc)pygobject_compare;
+    _PyRegister_Compare_Slot(PyGObject_Type, pygobject_compare,
+			     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/pygobject.h b/gobject/pygobject.h
index 47beb7d..c7453f4 100644
--- a/gobject/pygobject.h
+++ b/gobject/pygobject.h
@@ -3,7 +3,7 @@
 #define _PYGOBJECT_H_
 
 #include <Python.h>
-
+#include <pyglib.h>
 #include <glib.h>
 #include <glib-object.h>
 
@@ -319,7 +319,7 @@ pygobject_init(int req_major, int req_minor, int req_micro)
             Py_XDECREF(traceback);
             PyErr_Format(PyExc_ImportError,
                          "could not import gobject (error was: %s)",
-                         PyString_AsString(py_orig_exc));
+                         _PyUnicode_AsString(py_orig_exc));
             Py_DECREF(py_orig_exc);
         } else {
             PyErr_SetString(PyExc_ImportError,
diff --git a/gobject/pygparamspec.c b/gobject/pygparamspec.c
index be3840b..4f588c2 100644
--- a/gobject/pygparamspec.c
+++ b/gobject/pygparamspec.c
@@ -40,6 +40,33 @@ pyg_param_spec_compare(PyGParamSpec *self, PyGParamSpec *v)
     return 1;
 }
 
+static PyObject*
+pyg_param_spec_richcompare(PyGParamSpec *self, PyGParamSpec *other,
+                           int op)
+{
+    PyObject *res;
+
+    switch (op) {
+
+      case Py_EQ:
+	 res = (self->pspec == other->pspec) ? Py_True : Py_NotImplemented;
+	 Py_INCREF(res);
+	 break;
+
+      case Py_NE:
+	 res = (self->pspec != other->pspec) ? Py_True : Py_NotImplemented;
+	 Py_INCREF(res);
+	 break;
+
+      default:
+	  res = Py_NotImplemented;
+	  Py_INCREF(res);
+	  break;
+    }
+
+    return res;
+}
+
 static long
 pyg_param_spec_hash(PyGParamSpec *self)
 {
@@ -387,7 +414,8 @@ 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;
+    _PyRegister_Compare_Slot(PyGParamSpec_Type, pyg_param_spec_compare,
+			     pyg_param_spec_richcompare);
     PyGParamSpec_Type.tp_repr = (reprfunc)pyg_param_spec_repr;
     PyGParamSpec_Type.tp_hash = (hashfunc)pyg_param_spec_hash;
 
diff --git a/gobject/pygpointer.c b/gobject/pygpointer.c
index ee0a8da..1316a78 100644
--- a/gobject/pygpointer.c
+++ b/gobject/pygpointer.c
@@ -46,6 +46,33 @@ pyg_pointer_compare(PyGPointer *self, PyGPointer *v)
     return 1;
 }
 
+static PyObject*
+pyg_pointer_richcompare(PyGPointer *self, PyGPointer *other,
+                        int op)
+{
+    PyObject *res;
+
+    switch (op) {
+
+      case Py_EQ:
+	 res = (self->pointer == other->pointer) ? Py_True : Py_NotImplemented;
+	 Py_INCREF(res);
+	 break;
+
+      case Py_NE:
+	 res = (self->pointer != other->pointer) ? Py_True : Py_NotImplemented;
+	 Py_INCREF(res);
+	 break;
+
+      default:
+	  res = Py_NotImplemented;
+	  Py_INCREF(res);
+	  break;
+    }
+
+    return res;
+}
+
 static long
 pyg_pointer_hash(PyGPointer *self)
 {
@@ -176,7 +203,8 @@ 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;
+    _PyRegister_Compare_Slot(PyGPointer_Type, pyg_pointer_compare,
+			     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 601ea83..8bb0d3b 100644
--- a/gobject/pygtype.c
+++ b/gobject/pygtype.c
@@ -47,6 +47,33 @@ pyg_type_wrapper_compare(PyGTypeWrapper *self, PyGTypeWrapper *v)
     return 1;
 }
 
+static PyObject*
+pyg_type_wrapper_richcompare(PyGTypeWrapper *self, PyGTypeWrapper *other,
+                             int op)
+{
+    PyObject *res;
+
+    switch (op) {
+
+      case Py_EQ:
+	 res = (self->type == other->type) ? Py_True : Py_NotImplemented;
+	 Py_INCREF(res);
+	 break;
+
+      case Py_NE:
+	 res = (self->type != other->type) ? Py_True : Py_NotImplemented;
+	 Py_INCREF(res);
+	 break;
+
+      default:
+	  res = Py_NotImplemented;
+	  Py_INCREF(res);
+	  break;
+    }
+
+    return res;
+}
+
 static long
 pyg_type_wrapper_hash(PyGTypeWrapper *self)
 {
@@ -705,7 +732,7 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
 	break;
     case G_TYPE_CHAR:
 	if ((tmp = PyObject_Str(obj)))
-	    g_value_set_char(value, _PyUnicode_AsString(tmp)[0]);
+	    g_value_set_char(value, _PyUnicode_AsString(tmp));
 	else {
 	    PyErr_Clear();
 	    return -1;
@@ -714,7 +741,7 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
 	break;
     case G_TYPE_UCHAR:
 	if ((tmp = PyObject_Str(obj)))
-	    g_value_set_char(value, _PyUnicode_AsString(tmp)[0]);
+	    g_value_set_char(value, _PyUnicode_AsString(tmp));
 	else {
 	    PyErr_Clear();
 	    return -1;
@@ -1342,8 +1369,7 @@ gclosure_from_pyfunc(PyGObject *object, PyObject *func)
     {
         for (l = inst_data->closures; l; l = l->next) {
             PyGClosure *pyclosure = l->data;
-            int res;
-            PyObject_Cmp(pyclosure->callback, func, &res);
+            int res = _PyObject_Cmp(pyclosure->callback, func);
             if (!res) {
                 return (GClosure*)pyclosure;
             }
@@ -1725,7 +1751,8 @@ 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;
+    _PyRegister_Compare_Slot(PyGTypeWrapper_Type, pyg_type_wrapper_compare,
+			     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;
