summaryrefslogtreecommitdiff
path: root/gobject
diff options
context:
space:
mode:
authorGustavo J. A. M. Carneiro <gjc@src.gnome.org>2006-04-11 21:51:06 +0000
committerGustavo J. A. M. Carneiro <gjc@src.gnome.org>2006-04-11 21:51:06 +0000
commit921eb7103fce05bb55aaadc0bcd3527781a1b229 (patch)
tree34e9d19e16167878c437ef27632c27d7d35508eb /gobject
parent2b30a70e7b7d2111910ebbf76750bdefe51381ff (diff)
downloadpygobject-921eb7103fce05bb55aaadc0bcd3527781a1b229.tar.gz
Move GObjectMeta from C to python-land
Diffstat (limited to 'gobject')
-rw-r--r--gobject/__init__.py18
-rw-r--r--gobject/gobjectmodule.c23
-rw-r--r--gobject/pygobject-private.h2
-rw-r--r--gobject/pygobject.c92
4 files changed, 36 insertions, 99 deletions
diff --git a/gobject/__init__.py b/gobject/__init__.py
index c31c7773..22cc4347 100644
--- a/gobject/__init__.py
+++ b/gobject/__init__.py
@@ -28,3 +28,21 @@ except ImportError:
pass
from _gobject import *
+
+class GObjectMeta(type):
+ "Metaclass for automatically gobject.type_register()ing GObject classes"
+ def __init__(cls, name, bases, dict_):
+ type.__init__(cls, name, bases, dict_)
+ ## don't register the class if already registered
+ if '__gtype__' in cls.__dict__:
+ return
+
+ if not ('__gproperties__' in cls.__dict__ or
+ '__gsignals__' in cls.__dict__ or
+ '__gtype_name__' in cls.__dict__):
+ return
+
+ type_register(cls, cls.__dict__.get('__gtype_name__'))
+
+_gobject._install_metaclass(GObjectMeta)
+
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index 9f4faafd..753a8370 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -1070,8 +1070,9 @@ static PyObject *
_wrap_pyg_type_register(PyObject *self, PyObject *args)
{
PyTypeObject *class;
+ char *type_name = NULL;
- if (!PyArg_ParseTuple(args, "O!:gobject.type_register", &PyType_Type, &class))
+ if (!PyArg_ParseTuple(args, "O!|z:gobject.type_register", &PyType_Type, &class, &type_name))
return NULL;
if (!PyType_IsSubtype(class, &PyGObject_Type)) {
PyErr_SetString(PyExc_TypeError,"argument must be a GObject subclass");
@@ -1082,7 +1083,7 @@ _wrap_pyg_type_register(PyObject *self, PyObject *args)
if (pyg_type_from_object((PyObject *) class) ==
pyg_type_from_object((PyObject *) class->tp_base))
{
- if (pyg_type_register(class, NULL))
+ if (pyg_type_register(class, type_name))
return NULL;
}
@@ -2461,6 +2462,16 @@ pyg_remove_emission_hook(PyGObject *self, PyObject *args)
return Py_None;
}
+static PyObject *
+pyg__install_metaclass(PyObject *dummy, PyTypeObject *metaclass)
+{
+ Py_INCREF(metaclass);
+ PyGObject_MetaType = metaclass;
+ Py_INCREF(metaclass);
+ PyGObject_Type.ob_type = metaclass;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
static PyMethodDef pygobject_functions[] = {
{ "type_name", pyg_type_name, METH_VARARGS },
@@ -2492,6 +2503,7 @@ static PyMethodDef pygobject_functions[] = {
{ "signal_accumulator_true_handled", (PyCFunction)pyg_signal_accumulator_true_handled, METH_VARARGS },
{ "add_emission_hook", (PyCFunction)pyg_add_emission_hook, METH_VARARGS },
{ "remove_emission_hook", (PyCFunction)pyg_remove_emission_hook, METH_VARARGS },
+ { "_install_metaclass", (PyCFunction)pyg__install_metaclass, METH_O },
{ NULL, NULL, 0 }
};
@@ -3002,13 +3014,6 @@ init_gobject(void)
gerror_exc = PyErr_NewException("gobject.GError", PyExc_RuntimeError,NULL);
PyDict_SetItemString(d, "GError", gerror_exc);
- PyGObject_MetaType.tp_base = &PyType_Type;
- PyGObject_MetaType.tp_traverse = PyType_Type.tp_traverse;
- PyGObject_MetaType.tp_clear = PyType_Type.tp_clear;
- PyGObject_MetaType.tp_is_gc = PyType_Type.tp_is_gc;
- PyType_Ready(&PyGObject_MetaType);
- PyDict_SetItemString(d, "GObjectMeta", (PyObject *) &PyGObject_MetaType);
-
PyGObject_Type.tp_alloc = PyType_GenericAlloc;
PyGObject_Type.tp_new = PyType_GenericNew;
pygobject_register_class(d, "GObject", G_TYPE_OBJECT,
diff --git a/gobject/pygobject-private.h b/gobject/pygobject-private.h
index 84d01b45..e1aa5579 100644
--- a/gobject/pygobject-private.h
+++ b/gobject/pygobject-private.h
@@ -101,7 +101,7 @@ GClosure *pyg_signal_class_closure_get(void);
PyObject *pyg_object_descr_doc_get(void);
-extern PyTypeObject PyGObject_MetaType;
+extern PyTypeObject *PyGObject_MetaType;
/* from pygobject.h */
extern PyTypeObject PyGObject_Type;
diff --git a/gobject/pygobject.c b/gobject/pygobject.c
index a4fb38ac..b9a51b1e 100644
--- a/gobject/pygobject.c
+++ b/gobject/pygobject.c
@@ -34,6 +34,8 @@ typedef struct {
} SinkFunc;
static GArray *sink_funcs = NULL;
+PyTypeObject *PyGObject_MetaType = NULL;
+
/**
* pygobject_sink:
* @obj: a GObject
@@ -514,7 +516,7 @@ pygobject_register_class(PyObject *dict, const gchar *type_name,
} else
bases = runtime_bases;
- type->ob_type = &PyGObject_MetaType;
+ type->ob_type = PyGObject_MetaType;
type->tp_bases = bases;
if (G_LIKELY(bases)) {
type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0);
@@ -1726,91 +1728,3 @@ PyTypeObject PyGObject_Type = {
};
-static int
-pygobjectmeta_register(PyTypeObject *subtype)
-{
- PyObject *pytype_name;
- const char *type_name = NULL;
- int retval = 0;
-
- /* Maybe the type doesn't really need to registered? */
- if (subtype->tp_dict == NULL)
- goto out;
-
- if (!(PyDict_GetItemString(subtype->tp_dict, "__gtype_name__")
- || PyDict_GetItemString(subtype->tp_dict, "__gproperties__")
- || PyDict_GetItemString(subtype->tp_dict, "__gsignals__")))
- goto out;
-
- /* If it's already registered, skip registration */
- if (PyDict_GetItemString(subtype->tp_dict, "__gtype__"))
- goto out;
-
- pytype_name = PyDict_GetItemString(subtype->tp_dict, "__gtype_name__");
- if (pytype_name)
- type_name = PyString_AsString(pytype_name);
- retval = pyg_type_register(subtype, type_name);
-
-out:
- return retval;
-}
-
-/* -------- GObject MetaClass -----------*/
-static int
-pygobjectmeta_init(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
-{
- if (PyType_Type.tp_init((PyObject *) subtype, args, kwargs))
- return -1;
-
- return pygobjectmeta_register(subtype);
-}
-
-
-PyTypeObject PyGObject_MetaType = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "gobject.GObjectMeta", /* tp_name */
- 0, /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- (destructor)0, /* tp_dealloc */
- (printfunc)0, /* tp_print */
- (getattrfunc)0, /* tp_getattr */
- (setattrfunc)0, /* tp_setattr */
- (cmpfunc)0, /* tp_compare */
- (reprfunc)0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- (hashfunc)0, /* tp_hash */
- (ternaryfunc)0, /* tp_call */
- (reprfunc)0, /* tp_str */
- (getattrofunc)0, /* tp_getattro */
- (setattrofunc)0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_BASETYPE, /* tp_flags */
- "GObject Metaclass -- automatically registers GObject subclasses "
- "as new GType's", /* Documentation string */
- (traverseproc)0, /* tp_traverse */
- (inquiry)0, /* tp_clear */
- (richcmpfunc)0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- (getiterfunc)0, /* tp_iter */
- (iternextfunc)0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- NULL, /* tp_base */
- (PyObject *)0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)pygobjectmeta_init, /* tp_init */
- (allocfunc)0, /* tp_alloc */
- (newfunc)0, /* tp_new */
- 0, /* tp_free */
- (inquiry)0, /* tp_is_gc */
- NULL, /* tp_bases */
-};
-
-