Your change to generate.py won't actually help here. gtk_ctree_node_nth returns a GtkCTreeNode, which is not a GtkObject. The code that makes the wrapper for GtkCTreeNode is in the boxed type code generator. I've made some changes to generate.py that allow you to specify a null-ok flag for define-func. It generates the wrapping code for string, boxed, and GtkObject types to check for NULL and return None if NULL. So: (define-func gtk_ctree_node_nth GtkCTreeNode ((GtkCTree ctree) (uint row))) becomes: (define-func gtk_ctree_node_nth (GtkCTreeNode null-ok) ((GtkCTree ctree) (uint row))) Now, I know the notation isn't quite right. But it's the best I could come up with. I had run into this problem when wrapping gnome-util.h functions last week, so I added a string_or_null type. That was a quick hack. This, I think is much better, as it handles the various boxed types, GtkObject, and string all the same. Attached is a diff from CVS HEAD. James, if this looks OK to you, I'll go ahead and commit it. Matt
Index: pygnome/generate/gnome.defs =================================================================== RCS file: /cvs/gnome/gnome-python/pygnome/generate/gnome.defs,v retrieving revision 1.5 diff -u -r1.5 gnome.defs --- pygnome/generate/gnome.defs 1999/12/13 03:11:16 1.5 +++ pygnome/generate/gnome.defs 1999/12/17 04:09:39 @@ -259,42 +259,42 @@ ;; gnome-util.h (define-func gnome_libdir_file - string_or_null + (string null-ok) ((string filename))) (define-func gnome_datadir_file - string_or_null + (string null-ok) ((string filename))) (define-func gnome_sound_file - string_or_null + (string null-ok) ((string filename))) (define-func gnome_pixmap_file - string_or_null + (string null-ok) ((string filename))) (define-func gnome_config_file - string_or_null + (string null-ok) ((string filename))) (define-func gnome_unconditional_libdir_file - string_or_null + (string null-ok) ((string filename))) (define-func gnome_unconditional_datadir_file - string_or_null + (string null-ok) ((string filename))) (define-func gnome_unconditional_sound_file - string_or_null + (string null-ok) ((string filename))) (define-func gnome_unconditional_pixmap_file - string_or_null + (string null-ok) ((string filename))) (define-func gnome_unconditional_config_file - string_or_null + (string null-ok) ((string filename))) Index: pygtk/generate/generate.py =================================================================== RCS file: /cvs/gnome/gnome-python/pygtk/generate/generate.py,v retrieving revision 1.3 diff -u -r1.3 generate.py --- pygtk/generate/generate.py 1999/12/13 03:11:18 1.3 +++ pygtk/generate/generate.py 1999/12/17 04:09:39 @@ -224,7 +224,11 @@ parseList = [] # args to PyArg_ParseTuple argList = [] # args to actual function extraCode = [] # any extra code (for enums, flags) - if retType == 'string' or retType == 'string_or_null': + retArgs = None + if type(retType) == type(()): + retArgs = retType[1:] + retType = retType[0] + if retType == 'string': # this is needed so we can free result string varDefs.add('char', '*ret') varDefs.add('PyObject', '*py_ret') @@ -381,14 +385,22 @@ impl.write(string.join(extraCode, '')) funcCall = name + '(' + string.join(argList, ', ') + ')' - if self.decodeRet(impl, funcCall, retType): + if self.decodeRet(impl, funcCall, retType, retArgs): return impl.write('}\n\n') # actually write the info to the output files self.defs.write(funcDefTmpl % (name,name)) self.impl.write(impl.getvalue()) - def decodeRet(self, impl, funcCall, retType): + def decodeRet(self, impl, funcCall, retType, retArgs=None): + nullok = FALSE + if retArgs: + # XXX fix me + if retArgs[0] == 'null-ok': + nullok = TRUE + else: + print "unknown return attribute '%s'" % (retArgs,) + return 1 if retType == 'none': impl.write(' ') impl.write(funcCall) @@ -398,13 +410,21 @@ impl.write(funcCall) impl.write(');\n') elif retType == 'string': - impl.write(' ret = ') - impl.write(funcCall) - impl.write(';\n py_ret = PyString_FromString(ret);\n g_free(ret);\n return py_ret;\n') - elif retType == 'string_or_null': - impl.write(' ret = ') - impl.write(funcCall) - impl.write(';\n if (ret) {\n py_ret = PyString_FromString(ret);\n g_free(ret);\n return py_ret;\n } else {\n Py_INCREF(Py_None);\n return Py_None;\n }\n') + if nullok: + impl.write(' ret = %s;\n' % funcCall) + impl.write(' if (ret) {\n') + impl.write(' py_ret = +PyString_FromString(ret);\n' + ' g_free(ret);\n' + ' return py_ret;\n' + ' } else {\n' + ' Py_INCREF(Py_None);\n' + ' return Py_None;\n' + ' }\n') + else: + impl.write(' ret = %s;\n' % funcCall) + impl.write(' py_ret = PyString_FromString(ret);\n' + ' g_free(ret);\n' + ' return py_ret;\n') elif retType in ('char', 'uchar'): impl.write(' return PyString_fromStringAndSize(*(') impl.write(funcCall) @@ -419,17 +439,35 @@ impl.write(funcCall) impl.write(');\n') elif retType in boxed.keys(): - impl.write(' return ') - impl.write(boxed[retType][2]) - impl.write('(') - impl.write(funcCall) - impl.write(');\n') + if nullok: + impl.write(' {\n' + ' %s *p = %s;\n' % (retType, +funcCall)) + impl.write(' if (p)\n') + impl.write(' return %s(p);\n' % +boxed[retType][2]) + impl.write(' else {\n' + ' Py_INCREF(Py_None);\n' + ' return Py_None;\n' + ' }\n' + ' }\n') + else: + impl.write(' return ') + impl.write(boxed[retType][2]) + impl.write('(') + impl.write(funcCall) + impl.write(');\n') elif retType in objects.keys(): - impl.write(' return PyGtk_New((GtkObject *)') - impl.write(funcCall) - impl.write(');\n') + if nullok: + impl.write(' GtkObject *p = %s;' % funcCall) + impl.write(' if (p)\n' + ' return PyGtk_New((GtkObject *) +p);\n') + impl.write(' Py_INCREF(Py_None);\n' + ' return Py_None;\n') + + else: + impl.write(' return PyGtk_New((GtkObject *)') + impl.write(funcCall) + impl.write(');\n') else: - print "%s: unknown return type '%s'" % (name, retType) + print "unknown return type '%s'" % (retType,) return 1 return 0 Index: pygtk/generate/gtklists.defs =================================================================== RCS file: /cvs/gnome/gnome-python/pygtk/generate/gtklists.defs,v retrieving revision 1.6 diff -u -r1.6 gtklists.defs --- pygtk/generate/gtklists.defs 1999/12/15 23:33:51 1.6 +++ pygtk/generate/gtklists.defs 1999/12/17 04:09:39 @@ -648,7 +648,7 @@ ;gtk_ctree_find_node_ptr (define-func gtk_ctree_node_nth - GtkCTreeNode + (GtkCTreeNode null-ok) ((GtkCTree ctree) (uint row)))