summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Henstridge <james@daa.com.au>2001-06-22 12:37:52 +0000
committerJames Henstridge <jamesh@src.gnome.org>2001-06-22 12:37:52 +0000
commit9b322a660e816c67109ac6246afd774b799b3a9d (patch)
treea4d90f6c5b544abb779ae7e126af06b603c5a930
parent4518d3615b7e13ec4790b383ee8ce725adf327dd (diff)
new arg type for GType and GtkType args that uses pyg_type_from_object.
2001-06-22 James Henstridge <james@daa.com.au> * codegen/argtypes.py (GTypeArg.write_param): new arg type for GType and GtkType args that uses pyg_type_from_object. * gobjectmodule.c (pyg_type_from_object): new function to get a type code from various types of python objects (currently, integer like objects, strings and other objects that have a __gtype__ attribute). (pygobject__init__): use pyg_type_from_object to get the object type. (pyg_signal_new): same here. 2001-06-21 James Henstridge <james@daa.com.au> * gobjectmodule.c (pyg_boxed_getattro): allow getattr to work on PyGBoxed types (while not overloading tp_getattr). We fall back to tp_getattr if provided by the boxed type. (pyg_register_boxed): make sure tp_getattro is set correctly. * gtk/gtk-types.c (_pygtk_register_boxed_types): convert GtkAccelGroup to a PyGBoxed type.
-rw-r--r--gobject/gobjectmodule.c127
-rw-r--r--gobject/pygobject.h4
2 files changed, 83 insertions, 48 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index 861a03c..9e71563 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -307,6 +307,26 @@ pyg_boxed_repr(PyGBoxed *self)
}
static PyObject *
+pyg_boxed_getattro(PyGBoxed *self, PyObject *attro)
+{
+ char *attr;
+ PyObject *ret;
+
+ attr = PyString_AsString(attro);
+
+ ret = Py_FindAttrString((PyObject *)self, attr);
+ if (ret)
+ return ret;
+ PyErr_Clear();
+
+ if (self->ob_type->tp_getattr)
+ return (* self->ob_type->tp_getattr)((PyObject *)self, attr);
+
+ PyErr_SetString(PyExc_AttributeError, attr);
+ return NULL;
+}
+
+static PyObject *
pyg_boxed__class_init__(PyObject *self, PyObject *args)
{
PyExtensionClass *subclass;
@@ -361,7 +381,7 @@ static PyExtensionClass PyGBoxed_Type = {
(hashfunc)pyg_boxed_hash, /* tp_hash */
(ternaryfunc)0, /* tp_call */
(reprfunc)0, /* tp_str */
- (getattrofunc)0, /* tp_getattro */
+ (getattrofunc)pyg_boxed_getattro, /* tp_getattro */
(setattrofunc)0, /* tp_setattro */
/* Space for future expansion */
0L, 0L,
@@ -386,10 +406,11 @@ pyg_register_boxed(PyObject *dict, const gchar *class_name,
if (!boxed_types)
boxed_types = g_hash_table_new(g_direct_hash, g_direct_equal);
- if (!ec->tp_dealloc) ec->tp_dealloc = (destructor)pyg_boxed_dealloc;
- if (!ec->tp_compare) ec->tp_compare = (cmpfunc)pyg_boxed_compare;
- if (!ec->tp_hash) ec->tp_hash = (hashfunc)pyg_boxed_hash;
- if (!ec->tp_repr) ec->tp_repr = (reprfunc)pyg_boxed_repr;
+ if (!ec->tp_dealloc) ec->tp_dealloc = (destructor)pyg_boxed_dealloc;
+ if (!ec->tp_compare) ec->tp_compare = (cmpfunc)pyg_boxed_compare;
+ if (!ec->tp_hash) ec->tp_hash = (hashfunc)pyg_boxed_hash;
+ if (!ec->tp_repr) ec->tp_repr = (reprfunc)pyg_boxed_repr;
+ if (!ec->tp_getattro) ec->tp_getattro = (getattrofunc)pyg_boxed_getattro;
PyExtensionClass_ExportSubclassSingle(dict, (char *)class_name, *ec,
PyGBoxed_Type);
@@ -523,6 +544,52 @@ pyg_flags_get_value(GType flag_type, PyObject *obj, gint *val)
return res;
}
+static GType
+pyg_type_from_object(PyObject *obj)
+{
+ PyObject *gtype;
+ GType type;
+
+ /* NULL check */
+ if (!obj) {
+ PyErr_SetString(PyExc_TypeError, "can't get type from NULL object");
+ return 0;
+ }
+
+ /* handle int like objects */
+ type = (GType) PyInt_AsLong(obj);
+ if (!PyErr_Occurred() && type != 0)
+ return type;
+ PyErr_Clear();
+
+ /* handle strings */
+ if (PyString_Check(obj)) {
+ type = g_type_from_name(PyString_AsString(obj));
+ if (type == 0)
+ PyErr_SetString(PyExc_TypeError, "could not find named typecode");
+ return type;
+ }
+
+ /* finally, look for a __gtype__ attribute on the object */
+ gtype = PyObject_GetAttrString(obj, "__gtype__");
+ if (!gtype) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError, "could not get typecode from object");
+ return 0;
+ }
+ type = (GType) PyInt_AsLong(gtype);
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ Py_DECREF(gtype);
+ PyErr_SetString(PyExc_TypeError, "could not get typecode from object");
+ return 0;
+ }
+ Py_DECREF(gtype);
+ if (type == 0)
+ PyErr_SetString(PyExc_TypeError, "could not get typecode from object");
+ return type;
+}
+
typedef PyObject *(* fromvaluefunc)(const GValue *value);
typedef int (*tovaluefunc)(GValue *value, PyObject *obj);
typedef struct {
@@ -1085,28 +1152,15 @@ pygobject__class_init__(PyObject *something, PyObject *args)
static PyObject *
pygobject__init__(PyGObject *self, PyObject *args)
{
- PyObject *gtype;
GType object_type;
if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
return NULL;
- gtype = PyObject_GetAttrString((PyObject *)self, "__gtype__");
- if (!gtype) {
- PyErr_Clear();
- PyErr_SetString(PyExc_TypeError,
- "required __gtype__ attribute missing");
- return NULL;
- }
- object_type = (GType) PyInt_AsLong(gtype);
- if (PyErr_Occurred()) {
- PyErr_Clear();
- Py_DECREF(gtype);
- PyErr_SetString(PyExc_TypeError,
- "__gtype__ attribute not an integer");
+ object_type = pyg_type_from_object((PyObject *)self);
+ if (!object_type)
return NULL;
- }
- Py_DECREF(gtype);
+
self->obj = g_object_new(object_type, NULL);
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create object");
@@ -1855,33 +1909,9 @@ pyg_signal_new(PyObject *self, PyObject *args)
&py_type, &signal_flags, &return_type,
&py_param_types))
return NULL;
- if (ExtensionClassSubclass_Check(py_type, &PyGObject_Type)) {
- PyObject *gtype = PyObject_GetAttrString(py_type, "__gtype__");
-
- if (!gtype) {
- PyErr_Clear();
- PyErr_SetString(PyExc_TypeError,
- "argument 2 must be a GObject or a GType code");
- return NULL;
- }
- instance_type = (GType) PyInt_AsLong(gtype);
- if (PyErr_Occurred()) {
- PyErr_Clear();
- Py_DECREF(gtype);
- PyErr_SetString(PyExc_TypeError,
- "argument 2 must be a GObject or a GType code");
- return NULL;
- }
- Py_DECREF(gtype);
- } else {
- instance_type = (GType)PyInt_AsLong(py_type);
- if (PyErr_Occurred()) {
- PyErr_Clear();
- PyErr_SetString(PyExc_TypeError,
- "argument 2 must be a GObject or a GType code");
- return NULL;
- }
- }
+ instance_type = pyg_type_from_object(py_type);
+ if (!instance_type)
+ return NULL;
if (!PySequence_Check(py_param_types)) {
PyErr_SetString(PyExc_TypeError,
"argument 5 must be a sequence of GType codes");
@@ -1935,6 +1965,7 @@ static struct _PyGObject_Functions functions = {
pygobject_register_wrapper,
pygobject_lookup_class,
pygobject_new,
+ pyg_type_from_object,
pyg_enum_get_value,
pyg_flags_get_value,
pyg_boxed_register,
diff --git a/gobject/pygobject.h b/gobject/pygobject.h
index f2d15fe..271ba4d 100644
--- a/gobject/pygobject.h
+++ b/gobject/pygobject.h
@@ -35,6 +35,7 @@ struct _PyGObject_Functions {
void (* register_wrapper)(PyObject *self);
PyExtensionClass *(* lookup_class)(GType type);
PyObject *(* new)(GObject *obj);
+ GType (* type_from_object)(PyObject *obj);
gint (* enum_get_value)(GType enum_type, PyObject *obj, gint *val);
gint (* flags_get_value)(GType flag_type, PyObject *obj, gint *val);
void (* boxed_register)(GType boxed_type,
@@ -64,12 +65,15 @@ struct _PyGObject_Functions *_PyGObject_API;
#define pygobject_register_wrapper (_PyGObject_API->register_wrapper)
#define pygobject_lookup_class (_PyGObject_API->lookup_class)
#define pygobject_new (_PyGObject_API->new)
+#define pyg_type_from_object (_PyGObject_API->type_from_object)
#define pyg_enum_get_value (_PyGObject_API->enum_get_value)
#define pyg_flags_get_value (_PyGObject_API->flags_get_value)
#define pyg_boxed_register (_PyGObject_API->boxed_register)
#define pyg_value_from_pyobject (_PyGObject_API->value_from_pyobject)
#define pyg_value_as_pyobject (_PyGObject_API->value_as_pyobject)
#define pyg_register_interface (_PyGObject_API->register_interface)
+#define pyg_register_boxed (_PyGObject_API->register_boxed)
+#define pyg_boxed_new (_PyGObject_API->boxed_new)
#define init_pygobject() { \
PyObject *gobject = PyImport_ImportModule("gobject"); \