summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gobject/gobjectmodule.c86
-rw-r--r--gobject/pygobject-private.h3
-rw-r--r--gobject/pygobject.c35
-rw-r--r--tests/test_gtype.py9
4 files changed, 87 insertions, 46 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index d0701ce4..e24313ee 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -946,7 +946,7 @@ _wrap_pyg_type_register(PyObject *self, PyObject *args)
if (gtype == NULL) {
PyErr_Clear();
/* not registered */
- if (pyg_type_register(class))
+ if (pyg_type_register(class, NULL))
return NULL;
} else
/* already registered */
@@ -956,13 +956,54 @@ _wrap_pyg_type_register(PyObject *self, PyObject *args)
return (PyObject *) class;
}
+static char *
+get_type_name_for_class(PyTypeObject *class)
+{
+ gint i, name_serial;
+ char name_serial_str[16];
+ PyObject *module;
+ char *type_name = NULL;
+
+ /* make name for new GType */
+ name_serial = 1;
+ /* give up after 1000 tries, just in case.. */
+ while (name_serial < 1000)
+ {
+ snprintf(name_serial_str, 16, "-v%i", name_serial);
+ module = PyObject_GetAttrString((PyObject *)class, "__module__");
+ if (module && PyString_Check(module)) {
+ type_name = g_strconcat(PyString_AsString(module), ".",
+ class->tp_name,
+ name_serial > 1 ? name_serial_str : NULL,
+ NULL);
+ Py_DECREF(module);
+ } else {
+ if (module)
+ Py_DECREF(module);
+ else
+ PyErr_Clear();
+ type_name = g_strconcat(class->tp_name,
+ name_serial > 1 ? name_serial_str : NULL,
+ NULL);
+ }
+ /* convert '.' in type name to '+', which isn't banned (grumble) */
+ for (i = 0; type_name[i] != '\0'; i++)
+ if (type_name[i] == '.')
+ type_name[i] = '+';
+ if (g_type_from_name(type_name) == 0)
+ break; /* we now have a unique name */
+ ++name_serial;
+ }
+
+ return type_name;
+}
+
int
-pyg_type_register(PyTypeObject *class)
+pyg_type_register(PyTypeObject *class, char *type_name)
{
- PyObject *gtype, *module, *gsignals, *gproperties, *overridden_signals;
+ PyObject *gtype, *gsignals, *gproperties, *overridden_signals;
GType parent_type, instance_type;
- gchar *type_name = NULL;
- gint i, name_serial;
+ gint i;
GTypeQuery query;
gpointer gclass;
GTypeInfo type_info = {
@@ -987,38 +1028,9 @@ pyg_type_register(PyTypeObject *class)
return -1;
}
- /* make name for new GType */
- name_serial = 1;
- while (name_serial < 1000) /* give up after 1000 tries, just in case.. */
- {
- char name_serial_str[16];
-
- snprintf(name_serial_str, 16, "-v%i", name_serial);
- module = PyObject_GetAttrString((PyObject *)class, "__module__");
- if (module && PyString_Check(module)) {
- type_name = g_strconcat(PyString_AsString(module), ".",
- class->tp_name,
- name_serial > 1? name_serial_str : NULL,
- NULL);
- Py_DECREF(module);
- } else {
- if (module)
- Py_DECREF(module);
- else
- PyErr_Clear();
- type_name = g_strconcat(class->tp_name,
- name_serial > 1? name_serial_str : NULL,
- NULL);
- }
- /* convert '.' in type name to '+', which isn't banned (grumble) */
- for (i = 0; type_name[i] != '\0'; i++)
- if (type_name[i] == '.')
- type_name[i] = '+';
- if (g_type_from_name(type_name) == 0)
- break; /* we now have a unique name */
- ++name_serial;
- }
-
+ if (!type_name)
+ type_name = get_type_name_for_class(class);
+
/* set class_data that will be passed to the class_init function. */
type_info.class_data = class;
diff --git a/gobject/pygobject-private.h b/gobject/pygobject-private.h
index fb6f4192..50264ff0 100644
--- a/gobject/pygobject-private.h
+++ b/gobject/pygobject-private.h
@@ -104,7 +104,8 @@ PyTypeObject *pygobject_lookup_class (GType gtype);
void pygobject_watch_closure (PyObject *self, GClosure *closure);
void pygobject_register_sinkfunc(GType type,
void (* sinkfunc)(GObject *object));
-int pyg_type_register (PyTypeObject *class);
+int pyg_type_register (PyTypeObject *class,
+ char *typename);
/* from pygboxed.c */
extern PyTypeObject PyGBoxed_Type;
diff --git a/gobject/pygobject.c b/gobject/pygobject.c
index 2c7913d9..2b2b2c4b 100644
--- a/gobject/pygobject.c
+++ b/gobject/pygobject.c
@@ -1244,21 +1244,42 @@ PyTypeObject PyGObject_Type = {
};
+static int
+pygobjectmeta_register(PyTypeObject *subtype, PyObject *instance_dict)
+{
+ PyObject *pytype_name;
+ char *type_name = NULL;
+ int retval = 0;
+
+ if (!instance_dict) {
+ PyErr_Clear();
+ goto out;
+ }
+
+ /* If it's already registered, skip registration */
+ if (PyDict_GetItemString(instance_dict, "__gtype__"))
+ goto out;
+
+ pytype_name = PyDict_GetItemString(instance_dict, "__gtype_name__");
+ if (pytype_name)
+ type_name = g_strdup(PyString_AsString(pytype_name));
+ retval = pyg_type_register(subtype, type_name);
- /* -------- GObject MetaClass -----------*/
+out:
+ return retval;
+}
+
+/* -------- GObject MetaClass -----------*/
static int
pygobjectmeta_init(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
{
PyObject *instance_dict;
+
if (PyType_Type.tp_init((PyObject *) subtype, args, kwargs))
return -1;
+
instance_dict = PyTuple_GetItem(args, 2);
- if (instance_dict) {
- if (PyDict_GetItemString(instance_dict, "__gtype__") == NULL)
- return pyg_type_register(subtype);
- } else
- PyErr_Clear();
- return 0;
+ return pygobjectmeta_register(subtype, instance_dict);
}
diff --git a/tests/test_gtype.py b/tests/test_gtype.py
index a891ba2c..bdaa2d16 100644
--- a/tests/test_gtype.py
+++ b/tests/test_gtype.py
@@ -55,6 +55,13 @@ class GTypeTest(unittest.TestCase):
self.checkType(gobject.TYPE_OBJECT, 'PyObject')
# XXX: Flags, Enums
-
+
+class MyObject(gobject.GObject):
+ __gtype_name__ = 'MyObject'
+
+class TypeNameTest(unittest.TestCase):
+ def testTypeName(self):
+ self.assertEqual(gobject.type_name(MyObject), 'MyObject')
+
if __name__ == '__main__':
unittest.main()