diff options
author | Gustavo J. A. M. Carneiro <gjc@src.gnome.org> | 2006-04-11 21:51:06 +0000 |
---|---|---|
committer | Gustavo J. A. M. Carneiro <gjc@src.gnome.org> | 2006-04-11 21:51:06 +0000 |
commit | 921eb7103fce05bb55aaadc0bcd3527781a1b229 (patch) | |
tree | 34e9d19e16167878c437ef27632c27d7d35508eb /gobject | |
parent | 2b30a70e7b7d2111910ebbf76750bdefe51381ff (diff) | |
download | pygobject-921eb7103fce05bb55aaadc0bcd3527781a1b229.tar.gz |
Move GObjectMeta from C to python-land
Diffstat (limited to 'gobject')
-rw-r--r-- | gobject/__init__.py | 18 | ||||
-rw-r--r-- | gobject/gobjectmodule.c | 23 | ||||
-rw-r--r-- | gobject/pygobject-private.h | 2 | ||||
-rw-r--r-- | gobject/pygobject.c | 92 |
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 */ -}; - - |