[pygobject/py3k: 19/20] Python 3 support for setup.py



commit 27e7665c4805eab2f4d97b99436e471cf7ba945c
Author: John Ehresman <jpe wingware com>
Date:   Thu Apr 15 12:57:22 2010 -0400

    Python 3 support for setup.py

 codegen/__init__.py                        |   16 -
 codegen/code-coverage.py                   |    2 +-
 codegen/codegen.py                         | 1722 +---------------------------
 codegen/defsconvert.py                     |    4 +-
 codegen/defsgen.py                         |    4 +-
 codegen/defsparser.py                      |  154 +---
 codegen/docextract.py                      |  448 --------
 codegen/docextract_to_xml.py               |  101 +--
 codegen/libcodegen/__init__.py             |   16 +
 codegen/{ => libcodegen}/argtypes.py       |   53 +-
 codegen/libcodegen/codegen.py              | 1722 ++++++++++++++++++++++++++++
 codegen/{ => libcodegen}/definitions.py    |   16 +-
 codegen/libcodegen/defsparser.py           |  153 +++
 codegen/libcodegen/docextract.py           |  185 +++
 codegen/libcodegen/override.py             |  285 +++++
 codegen/{ => libcodegen}/reversewrapper.py |   10 +-
 codegen/libcodegen/scmexpr.py              |  147 +++
 codegen/override.py                        |  286 +-----
 codegen/scmexpr.py                         |  146 +---
 dsextras.py                                |   24 +-
 setup.py                                   |   41 +-
 21 files changed, 2626 insertions(+), 2909 deletions(-)
---
diff --git a/codegen/__init__.py b/codegen/__init__.py
index 86188f9..e69de29 100644
--- a/codegen/__init__.py
+++ b/codegen/__init__.py
@@ -1,16 +0,0 @@
-# -*- Mode: Python; py-indent-offset: 4 -*-
-
-__all__ = [
-    'argtypes',
-    'codegen',
-    'definitions',
-    'defsparser',
-    'docextract',
-    'docgen',
-    'h2def',
-    'defsgen'
-    'mergedefs',
-    'mkskel',
-    'override',
-    'scmexpr'
-]
diff --git a/codegen/code-coverage.py b/codegen/code-coverage.py
index 1dc54c3..5d192b3 100755
--- a/codegen/code-coverage.py
+++ b/codegen/code-coverage.py
@@ -38,7 +38,7 @@ def main():
     for symbol in read_symbols(library, type='T', dynamic=1):
         if symbol[0] == '_': continue
         if symbol not in wrapper_symbols:
-            print symbol
+            print(symbol)
 
 if __name__ == '__main__':
     main()
diff --git a/codegen/codegen.py b/codegen/codegen.py
old mode 100755
new mode 100644
index aef93ae..6486fb7
--- a/codegen/codegen.py
+++ b/codegen/codegen.py
@@ -1,1719 +1,11 @@
 #! /usr/bin/env python
 
-import getopt
-import keyword
-import os
-import string
-import sys
-
-import argtypes
-import definitions
-import defsparser
-import override
-import reversewrapper
-import warnings
-
-class Coverage(object):
-    def __init__(self, name):
-        self.name = name
-        self.wrapped = 0
-        self.not_wrapped = 0
-
-    def declare_wrapped(self):
-        self.wrapped += 1
-
-    def declare_not_wrapped(self):
-        self.not_wrapped += 1
-
-    def printstats(self):
-        total = self.wrapped + self.not_wrapped
-        fd = sys.stderr
-        if total:
-            fd.write("***INFO*** The coverage of %s is %.2f%% (%i/%i)\n" %
-                     (self.name,
-                      float(self.wrapped*100)/total,
-                      self.wrapped,
-                      total))
-        else:
-            fd.write("***INFO*** There are no declared %s.\n" % self.name)
-
-functions_coverage = Coverage("global functions")
-methods_coverage = Coverage("methods")
-vproxies_coverage = Coverage("virtual proxies")
-vaccessors_coverage = Coverage("virtual accessors")
-iproxies_coverage = Coverage("interface proxies")
-
-def exc_info():
-    warnings.warn("deprecated", DeprecationWarning, stacklevel=2)
-    #traceback.print_exc()
-    etype, value, tb = sys.exc_info()
-    ret = ""
-    try:
-        sval = str(value)
-        if etype == argtypes.ArgTypeError:
-            ret = "No ArgType for %s" % (sval,)
-        else:
-            ret = sval
-    finally:
-        del etype, value, tb
-    return ret
-
-def fixname(name):
-    if keyword.iskeyword(name):
-        return name + '_'
-    return name
-
-class FileOutput:
-    '''Simple wrapper for file object, that makes writing #line
-    statements easier.''' # "
-    def __init__(self, fp, filename=None):
-        self.fp = fp
-        self.lineno = 1
-        if filename:
-            self.filename = filename
-        else:
-            self.filename = self.fp.name
-    # handle writing to the file, and keep track of the line number ...
-    def write(self, str):
-        self.fp.write(str)
-        self.lineno = self.lineno + str.count('\n')
-    def writelines(self, sequence):
-        for line in sequence:
-            self.write(line)
-    def close(self):
-        self.fp.close()
-    def flush(self):
-        self.fp.flush()
-
-    def setline(self, linenum, filename):
-        '''writes out a #line statement, for use by the C
-        preprocessor.''' # "
-        self.write('#line %d "%s"\n' % (linenum, filename))
-    def resetline(self):
-        '''resets line numbering to the original file'''
-        self.setline(self.lineno + 1, self.filename)
-
-class Wrapper:
-    type_tmpl = (
-        'PyTypeObject G_GNUC_INTERNAL Py%(typename)s_Type = {\n'
-        '    PyVarObject_HEAD_INIT(NULL, 0)\n'
-        '    "%(classname)s",                   /* tp_name */\n'
-        '    sizeof(%(tp_basicsize)s),          /* tp_basicsize */\n'
-        '    0,                                 /* tp_itemsize */\n'
-        '    /* methods */\n'
-        '    (destructor)%(tp_dealloc)s,        /* tp_dealloc */\n'
-        '    (printfunc)0,                      /* tp_print */\n'
-        '    (getattrfunc)%(tp_getattr)s,       /* tp_getattr */\n'
-        '    (setattrfunc)%(tp_setattr)s,       /* tp_setattr */\n'
-        '    NULL, //%(tp_compare)s,                    /* tp_compare */\n'
-        '    (reprfunc)%(tp_repr)s,             /* tp_repr */\n'
-        '    (PyNumberMethods*)%(tp_as_number)s,     /* tp_as_number */\n'
-        '    (PySequenceMethods*)%(tp_as_sequence)s, /* tp_as_sequence */\n'
-        '    (PyMappingMethods*)%(tp_as_mapping)s,   /* tp_as_mapping */\n'
-        '    (hashfunc)%(tp_hash)s,             /* tp_hash */\n'
-        '    (ternaryfunc)%(tp_call)s,          /* tp_call */\n'
-        '    (reprfunc)%(tp_str)s,              /* tp_str */\n'
-        '    (getattrofunc)%(tp_getattro)s,     /* tp_getattro */\n'
-        '    (setattrofunc)%(tp_setattro)s,     /* tp_setattro */\n'
-        '    (PyBufferProcs*)%(tp_as_buffer)s,  /* tp_as_buffer */\n'
-        '    %(tp_flags)s,                      /* tp_flags */\n'
-        '    %(tp_doc)s,                        /* Documentation string */\n'
-        '    (traverseproc)%(tp_traverse)s,     /* tp_traverse */\n'
-        '    (inquiry)%(tp_clear)s,             /* tp_clear */\n'
-        '    (richcmpfunc)%(tp_richcompare)s,   /* tp_richcompare */\n'
-        '    %(tp_weaklistoffset)s,             /* tp_weaklistoffset */\n'
-        '    (getiterfunc)%(tp_iter)s,          /* tp_iter */\n'
-        '    (iternextfunc)%(tp_iternext)s,     /* tp_iternext */\n'
-        '    (struct PyMethodDef*)%(tp_methods)s, /* tp_methods */\n'
-        '    (struct PyMemberDef*)0,              /* tp_members */\n'
-        '    (struct PyGetSetDef*)%(tp_getset)s,  /* tp_getset */\n'
-        '    NULL,                              /* tp_base */\n'
-        '    NULL,                              /* tp_dict */\n'
-        '    (descrgetfunc)%(tp_descr_get)s,    /* tp_descr_get */\n'
-        '    (descrsetfunc)%(tp_descr_set)s,    /* tp_descr_set */\n'
-        '    %(tp_dictoffset)s,                 /* tp_dictoffset */\n'
-        '    (initproc)%(tp_init)s,             /* tp_init */\n'
-        '    (allocfunc)%(tp_alloc)s,           /* tp_alloc */\n'
-        '    (newfunc)%(tp_new)s,               /* tp_new */\n'
-        '    (freefunc)%(tp_free)s,             /* tp_free */\n'
-        '    (inquiry)%(tp_is_gc)s              /* tp_is_gc */\n'
-        '};\n\n'
-        )
-
-    slots_list = [
-        'tp_getattr', 'tp_setattr', 'tp_getattro', 'tp_setattro',
-        'tp_compare', 'tp_repr',
-        'tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'tp_hash',
-        'tp_call', 'tp_str', 'tp_as_buffer', 'tp_richcompare', 'tp_iter',
-        'tp_iternext', 'tp_descr_get', 'tp_descr_set', 'tp_init',
-        'tp_alloc', 'tp_new', 'tp_free', 'tp_is_gc',
-        'tp_traverse', 'tp_clear', 'tp_dealloc', 'tp_flags', 'tp_doc'
-        ]
-
-    getter_tmpl = (
-        'static PyObject *\n'
-        '%(funcname)s(PyObject *self, void *closure)\n'
-        '{\n'
-        '%(varlist)s'
-        '    ret = %(field)s;\n'
-        '%(codeafter)s\n'
-        '}\n\n'
-        )
-
-    parse_tmpl = (
-        '    if (!PyArg_ParseTupleAndKeywords(args, kwargs,'
-        '"%(typecodes)s:%(name)s"%(parselist)s))\n'
-        '        return %(errorreturn)s;\n'
-        )
-
-    deprecated_tmpl = (
-        '    if (PyErr_Warn(PyExc_DeprecationWarning, '
-        '"%(deprecationmsg)s") < 0)\n'
-        '        return %(errorreturn)s;\n'
-        )
-
-    methdef_tmpl = (
-        '    { "%(name)s", (PyCFunction)%(cname)s, %(flags)s,\n'
-        '      %(docstring)s },\n'
-        )
-
-    noconstructor = (
-        'static int\n'
-        'pygobject_no_constructor(PyObject *self, PyObject *args, '
-        'PyObject *kwargs)\n'
-        '{\n'
-        '    gchar buf[512];\n'
-        '\n'
-        '    g_snprintf(buf, sizeof(buf), "%s is an abstract widget", '
-        'self->ob_type->tp_name);\n'
-        '    PyErr_SetString(PyExc_NotImplementedError, buf);\n'
-        '    return -1;\n'
-        '}\n\n'
-        )
-
-    function_tmpl = (
-        'static PyObject *\n'
-        '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
-        '{\n'
-        '%(varlist)s'
-        '%(parseargs)s'
-        '%(codebefore)s'
-        '    %(begin_allow_threads)s\n'
-        '    %(setreturn)s%(cname)s(%(arglist)s);\n'
-        '    %(end_allow_threads)s\n'
-        '%(codeafter)s\n'
-        '}\n\n'
-        )
-
-    virtual_accessor_tmpl = (
-        'static PyObject *\n'
-        '_wrap_%(cname)s(PyObject *cls%(extraparams)s)\n'
-        '{\n'
-        '    gpointer klass;\n'
-        '%(varlist)s'
-        '%(parseargs)s'
-        '%(codebefore)s'
-        '    klass = g_type_class_ref(pyg_type_from_object(cls));\n'
-        '    if (%(class_cast_macro)s(klass)->%(virtual)s)\n'
-        '        %(setreturn)s%(class_cast_macro)s(klass)->'
-        '%(virtual)s(%(arglist)s);\n'
-        '    else {\n'
-        '        PyErr_SetString(PyExc_NotImplementedError, '
-        '"virtual method %(name)s not implemented");\n'
-        '        g_type_class_unref(klass);\n'
-        '        return NULL;\n'
-        '    }\n'
-        '    g_type_class_unref(klass);\n'
-        '%(codeafter)s\n'
-        '}\n\n'
-        )
-
-    # template for method calls
-    constructor_tmpl = None
-    method_tmpl = None
-
-    def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)):
-        self.parser = parser
-        self.objinfo = objinfo
-        self.overrides = overrides
-        self.fp = fp
-
-    def get_lower_name(self):
-        return string.lower(string.replace(self.objinfo.typecode,
-                                           '_TYPE_', '_', 1))
-
-    def get_field_accessor(self, fieldname):
-        raise NotImplementedError
-
-    def get_initial_class_substdict(self): return {}
-
-    def get_initial_constructor_substdict(self, constructor):
-        return { 'name': '%s.__init__' % self.objinfo.py_name,
-                 'errorreturn': '-1' }
-
-    def get_initial_method_substdict(self, method):
-        substdict = { 'name': '%s.%s' % (self.objinfo.py_name, method.name) }
-        if method.unblock_threads:
-            substdict['begin_allow_threads'] = 'pyg_begin_allow_threads;'
-            substdict['end_allow_threads'] = 'pyg_end_allow_threads;'
-        else:
-            substdict['begin_allow_threads'] = ''
-            substdict['end_allow_threads'] = ''
-        return substdict
-
-    def write_class(self):
-        if self.overrides.is_type_ignored(self.objinfo.c_name):
-            return
-        self.fp.write('\n/* ----------- %s ----------- */\n\n' %
-                      self.objinfo.c_name)
-        substdict = self.get_initial_class_substdict()
-        if not substdict.has_key('tp_flags'):
-            substdict['tp_flags'] = 'Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE'
-        substdict['typename'] = self.objinfo.c_name
-        if self.overrides.modulename:
-            substdict['classname'] = '%s.%s' % (self.overrides.modulename,
-                                           self.objinfo.name)
-        else:
-            substdict['classname'] = self.objinfo.name
-        substdict['tp_doc'] = self.objinfo.docstring
-
-        # Maybe this could be done in a nicer way, but I'll leave it as it is
-        # for now: -- Johan
-        if not self.overrides.slot_is_overriden('%s.tp_init' %
-                                                self.objinfo.c_name):
-            substdict['tp_init'] = self.write_constructor()
-        substdict['tp_methods'] = self.write_methods()
-        substdict['tp_getset'] = self.write_getsets()
-
-        # handle slots ...
-        for slot in self.slots_list:
-
-            slotname = '%s.%s' % (self.objinfo.c_name, slot)
-            slotfunc = '_wrap_%s_%s' % (self.get_lower_name(), slot)
-            if slot[:6] == 'tp_as_':
-                slotfunc = '&' + slotfunc
-            if self.overrides.slot_is_overriden(slotname):
-                data = self.overrides.slot_override(slotname)
-                self.write_function(slotname, data)
-                substdict[slot] = slotfunc
-            else:
-                if not substdict.has_key(slot):
-                    substdict[slot] = '0'
-
-        self.fp.write(self.type_tmpl % substdict)
-
-        self.write_virtuals()
-
-    def write_function_wrapper(self, function_obj, template,
-                               handle_return=0, is_method=0, kwargs_needed=0,
-                               substdict=None):
-        '''This function is the guts of all functions that generate
-        wrappers for functions, methods and constructors.'''
-        if not substdict: substdict = {}
-
-        info = argtypes.WrapperInfo()
-
-        substdict.setdefault('errorreturn', 'NULL')
-
-        # for methods, we want the leading comma
-        if is_method:
-            info.arglist.append('')
-
-        if function_obj.varargs:
-            raise argtypes.ArgTypeNotFoundError("varargs functions not supported")
-
-        for param in function_obj.params:
-            if param.pdflt != None and '|' not in info.parsestr:
-                info.add_parselist('|', [], [])
-            handler = argtypes.matcher.get(param.ptype)
-            handler.write_param(param.ptype, param.pname, param.pdflt,
-                                param.pnull, info)
-
-        substdict['setreturn'] = ''
-        if handle_return:
-            if function_obj.ret not in ('none', None):
-                substdict['setreturn'] = 'ret = '
-            handler = argtypes.matcher.get(function_obj.ret)
-            handler.write_return(function_obj.ret,
-                                 function_obj.caller_owns_return, info)
-
-        if function_obj.deprecated != None:
-            deprecated = self.deprecated_tmpl % {
-                'deprecationmsg': function_obj.deprecated,
-                'errorreturn': substdict['errorreturn'] }
-        else:
-            deprecated = ''
-
-        # if name isn't set, set it to function_obj.name
-        substdict.setdefault('name', function_obj.name)
-
-        if function_obj.unblock_threads:
-            substdict['begin_allow_threads'] = 'pyg_begin_allow_threads;'
-            substdict['end_allow_threads'] = 'pyg_end_allow_threads;'
-        else:
-            substdict['begin_allow_threads'] = ''
-            substdict['end_allow_threads'] = ''
-
-        if self.objinfo:
-            substdict['typename'] = self.objinfo.c_name
-        substdict.setdefault('cname',  function_obj.c_name)
-        substdict['varlist'] = info.get_varlist()
-        substdict['typecodes'] = info.parsestr
-        substdict['parselist'] = info.get_parselist()
-        substdict['arglist'] = info.get_arglist()
-        substdict['codebefore'] = deprecated + (
-            string.replace(info.get_codebefore(),
-            'return NULL', 'return ' + substdict['errorreturn'])
-            )
-        substdict['codeafter'] = (
-            string.replace(info.get_codeafter(),
-                           'return NULL',
-                           'return ' + substdict['errorreturn']))
-
-        if info.parsestr or kwargs_needed:
-            substdict['parseargs'] = self.parse_tmpl % substdict
-            substdict['extraparams'] = ', PyObject *args, PyObject *kwargs'
-            flags = 'METH_VARARGS|METH_KEYWORDS'
-
-            # prepend the keyword list to the variable list
-            substdict['varlist'] = info.get_kwlist() + substdict['varlist']
-        else:
-            substdict['parseargs'] = ''
-            substdict['extraparams'] = ''
-            flags = 'METH_NOARGS'
-
-        return template % substdict, flags
-
-    def write_constructor(self):
-        initfunc = '0'
-        constructor = self.parser.find_constructor(self.objinfo,self.overrides)
-        if not constructor:
-            return self.write_default_constructor()
-
-        funcname = constructor.c_name
-        try:
-            if self.overrides.is_overriden(funcname):
-                data = self.overrides.override(funcname)
-                self.write_function(funcname, data)
-                self.objinfo.has_new_constructor_api = (
-                    self.objinfo.typecode in
-                    self.overrides.newstyle_constructors)
-            else:
-                # ok, a hack to determine if we should use
-                # new-style constructores :P
-                property_based = getattr(self,
-                                         'write_property_based_constructor',
-                                         None)
-                if property_based:
-                    if (len(constructor.params) == 0 or
-                        isinstance(constructor.params[0],
-                                   definitions.Property)):
-                        # write_property_based_constructor is only
-                        # implemented in GObjectWrapper
-                        return self.write_property_based_constructor(
-                            constructor)
-                    else:
-                        sys.stderr.write(
-                            "Warning: generating old-style constructor for:" +
-                            constructor.c_name + '\n')
-
-                # write constructor from template ...
-                code = self.write_function_wrapper(constructor,
-                    self.constructor_tmpl,
-                    handle_return=0, is_method=0, kwargs_needed=1,
-                    substdict=self.get_initial_constructor_substdict(
-                    constructor))[0]
-                self.fp.write(code)
-            initfunc = '_wrap_' + funcname
-        except argtypes.ArgTypeError, ex:
-            sys.stderr.write('Could not write constructor for %s: %s\n'
-                             % (self.objinfo.c_name, str(ex)))
-
-            initfunc = self.write_noconstructor()
-        return initfunc
-
-    def write_noconstructor(self):
-        # this is a hack ...
-        if not hasattr(self.overrides, 'no_constructor_written'):
-            self.fp.write(self.noconstructor)
-            self.overrides.no_constructor_written = 1
-        initfunc = 'pygobject_no_constructor'
-        return initfunc
-
-    def write_default_constructor(self):
-        return self.write_noconstructor()
-
-    def get_methflags(self, funcname):
-        if self.overrides.wants_kwargs(funcname):
-            flags = 'METH_VARARGS|METH_KEYWORDS'
-        elif self.overrides.wants_noargs(funcname):
-            flags = 'METH_NOARGS'
-        elif self.overrides.wants_onearg(funcname):
-            flags = 'METH_O'
-        else:
-            flags = 'METH_VARARGS'
-        if self.overrides.is_staticmethod(funcname):
-            flags += '|METH_STATIC'
-        elif self.overrides.is_classmethod(funcname):
-            flags += '|METH_CLASS'
-        return flags
-
-    def write_function(self, funcname, data):
-        lineno, filename = self.overrides.getstartline(funcname)
-        self.fp.setline(lineno, filename)
-        self.fp.write(data)
-        self.fp.resetline()
-        self.fp.write('\n\n')
-
-    def _get_class_virtual_substdict(self, meth, cname, parent):
-        substdict = self.get_initial_method_substdict(meth)
-        substdict['virtual'] = meth.name
-        substdict['cname'] = cname
-        substdict['class_cast_macro'] = parent.typecode.replace(
-            '_TYPE_', '_', 1) + "_CLASS"
-        substdict['typecode'] = self.objinfo.typecode
-        substdict['cast'] = string.replace(parent.typecode, '_TYPE_', '_', 1)
-        return substdict
-
-    def write_methods(self):
-        methods = []
-        klass = self.objinfo.c_name
-        # First, get methods from the defs files
-        for meth in self.parser.find_methods(self.objinfo):
-            method_name = meth.c_name
-            if self.overrides.is_ignored(method_name):
-                continue
-            try:
-                if self.overrides.is_overriden(method_name):
-                    if not self.overrides.is_already_included(method_name):
-                        data = self.overrides.override(method_name)
-                        self.write_function(method_name, data)
-
-                    methflags = self.get_methflags(method_name)
-                else:
-                    # write constructor from template ...
-                    code, methflags = self.write_function_wrapper(meth,
-                        self.method_tmpl, handle_return=1, is_method=1,
-                        substdict=self.get_initial_method_substdict(meth))
-                    self.fp.write(code)
-                methods.append(self.methdef_tmpl %
-                               { 'name':  fixname(meth.name),
-                                 'cname': '_wrap_' + method_name,
-                                 'flags': methflags,
-                                 'docstring': meth.docstring })
-                methods_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
-                methods_coverage.declare_not_wrapped()
-                sys.stderr.write('Could not write method %s.%s: %s\n'
-                                % (klass, meth.name, str(ex)))
-
-        # Now try to see if there are any defined in the override
-        for method_name in self.overrides.get_defines_for(klass):
-            c_name = override.class2cname(klass, method_name)
-            if self.overrides.is_already_included(method_name):
-                continue
-
-            try:
-                data = self.overrides.define(klass, method_name)
-                self.write_function(method_name, data)
-                methflags = self.get_methflags(method_name)
-
-                methods.append(self.methdef_tmpl %
-                               { 'name':  method_name,
-                                 'cname': '_wrap_' + c_name,
-                                 'flags': methflags,
-                                 'docstring': 'NULL' })
-                methods_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
-                methods_coverage.declare_not_wrapped()
-                sys.stderr.write('Could not write method %s.%s: %s\n'
-                                % (klass, method_name, str(ex)))
-
-        # Add GObject virtual method accessors, for chaining to parent
-        # virtuals from subclasses
-        methods += self.write_virtual_accessors()
-
-        if methods:
-            methoddefs = '_Py%s_methods' % self.objinfo.c_name
-            # write the PyMethodDef structure
-            methods.append('    { NULL, NULL, 0, NULL }\n')
-            self.fp.write('static const PyMethodDef %s[] = {\n' % methoddefs)
-            self.fp.write(string.join(methods, ''))
-            self.fp.write('};\n\n')
-        else:
-            methoddefs = 'NULL'
-        return methoddefs
-
-    def write_virtual_accessors(self):
-        klass = self.objinfo.c_name
-        methods = []
-        for meth in self.parser.find_virtuals(self.objinfo):
-            method_name = self.objinfo.c_name + "__do_" + meth.name
-            if self.overrides.is_ignored(method_name):
-                continue
-            try:
-                if self.overrides.is_overriden(method_name):
-                    if not self.overrides.is_already_included(method_name):
-                        data = self.overrides.override(method_name)
-                        self.write_function(method_name, data)
-                    methflags = self.get_methflags(method_name)
-                else:
-                    # temporarily add a 'self' parameter as first argument
-                    meth.params.insert(0, definitions.Parameter(
-                        ptype=(self.objinfo.c_name + '*'),
-                        pname='self', pdflt=None, pnull=None))
-                    try:
-                        # write method from template ...
-                        code, methflags = self.write_function_wrapper(
-                            meth, self.virtual_accessor_tmpl,
-                            handle_return=True, is_method=False,
-                            substdict=self._get_class_virtual_substdict(
-                            meth, method_name, self.objinfo))
-                        self.fp.write(code)
-                    finally:
-                        del meth.params[0]
-                methods.append(self.methdef_tmpl %
-                               { 'name':  "do_" + fixname(meth.name),
-                                 'cname': '_wrap_' + method_name,
-                                 'flags': methflags + '|METH_CLASS',
-                                 'docstring': 'NULL'})
-                vaccessors_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
-                vaccessors_coverage.declare_not_wrapped()
-                sys.stderr.write(
-                    'Could not write virtual accessor method %s.%s: %s\n'
-                    % (klass, meth.name, str(ex)))
-        return methods
-
-    def write_virtuals(self):
-        '''
-        Write _wrap_FooBar__proxy_do_zbr() reverse wrapers for
-        GObject virtuals
-        '''
-        klass = self.objinfo.c_name
-        virtuals = []
-        for meth in self.parser.find_virtuals(self.objinfo):
-            method_name = self.objinfo.c_name + "__proxy_do_" + meth.name
-            if self.overrides.is_ignored(method_name):
-                continue
-            try:
-                if self.overrides.is_overriden(method_name):
-                    if not self.overrides.is_already_included(method_name):
-                        data = self.overrides.override(method_name)
-                        self.write_function(method_name, data)
-                else:
-                    # write virtual proxy ...
-                    ret, props = argtypes.matcher.get_reverse_ret(meth.ret)
-                    wrapper = reversewrapper.ReverseWrapper(
-                        '_wrap_' + method_name, is_static=True)
-                    wrapper.set_return_type(ret(wrapper, **props))
-                    wrapper.add_parameter(reversewrapper.PyGObjectMethodParam(
-                        wrapper, "self", method_name="do_" + meth.name,
-                        c_type=(klass + ' *')))
-                    for param in meth.params:
-                        handler, props = argtypes.matcher.get_reverse(
-                            param.ptype)
-                        props["direction"] = param.pdir
-                        wrapper.add_parameter(handler(wrapper,
-                                                      param.pname, **props))
-                    buf = reversewrapper.MemoryCodeSink()
-                    wrapper.generate(buf)
-                    self.fp.write(buf.flush())
-                virtuals.append((fixname(meth.name), '_wrap_' + method_name))
-                vproxies_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
-                vproxies_coverage.declare_not_wrapped()
-                virtuals.append((fixname(meth.name), None))
-                sys.stderr.write('Could not write virtual proxy %s.%s: %s\n'
-                                % (klass, meth.name, str(ex)))
-        if virtuals:
-            # Write a 'pygtk class init' function for this object,
-            # except when the object type is explicitly ignored (like
-            # GtkPlug and GtkSocket on win32).
-            if self.overrides.is_ignored(self.objinfo.typecode):
-                return
-            class_cast_macro = self.objinfo.typecode.replace(
-                '_TYPE_', '_', 1) + "_CLASS"
-            cast_macro = self.objinfo.typecode.replace('_TYPE_', '_', 1)
-            funcname = "__%s_class_init" % klass
-            self.objinfo.class_init_func = funcname
-            have_implemented_virtuals = not not [True
-                                                 for name, cname in virtuals
-                                                     if cname is not None]
-            self.fp.write(
-            ('\nstatic int\n'
-             '%(funcname)s(gpointer gclass, PyTypeObject *pyclass)\n'
-             '{\n') % vars())
-
-            if have_implemented_virtuals:
-                self.fp.write('    PyObject *o;\n')
-                self.fp.write(
-                    '    %(klass)sClass *klass = '
-                    '%(class_cast_macro)s(gclass);\n'
-                    '    PyObject *gsignals = '
-                    'PyDict_GetItemString(pyclass->tp_dict, "__gsignals__");\n'
-                    % vars())
-
-            for name, cname in virtuals:
-                do_name = 'do_' + name
-                if cname is None:
-                    self.fp.write('\n    /* overriding %(do_name)s '
-                                  'is currently not supported */\n' % vars())
-                else:
-                    self.fp.write('''
-    o = PyObject_GetAttrString((PyObject *) pyclass, "%(do_name)s");
-    if (o == NULL)
-        PyErr_Clear();
-    else {
-        if (!PyObject_TypeCheck(o, &PyCFunction_Type)
-            && !(gsignals && PyDict_GetItemString(gsignals, "%(name)s")))
-            klass->%(name)s = %(cname)s;
-        Py_DECREF(o);
-    }
-''' % vars())
-            self.fp.write('    return 0;\n}\n')
-
-    def write_getsets(self):
-        lower_name = self.get_lower_name()
-        getsets_name = lower_name + '_getsets'
-        getterprefix = '_wrap_' + lower_name + '__get_'
-        setterprefix = '_wrap_' + lower_name + '__set_'
-
-        # no overrides for the whole function.  If no fields,
-        # don't write a func
-        if not self.objinfo.fields:
-            return '0'
-        getsets = []
-        for ftype, cfname in self.objinfo.fields:
-            fname = cfname.replace('.', '_')
-            gettername = '0'
-            settername = '0'
-            attrname = self.objinfo.c_name + '.' + fname
-            if self.overrides.attr_is_overriden(attrname):
-                code = self.overrides.attr_override(attrname)
-                self.write_function(attrname, code)
-                if string.find(code, getterprefix + fname) >= 0:
-                    gettername = getterprefix + fname
-                if string.find(code, setterprefix + fname) >= 0:
-                    settername = setterprefix + fname
-            if gettername == '0':
-                try:
-                    funcname = getterprefix + fname
-                    info = argtypes.WrapperInfo()
-                    handler = argtypes.matcher.get(ftype)
-                    # for attributes, we don't own the "return value"
-                    handler.write_return(ftype, 0, info)
-                    self.fp.write(self.getter_tmpl %
-                                  { 'funcname': funcname,
-                                    'varlist': info.varlist,
-                                    'field': self.get_field_accessor(cfname),
-                                    'codeafter': info.get_codeafter() })
-                    gettername = funcname
-                except argtypes.ArgTypeError, ex:
-                    sys.stderr.write(
-                        "Could not write getter for %s.%s: %s\n"
-                        % (self.objinfo.c_name, fname, str(ex)))
-            if gettername != '0' or settername != '0':
-                getsets.append('    { "%s", (getter)%s, (setter)%s },\n' %
-                               (fixname(fname), gettername, settername))
-
-        if not getsets:
-            return '0'
-        self.fp.write('static const PyGetSetDef %s[] = {\n' % getsets_name)
-        for getset in getsets:
-            self.fp.write(getset)
-        self.fp.write('    { NULL, (getter)0, (setter)0 },\n')
-        self.fp.write('};\n\n')
-
-        return getsets_name
-
-    def _write_get_symbol_names(self, writer, functions):
-        self.fp.write("""static PyObject *
-_wrap__get_symbol_names(PyObject *self)
-{
-    PyObject *pylist = PyList_New(0);
-
-""")
-        for obj, bases in writer.get_classes():
-            self.fp.write('    PyList_Append(pylist, '
-                          'PyString_FromString("%s"));\n' % (obj.name))
-
-        for name, cname, flags, docstring in functions:
-            self.fp.write('    PyList_Append(pylist, '
-                          'PyString_FromString("%s"));\n' % (name))
-
-        for enum in writer.get_enums():
-            self.fp.write('    PyList_Append(pylist, '
-                          'PyString_FromString("%s"));\n' % (enum.name))
-            for nick, value in enum.values:
-                name = value[len(self.overrides.modulename)+1:]
-                self.fp.write('    PyList_Append(pylist, '
-                              'PyString_FromString("%s"));\n' % (name))
-
-        self.fp.write("    return pylist;\n}\n\n");
-
-    def _write_get_symbol(self, writer, functions):
-        self.fp.write("""static PyObject *
-_wrap__get_symbol(PyObject *self, PyObject *args)
-{
-    PyObject *d;
-    char *name;
-    static PyObject *modulename = NULL;
-    static PyObject *module = NULL;
-    static char *strip_prefix = "%s";
-
-    if (!PyArg_ParseTuple(args, "Os", &d, &name))
-        return NULL;
-
-    if (!modulename)
-       modulename = PyString_FromString("%s");
-
-    if (!module)
-       module = PyDict_GetItemString(d, "__module__");
-
-""" % (self.overrides.modulename.upper() + '_',
-       self.overrides.modulename))
-
-        first = True
-        # Classes / GObjects
-        for obj, bases in writer.get_classes():
-            if first:
-                self.fp.write('    if (!strcmp(name, "%s")) {\n' % obj.name)
-                first = False
-            else:
-                self.fp.write('    } else if (!strcmp(name, "%s")) {\n' % obj.name)
-            self.fp.write(
-                '       return (PyObject*)pygobject_lookup_class(%s);\n' %
-                obj.typecode)
-        self.fp.write('    }\n')
-
-        # Functions
-        for name, cname, flags, docstring in functions:
-            self.fp.write('    else if (!strcmp(name, "%s")) {\n' % name)
-            self.fp.write('        static PyMethodDef ml = { '
-                          '"%s", (PyCFunction)%s, %s, "%s"};\n' % (
-                name, cname, flags, docstring))
-            self.fp.write('        return PyCFunction_NewEx(&ml, NULL, modulename);\n')
-            self.fp.write('    }\n')
-
-        # Enums
-        def write_enum(enum, returnobj=False):
-            if returnobj:
-                ret = 'return '
-            else:
-                ret = ''
-            if enum.deftype == 'enum':
-                self.fp.write(
-                    '        %spyg_enum_add(module, "%s", strip_prefix, %s);\n'
-                    % (ret, enum.name, enum.typecode))
-            else:
-                self.fp.write(
-                    '    %spyg_flags_add(module, "%s", strip_prefix, %s);\n'
-                    % (ret, enum.name, enum.typecode))
-
-        strip_len = len(self.overrides.modulename)+1 # GTK_
-        for enum in writer.get_enums():
-            # XXX: Implement without typecodes
-            self.fp.write('    else if (!strcmp(name, "%s")) {\n' % enum.name)
-            write_enum(enum, returnobj=True)
-            self.fp.write('    }\n')
-
-            for nick, value in enum.values:
-                value = value[strip_len:]
-                self.fp.write('    else if (!strcmp(name, "%s")) {\n' % value)
-                write_enum(enum)
-                self.fp.write('        return PyObject_GetAttrString(module, "%s");\n' %
-                              value)
-                self.fp.write('    }\n')
-
-        self.fp.write('    return Py_None;\n}\n\n');
-
-    def _write_function_bodies(self):
-        functions = []
-        # First, get methods from the defs files
-        for func in self.parser.find_functions():
-            funcname = func.c_name
-            if self.overrides.is_ignored(funcname):
-                continue
-            try:
-                if self.overrides.is_overriden(funcname):
-                    data = self.overrides.override(funcname)
-                    self.write_function(funcname, data)
-
-                    methflags = self.get_methflags(funcname)
-                else:
-                    # write constructor from template ...
-                    code, methflags = self.write_function_wrapper(func,
-                        self.function_tmpl, handle_return=1, is_method=0)
-                    self.fp.write(code)
-                functions.append((func.name, '_wrap_' + funcname,
-                                  methflags, func.docstring))
-                functions_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
-                functions_coverage.declare_not_wrapped()
-                sys.stderr.write('Could not write function %s: %s\n'
-                                 % (func.name, str(ex)))
-
-        # Now try to see if there are any defined in the override
-        for funcname in self.overrides.get_functions():
-            try:
-                data = self.overrides.function(funcname)
-                self.write_function(funcname, data)
-                methflags = self.get_methflags(funcname)
-                functions.append((funcname, '_wrap_' + funcname,
-                                  methflags, 'NULL'))
-                functions_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
-                functions_coverage.declare_not_wrapped()
-                sys.stderr.write('Could not write function %s: %s\n'
-                                 % (funcname, str(ex)))
-        return functions
-
-    def write_functions(self, writer, prefix):
-        self.fp.write('\n/* ----------- functions ----------- */\n\n')
-        functions = []
-        func_infos = self._write_function_bodies()
-
-        # If we have a dynamic namespace, write symbol and attribute getter
-        if self.overrides.dynamicnamespace:
-            self._write_get_symbol_names(writer, func_infos)
-            self._write_get_symbol(writer, func_infos)
-            for obj, bases in writer.get_classes():
-                self.fp.write("""static PyTypeObject *
-%s_register_type(const gchar *name, PyObject *unused)
-{
-    PyObject *m = PyImport_ImportModule("gtk");
-    PyObject *d = PyModule_GetDict(m);
-""" % obj.c_name)
-                writer.write_class(obj, bases, indent=1)
-                self.fp.write(
-                    '    return (%s)PyDict_GetItemString(d, "%s");\n' % (
-                    'PyTypeObject*', obj.name))
-                self.fp.write("}\n")
-
-            functions.append('    { "_get_symbol_names", '
-                             '(PyCFunction)_wrap__get_symbol_names, '
-                             'METH_NOARGS, NULL },\n')
-            functions.append('    { "_get_symbol", '
-                             '(PyCFunction)_wrap__get_symbol, '
-                             'METH_VARARGS, NULL },\n')
-        else:
-            for name, cname, flags, docstring in func_infos:
-                functions.append(self.methdef_tmpl % dict(name=name,
-                                                          cname=cname,
-                                                          flags=flags,
-                                                          docstring=docstring))
-
-        # write the PyMethodDef structure
-        functions.append('    { NULL, NULL, 0, NULL }\n')
-
-        self.fp.write('const PyMethodDef ' + prefix + '_functions[] = {\n')
-        self.fp.write(string.join(functions, ''))
-        self.fp.write('};\n\n')
-
-class GObjectWrapper(Wrapper):
-    constructor_tmpl = (
-        'static int\n'
-        '_wrap_%(cname)s(PyGObject *self%(extraparams)s)\n'
-        '{\n'
-        '%(varlist)s'
-        '%(parseargs)s'
-        '%(codebefore)s'
-        '    self->obj = (GObject *)%(cname)s(%(arglist)s);\n'
-        '%(codeafter)s\n'
-        '    if (!self->obj) {\n'
-        '        PyErr_SetString(PyExc_RuntimeError, '
-        '"could not create %(typename)s object");\n'
-        '        return -1;\n'
-        '    }\n'
-        '%(aftercreate)s'
-        '    pygobject_register_wrapper((PyObject *)self);\n'
-        '    return 0;\n'
-        '}\n\n'
-        )
-
-    method_tmpl = (
-        'static PyObject *\n'
-        '_wrap_%(cname)s(PyGObject *self%(extraparams)s)\n'
-        '{\n'
-        '%(varlist)s'
-        '%(parseargs)s'
-        '%(codebefore)s'
-        '    %(begin_allow_threads)s\n'
-        '    %(setreturn)s%(cname)s(%(cast)s(self->obj)%(arglist)s);\n'
-        '    %(end_allow_threads)s\n'
-        '%(codeafter)s\n'
-        '}\n\n'
-        )
-    def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)):
-        Wrapper.__init__(self, parser, objinfo, overrides, fp)
-        if self.objinfo:
-            self.castmacro = string.replace(self.objinfo.typecode,
-                                            '_TYPE_', '_', 1)
-
-    def get_initial_class_substdict(self):
-        return { 'tp_basicsize'      : 'PyGObject',
-                 'tp_weaklistoffset' : 'offsetof(PyGObject, weakreflist)',
-                 'tp_dictoffset'     : 'offsetof(PyGObject, inst_dict)' }
-
-    def get_field_accessor(self, fieldname):
-        castmacro = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1)
-        return '%s(pygobject_get(self))->%s' % (castmacro, fieldname)
-
-    def get_initial_constructor_substdict(self, constructor):
-        substdict = Wrapper.get_initial_constructor_substdict(self,
-                                                              constructor)
-        if not constructor.caller_owns_return:
-            substdict['aftercreate'] = "    g_object_ref(self->obj);\n"
-        else:
-            substdict['aftercreate'] = ''
-        return substdict
-
-    def get_initial_method_substdict(self, method):
-        substdict = Wrapper.get_initial_method_substdict(self, method)
-        substdict['cast'] = string.replace(self.objinfo.typecode,
-                                           '_TYPE_', '_', 1)
-        return substdict
-
-    def write_default_constructor(self):
-        try:
-            parent = self.parser.find_object(self.objinfo.parent)
-        except ValueError:
-            parent = None
-        if parent is not None:
-            ## just like the constructor is inheritted, we should
-            # inherit the new API compatibility flag
-            self.objinfo.has_new_constructor_api = (
-                parent.has_new_constructor_api)
-        elif self.objinfo.parent == 'GObject':
-            self.objinfo.has_new_constructor_api = True
-        return '0'
-
-    def write_property_based_constructor(self, constructor):
-        self.objinfo.has_new_constructor_api = True
-        out = self.fp
-        print >> out, "static int"
-        print >> out, '_wrap_%s(PyGObject *self, PyObject *args,' \
-              ' PyObject *kwargs)\n{' % constructor.c_name
-        if constructor.params:
-            s = "    GType obj_type = pyg_type_from_object((PyObject *) self);"
-            print >> out, s
-
-        def py_str_list_to_c(arg):
-            if arg:
-                return "{" + ", ".join(
-                    map(lambda s: '"' + s + '"', arg)) + ", NULL }"
-            else:
-                return "{ NULL }"
-
-        classname = '%s.%s' % (self.overrides.modulename,
-                               self.objinfo.name)
-
-        if constructor.params:
-            mandatory_arguments = [param for param in constructor.params
-                                             if not param.optional]
-            optional_arguments = [param for param in constructor.params
-                                            if param.optional]
-            arg_names = py_str_list_to_c(
-            [param.argname
-             for param in mandatory_arguments + optional_arguments])
-
-            prop_names = py_str_list_to_c(
-            [param.pname
-             for param in mandatory_arguments + optional_arguments])
-
-            print >> out, "    GParameter params[%i];" % \
-                  len(constructor.params)
-            print >> out, "    PyObject *parsed_args[%i] = {NULL, };" % \
-                  len(constructor.params)
-            print >> out, "    char *arg_names[] = %s;" % arg_names
-            print >> out, "    char *prop_names[] = %s;" % prop_names
-            print >> out, "    guint nparams, i;"
-            print >> out
-            if constructor.deprecated is not None:
-                out.write(
-                    '    if (PyErr_Warn(PyExc_DeprecationWarning, '
-                    '"%s") < 0)\n' %
-                    constructor.deprecated)
-                print >> out, '        return -1;'
-                print >> out
-            out.write("    if (!PyArg_ParseTupleAndKeywords(args, kwargs, ")
-            template = '"'
-            if mandatory_arguments:
-                template += "O"*len(mandatory_arguments)
-            if optional_arguments:
-                template += "|" + "O"*len(optional_arguments)
-            template += ':%s.__init__"' % classname
-            print >> out, template, ", arg_names",
-            for i in range(len(constructor.params)):
-                print >> out, ", &parsed_args[%i]" % i,
-
-            out.write(
-                "))\n"
-                "        return -1;\n"
-                "\n"
-                "    memset(params, 0, sizeof(GParameter)*%i);\n"
-                "    if (!pyg_parse_constructor_args(obj_type, arg_names,\n"
-                "                                    prop_names, params, \n"
-                "                                    &nparams, parsed_args))\n"
-                "        return -1;\n"
-                "    pygobject_constructv(self, nparams, params);\n"
-                "    for (i = 0; i < nparams; ++i)\n"
-                "        g_value_unset(&params[i].value);\n"
-                % len(constructor.params))
-        else:
-            out.write(
-                "    static char* kwlist[] = { NULL };\n"
-                "\n")
-
-            if constructor.deprecated is not None:
-                out.write(
-                    '    if (PyErr_Warn(PyExc_DeprecationWarning, "%s") < 0)\n'
-                    '        return -1;\n'
-                    '\n' % constructor.deprecated)
-
-            out.write(
-                '    if (!PyArg_ParseTupleAndKeywords(args, kwargs,\n'
-                '                                     ":%s.__init__",\n'
-                '                                     kwlist))\n'
-                '        return -1;\n'
-                '\n'
-                '    pygobject_constructv(self, 0, NULL);\n' % classname)
-        out.write(
-            '    if (!self->obj) {\n'
-            '        PyErr_SetString(\n'
-            '            PyExc_RuntimeError, \n'
-            '            "could not create %s object");\n'
-            '        return -1;\n'
-            '    }\n' % classname)
-
-        if not constructor.caller_owns_return:
-            print >> out, "    g_object_ref(self->obj);\n"
-
-        out.write(
-            '    return 0;\n'
-            '}\n\n')
-
-        return "_wrap_%s" % constructor.c_name
-
-
-class GInterfaceWrapper(GObjectWrapper):
-    virtual_accessor_tmpl = (
-        'static PyObject *\n'
-        '_wrap_%(cname)s(PyObject *cls%(extraparams)s)\n'
-        '{\n'
-        '    %(vtable)s *iface;\n'
-        '%(varlist)s'
-        '%(parseargs)s'
-        '%(codebefore)s'
-        '    iface = g_type_interface_peek('
-        'g_type_class_peek(pyg_type_from_object(cls)), %(typecode)s);\n'
-        '    if (iface->%(virtual)s)\n'
-        '        %(setreturn)siface->%(virtual)s(%(arglist)s);\n'
-        '    else {\n'
-        '        PyErr_SetString(PyExc_NotImplementedError, '
-        '"interface method %(name)s not implemented");\n'
-        '        return NULL;\n'
-        '    }\n'
-        '%(codeafter)s\n'
-        '}\n\n'
-        )
-
-    def get_initial_class_substdict(self):
-        return { 'tp_basicsize'      : 'PyObject',
-                 'tp_weaklistoffset' : '0',
-                 'tp_dictoffset'     : '0'}
-
-    def write_constructor(self):
-        # interfaces have no constructors ...
-        return '0'
-    def write_getsets(self):
-        # interfaces have no fields ...
-        return '0'
-
-    def _get_class_virtual_substdict(self, meth, cname, parent):
-        substdict = self.get_initial_method_substdict(meth)
-        substdict['virtual'] = meth.name
-        substdict['cname'] = cname
-        substdict['typecode'] = self.objinfo.typecode
-        substdict['vtable'] = self.objinfo.vtable
-        return substdict
-
-    def write_virtuals(self):
-        ## Now write reverse method wrappers, which let python code
-        ## implement interface methods.
-        # First, get methods from the defs files
-        klass = self.objinfo.c_name
-        proxies = []
-        for meth in self.parser.find_virtuals(self.objinfo):
-            method_name = self.objinfo.c_name + "__proxy_do_" + meth.name
-            if self.overrides.is_ignored(method_name):
-                continue
-            try:
-                if self.overrides.is_overriden(method_name):
-                    if not self.overrides.is_already_included(method_name):
-                        data = self.overrides.override(method_name)
-                        self.write_function(method_name, data)
-                else:
-                    # write proxy ...
-                    ret, props = argtypes.matcher.get_reverse_ret(meth.ret)
-                    wrapper = reversewrapper.ReverseWrapper(
-                        '_wrap_' + method_name, is_static=True)
-                    wrapper.set_return_type(ret(wrapper, **props))
-                    wrapper.add_parameter(reversewrapper.PyGObjectMethodParam(
-                        wrapper, "self", method_name="do_" + meth.name,
-                        c_type=(klass + ' *')))
-                    for param in meth.params:
-                        handler, props = argtypes.matcher.get_reverse(
-                            param.ptype)
-                        props["direction"] = param.pdir
-                        wrapper.add_parameter(
-                            handler(wrapper, param.pname, **props))
-                    buf = reversewrapper.MemoryCodeSink()
-                    wrapper.generate(buf)
-                    self.fp.write(buf.flush())
-                proxies.append((fixname(meth.name), '_wrap_' + method_name))
-                iproxies_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
-                iproxies_coverage.declare_not_wrapped()
-                proxies.append((fixname(meth.name), None))
-                sys.stderr.write('Could not write interface proxy %s.%s: %s\n'
-                                % (klass, meth.name, str(ex)))
-
-        if not proxies or not [cname for name, cname in proxies if cname]:
-            return
-
-        ## Write an interface init function for this object
-        funcname = "__%s__interface_init" % klass
-        vtable = self.objinfo.vtable
-        self.fp.write(
-            '\nstatic void\n'
-            '%(funcname)s(%(vtable)s *iface, PyTypeObject *pytype)\n'
-            '{\n'
-            '    %(vtable)s *parent_iface = '
-            'g_type_interface_peek_parent(iface);\n'
-            '    PyObject *py_method;\n'
-            '\n'
-            % vars())
-
-        for name, cname in proxies:
-            do_name = 'do_' + name
-            if cname is None:
-                continue
-
-            self.fp.write((
-                '    py_method = pytype? PyObject_GetAttrString('
-                '(PyObject *) pytype, "%(do_name)s") : NULL;\n'
-                '    if (py_method && !PyObject_TypeCheck(py_method, '
-                '&PyCFunction_Type)) {\n'
-                '        iface->%(name)s = %(cname)s;\n'
-                '    } else {\n'
-                '        PyErr_Clear();\n'
-                '        if (parent_iface) {\n'
-                '            iface->%(name)s = parent_iface->%(name)s;\n'
-                '        }\n'
-                '    Py_XDECREF(py_method);\n'
-                '    }\n'
-                ) % vars())
-        self.fp.write('}\n\n')
-        interface_info = "__%s__iinfo" % klass
-        self.fp.write('''
-static const GInterfaceInfo %s = {
-    (GInterfaceInitFunc) %s,
-    NULL,
-    NULL
-};
-''' % (interface_info, funcname))
-        self.objinfo.interface_info = interface_info
-
-class GBoxedWrapper(Wrapper):
-    constructor_tmpl = (
-        'static int\n'
-        '_wrap_%(cname)s(PyGBoxed *self%(extraparams)s)\n'
-        '{\n'
-        '%(varlist)s'
-        '%(parseargs)s'
-        '%(codebefore)s'
-        '    self->gtype = %(typecode)s;\n'
-        '    self->free_on_dealloc = FALSE;\n'
-        '    self->boxed = %(cname)s(%(arglist)s);\n'
-        '%(codeafter)s\n'
-        '    if (!self->boxed) {\n'
-        '        PyErr_SetString(PyExc_RuntimeError, '
-        '"could not create %(typename)s object");\n'
-        '        return -1;\n'
-        '    }\n'
-        '    self->free_on_dealloc = TRUE;\n'
-        '    return 0;\n'
-        '}\n\n'
-        )
-
-    method_tmpl = (
-        'static PyObject *\n'
-        '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
-        '{\n'
-        '%(varlist)s'
-        '%(parseargs)s'
-        '%(codebefore)s'
-        '    %(begin_allow_threads)s\n'
-        '    %(setreturn)s%(cname)s(pyg_boxed_get(self, '
-        '%(typename)s)%(arglist)s);\n'
-        '    %(end_allow_threads)s\n'
-        '%(codeafter)s\n'
-        '}\n\n'
-        )
-
-    def get_initial_class_substdict(self):
-        return { 'tp_basicsize'      : 'PyGBoxed',
-                 'tp_weaklistoffset' : '0',
-                 'tp_dictoffset'     : '0' }
-
-    def get_field_accessor(self, fieldname):
-        return 'pyg_boxed_get(self, %s)->%s' % (self.objinfo.c_name, fieldname)
-
-    def get_initial_constructor_substdict(self, constructor):
-        substdict = Wrapper.get_initial_constructor_substdict(
-            self, constructor)
-        substdict['typecode'] = self.objinfo.typecode
-        return substdict
-
-class GPointerWrapper(GBoxedWrapper):
-    constructor_tmpl = (
-        'static int\n'
-        '_wrap_%(cname)s(PyGPointer *self%(extraparams)s)\n'
-        '{\n'
-        '%(varlist)s'
-        '%(parseargs)s'
-        '%(codebefore)s'
-        '    self->gtype = %(typecode)s;\n'
-        '    self->pointer = %(cname)s(%(arglist)s);\n'
-        '%(codeafter)s\n'
-        '    if (!self->pointer) {\n'
-        '        PyErr_SetString(PyExc_RuntimeError, '
-        '"could not create %(typename)s object");\n'
-        '        return -1;\n'
-        '    }\n'
-        '    return 0;\n'
-        '}\n\n'
-        )
-
-    method_tmpl = (
-        'static PyObject *\n'
-        '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
-        '{\n'
-        '%(varlist)s'
-        '%(parseargs)s'
-        '%(codebefore)s'
-        '    %(setreturn)s%(cname)s(pyg_pointer_get(self, '
-        '%(typename)s)%(arglist)s);\n'
-        '%(codeafter)s\n'
-        '}\n\n'
-        )
-
-    def get_initial_class_substdict(self):
-        return { 'tp_basicsize'      : 'PyGPointer',
-                 'tp_weaklistoffset' : '0',
-                 'tp_dictoffset'     : '0' }
-
-    def get_field_accessor(self, fieldname):
-        return 'pyg_pointer_get(self, %s)->%s' % (self.objinfo.c_name,
-                                                  fieldname)
-
-    def get_initial_constructor_substdict(self, constructor):
-        substdict = Wrapper.get_initial_constructor_substdict(
-            self, constructor)
-        substdict['typecode'] = self.objinfo.typecode
-        return substdict
-
-class SourceWriter:
-    def __init__(self, parser, overrides, prefix, fp=FileOutput(sys.stdout)):
-        self.parser = parser
-        self.overrides = overrides
-        self.prefix = prefix
-        self.fp = fp
-
-    def write(self, py_ssize_t_clean=False):
-        argtypes.py_ssize_t_clean = py_ssize_t_clean
-
-        self.write_headers(py_ssize_t_clean)
-        self.write_imports()
-        self.write_type_declarations()
-        self.write_body()
-        self.write_classes()
-
-        wrapper = Wrapper(self.parser, None, self.overrides, self.fp)
-        wrapper.write_functions(self, self.prefix)
-
-        if not self.overrides.dynamicnamespace:
-            self.write_enums()
-        self.write_extension_init()
-        self.write_registers()
-        
-        argtypes.py_ssize_t_clean = False
-
-    def write_headers(self, py_ssize_t_clean):
-        self.fp.write('/* -- THIS FILE IS GENERATED - DO NOT EDIT */')
-        self.fp.write('/* -*- Mode: C; c-basic-offset: 4 -*- */\n\n')
-        if py_ssize_t_clean:
-            self.fp.write('#define PY_SSIZE_T_CLEAN\n')
-        self.fp.write('#include <Python.h>\n\n\n')
-        if py_ssize_t_clean:
-            self.fp.write('''
-
-#if PY_VERSION_HEX < 0x02050000
-typedef int Py_ssize_t;
-#define PY_SSIZE_T_MAX INT_MAX
-#define PY_SSIZE_T_MIN INT_MIN
-typedef inquiry lenfunc;
-typedef intargfunc ssizeargfunc;
-typedef intobjargproc ssizeobjargproc;
-#endif
-
-''')
-        self.fp.write(self.overrides.get_headers())
-        self.fp.resetline()
-        self.fp.write('\n\n')
-
-    def write_imports(self):
-        self.fp.write('/* ---------- types from other modules ---------- */\n')
-        for module, pyname, cname, importing_for in self.overrides.get_imports():
-            if importing_for is None or is_registered_object(importing_for):
-                self.fp.write('static PyTypeObject *_%s;\n' % cname)
-                self.fp.write('#define %s (*_%s)\n' % (cname, cname))
-        self.fp.write('\n\n')
-
-    def write_type_declarations(self):
-        #todo use 'static' if used only in one file
-        self.fp.write('/* ---------- forward type declarations ---------- */\n')
-        for obj in self.parser.boxes:
-            if not self.overrides.is_type_ignored(obj.c_name):
-                self.fp.write('PyTypeObject G_GNUC_INTERNAL Py' + obj.c_name + '_Type;\n')
-        for obj in self.parser.objects:
-            if not self.overrides.is_type_ignored(obj.c_name):
-                self.fp.write('PyTypeObject G_GNUC_INTERNAL Py' + obj.c_name + '_Type;\n')
-        for interface in self.parser.interfaces:
-            if not self.overrides.is_type_ignored(interface.c_name):
-                self.fp.write('PyTypeObject G_GNUC_INTERNAL Py' + interface.c_name + '_Type;\n')
-        self.fp.write('\n')
-
-    def write_body(self):
-        self.fp.write(self.overrides.get_body())
-        self.fp.resetline()
-        self.fp.write('\n\n')
-
-    def _sort_parent_children(self, objects):
-        objects = list(objects)
-        modified = True
-        while modified:
-            modified = False
-            parent_index = None
-            child_index = None
-            for i, obj in enumerate(objects):
-                if obj.parent == 'GObject':
-                    continue
-                if obj.parent not in [info.c_name for info in objects[:i]]:
-                    for j, info in enumerate(objects[i+1:]):
-                        if info.c_name == obj.parent:
-                            parent_index = i + 1 + j
-                            child_index = i
-                            break
-                    else:
-                        continue
-                    break
-            if child_index is not None and parent_index is not None:
-                if child_index != parent_index:
-                    objects.insert(child_index, objects.pop(parent_index))
-                    modified = True
-        return objects
-
-    def write_classes(self):
-        ## Sort the objects, so that we generate code for the parent types
-        ## before their children.
-        objects = self._sort_parent_children(self.parser.objects)
-
-        for klass, items in ((GBoxedWrapper, self.parser.boxes),
-                             (GPointerWrapper, self.parser.pointers),
-                             (GObjectWrapper, objects),
-                             (GInterfaceWrapper, self.parser.interfaces)):
-            for item in items:
-                instance = klass(self.parser, item, self.overrides, self.fp)
-                instance.write_class()
-                self.fp.write('\n')
-
-    def get_enums(self):
-        enums = []
-        for enum in self.parser.enums:
-            if self.overrides.is_type_ignored(enum.c_name):
-                continue
-            enums.append(enum)
-        return enums
-
-    def write_enums(self):
-        if not self.parser.enums:
-            return
-
-        self.fp.write('\n/* ----------- enums and flags ----------- */\n\n')
-        self.fp.write(
-            'void\n' + self.prefix +
-            '_add_constants(PyObject *module, const gchar *strip_prefix)\n{\n')
-
-        self.fp.write(
-            '#ifdef VERSION\n'
-            '    PyModule_AddStringConstant(module, "__version__", VERSION);\n'
-            '#endif\n')
-
-        for enum in self.get_enums():
-            if enum.typecode is None:
-                for nick, value in enum.values:
-                    self.fp.write(
-                        '    PyModule_AddIntConstant(module, '
-                        '(char *) pyg_constant_strip_prefix("%s", strip_prefix), %s);\n'
-                        % (value, value))
-            else:
-                if enum.deftype == 'enum':
-                    self.fp.write('  pyg_enum_add(module, "%s", strip_prefix, %s);\n'
-                                  % (enum.name, enum.typecode))
-                else:
-                    self.fp.write('  pyg_flags_add(module, "%s", strip_prefix, %s);\n'
-                                  % (enum.name, enum.typecode))
-
-        self.fp.write('\n')
-        self.fp.write('  if (PyErr_Occurred())\n')
-        self.fp.write('    PyErr_Print();\n')
-        self.fp.write('}\n\n')
-
-    def write_object_imports(self, retval=''):
-        imports = self.overrides.get_imports()[:]
-        if not imports:
-            return
-
-        bymod = {}
-        for module, pyname, cname, importing_for in imports:
-            if importing_for is None or is_registered_object(importing_for):
-                bymod.setdefault(module, []).append((pyname, cname))
-        self.fp.write('    PyObject *module;\n\n')
-        for module in bymod:
-            self.fp.write(
-                '    if ((module = PyImport_ImportModule("%s")) != NULL) {\n'
-                % module)
-            #self.fp.write(
-            #    '        PyObject *moddict = PyModule_GetDict(module);\n\n')
-            for pyname, cname in bymod[module]:
-                #self.fp.write(
-                #    '        _%s = (PyTypeObject *)PyDict_GetItemString('
-                #    'moddict, "%s");\n' % (cname, pyname))
-                self.fp.write(
-                    '        _%s = (PyTypeObject *)PyObject_GetAttrString('
-                    'module, "%s");\n' % (cname, pyname))
-                self.fp.write('        if (_%s == NULL) {\n' % cname)
-                self.fp.write('            PyErr_SetString(PyExc_ImportError,\n')
-                self.fp.write('                "cannot import name %s from %s");\n'
-                         % (pyname, module))
-                self.fp.write('            return %s;\n' % retval)
-                self.fp.write('        }\n')
-            self.fp.write('    } else {\n')
-            self.fp.write('        PyErr_SetString(PyExc_ImportError,\n')
-            self.fp.write('            "could not import %s");\n' % module)
-            self.fp.write('        return %s;\n' % retval)
-            self.fp.write('    }\n')
-        self.fp.write('\n')
-
-    def write_extension_init(self):
-        self.fp.write('/* initialise stuff extension classes */\n')
-        self.fp.write('void\n' + self.prefix + '_register_classes(PyObject *d)\n{\n')
-        self.write_object_imports()
-        self.fp.write(self.overrides.get_init() + '\n')
-        self.fp.resetline()
-
-    def get_classes(self):
-        objects = self.parser.objects[:]
-        pos = 0
-        while pos < len(objects):
-            parent = objects[pos].parent
-            for i in range(pos+1, len(objects)):
-                if objects[i].c_name == parent:
-                    objects.insert(i+1, objects[pos])
-                    del objects[pos]
-                    break
-            else:
-                pos = pos + 1
-
-        retval = []
-        for obj in objects:
-            if self.overrides.is_type_ignored(obj.c_name):
-                continue
-            bases = []
-            if obj.parent != None:
-                bases.append(obj.parent)
-            bases = bases + obj.implements
-            retval.append((obj, bases))
-
-        return retval
-
-    def write_registers(self):
-        for boxed in self.parser.boxes:
-            if not self.overrides.is_type_ignored(boxed.c_name):
-                self.fp.write('    pyg_register_boxed(d, "' + boxed.name +
-                              '", ' + boxed.typecode +
-                              ', &Py' + boxed.c_name +
-                          '_Type);\n')
-        for pointer in self.parser.pointers:
-            if not self.overrides.is_type_ignored(pointer.c_name):
-                self.fp.write('    pyg_register_pointer(d, "' + pointer.name +
-                              '", ' + pointer.typecode +
-                              ', &Py' + pointer.c_name + '_Type);\n')
-        for interface in self.parser.interfaces:
-            if not self.overrides.is_type_ignored(interface.c_name):
-                self.fp.write('    pyg_register_interface(d, "'
-                              + interface.name + '", '+ interface.typecode
-                              + ', &Py' + interface.c_name + '_Type);\n')
-                if interface.interface_info is not None:
-                    self.fp.write('    pyg_register_interface_info(%s, &%s);\n' %
-                                  (interface.typecode, interface.interface_info))
-
-        if not self.overrides.dynamicnamespace:
-            for obj, bases in self.get_classes():
-                self.write_class(obj, bases)
-        else:
-            for obj, bases in self.get_classes():
-                self.fp.write(
-                    '    pyg_type_register_custom_callback("%s", '
-                    '(PyGTypeRegistrationFunction)%s_register_type, d);\n' %
-                    (obj.c_name, obj.c_name))
-
-        self.fp.write('}\n')
-
-    def _can_direct_ref(self, base):
-        if not self.overrides.dynamicnamespace:
-            return True
-        if base == 'GObject':
-            return True
-        obj = get_object_by_name(base)
-        if obj.module.lower() != self.overrides.modulename:
-            return True
-        return False
-
-    def write_class(self, obj, bases, indent=1):
-        indent_str = ' ' * (indent * 4)
-        if bases:
-            bases_str = 'Py_BuildValue("(%s)"' % (len(bases) * 'O')
-
-            for base in bases:
-                if self._can_direct_ref(base):
-                    bases_str += ', &Py%s_Type' % base
-                else:
-                    baseobj = get_object_by_name(base)
-                    bases_str += ', PyObject_GetAttrString(m, "%s")' % baseobj.name
-            bases_str += ')'
-        else:
-            bases_str = 'NULL'
-
-        self.fp.write(
-                '%(indent)spygobject_register_class(d, "%(c_name)s", %(typecode)s, &Py%(c_name)s_Type, %(bases)s);\n'
-                % dict(indent=indent_str, c_name=obj.c_name, typecode=obj.typecode, bases=bases_str))
-
-        if obj.has_new_constructor_api:
-            self.fp.write(
-                indent_str + 'pyg_set_object_has_new_constructor(%s);\n' %
-                obj.typecode)
-        else:
-            print >> sys.stderr, (
-                "Warning: Constructor for %s needs to be updated to new API\n"
-                "         See http://live.gnome.org/PyGTK_2fWhatsNew28";
-                "#update-constructors") % obj.c_name
-
-        if obj.class_init_func is not None:
-            self.fp.write(
-                indent_str + 'pyg_register_class_init(%s, %s);\n' %
-                (obj.typecode, obj.class_init_func))
-
-_objects = {}
-
-def is_registered_object(c_name):
-    return c_name in _objects
-
-def get_object_by_name(c_name):
-    global _objects
-    return _objects[c_name]
-
-def register_types(parser):
-    global _objects
-    for boxed in parser.boxes:
-        argtypes.matcher.register_boxed(boxed.c_name, boxed.typecode)
-        _objects[boxed.c_name] = boxed
-    for pointer in parser.pointers:
-        argtypes.matcher.register_pointer(pointer.c_name, pointer.typecode)
-    for obj in parser.objects:
-        argtypes.matcher.register_object(obj.c_name, obj.parent, obj.typecode)
-        _objects[obj.c_name] = obj
-    for iface in parser.interfaces:
-        argtypes.matcher.register_object(iface.c_name, None, iface.typecode)
-        _objects[iface.c_name] = iface
-    for enum in parser.enums:
-        if enum.deftype == 'flags':
-            argtypes.matcher.register_flag(enum.c_name, enum.typecode)
-        else:
-            argtypes.matcher.register_enum(enum.c_name, enum.typecode)
-
-usage = 'usage: codegen.py [-o overridesfile] [-p prefix] defsfile'
-def main(argv):
-    o = override.Overrides()
-    prefix = 'pygtk'
-    outfilename = None
-    errorfilename = None
-    opts, args = getopt.getopt(argv[1:], "o:p:r:t:D:I:",
-                        ["override=", "prefix=", "register=", "outfilename=",
-                         "load-types=", "errorfilename=", "py_ssize_t-clean"])
-    defines = {} # -Dkey[=val] options
-    py_ssize_t_clean = False
-    for opt, arg in opts:
-        if opt in ('-o', '--override'):
-            o = override.Overrides(arg)
-        elif opt in ('-p', '--prefix'):
-            prefix = arg
-        elif opt in ('-r', '--register'):
-            # Warning: user has to make sure all -D options appear before -r
-            p = defsparser.DefsParser(arg, defines)
-            p.startParsing()
-            register_types(p)
-            del p
-        elif opt == '--outfilename':
-            outfilename = arg
-        elif opt == '--errorfilename':
-            errorfilename = arg
-        elif opt in ('-t', '--load-types'):
-            globals = {}
-            execfile(arg, globals)
-        elif opt == '-D':
-            nameval = arg.split('=')
-            try:
-                defines[nameval[0]] = nameval[1]
-            except IndexError:
-                defines[nameval[0]] = None
-        elif opt == '-I':
-            defsparser.include_path.insert(0, arg)
-        elif opt == '--py_ssize_t-clean':
-            py_ssize_t_clean = True
-    if len(args) < 1:
-        print >> sys.stderr, usage
-        return 1
-    if errorfilename:
-        sys.stderr = open(errorfilename, "w")
-    p = defsparser.DefsParser(args[0], defines)
-    if not outfilename:
-        outfilename = os.path.splitext(args[0])[0] + '.c'
-
-    p.startParsing()
-
-    register_types(p)
-    sw = SourceWriter(p, o, prefix, FileOutput(sys.stdout, outfilename))
-    sw.write(py_ssize_t_clean)
+# codegen.py is runnable as a script and available as module in codegen package
+if __name__ == '__main__':
+    from libcodegen import codegen
+    import sys
+    sys.exit(codegen.main(sys.argv))
+else:
+    from codegen.libcodegen.codegen import *
 
-    functions_coverage.printstats()
-    methods_coverage.printstats()
-    vproxies_coverage.printstats()
-    vaccessors_coverage.printstats()
-    iproxies_coverage.printstats()
 
-if __name__ == '__main__':
-    sys.exit(main(sys.argv))
diff --git a/codegen/defsconvert.py b/codegen/defsconvert.py
index c3c2324..c58db53 100755
--- a/codegen/defsconvert.py
+++ b/codegen/defsconvert.py
@@ -16,11 +16,11 @@ def to_upper_str(name):
     name = _upperstr_pat1.sub(r'\1_\2', name)
     name = _upperstr_pat2.sub(r'\1_\2', name)
     name = _upperstr_pat3.sub(r'\1_\2', name, count=1)
-    return string.upper(name)
+    return name.upper()
 
 def typecode(typename):
     """create a typecode (eg. GTK_TYPE_WIDGET) from a typename"""
-    return string.replace(to_upper_str(typename), '_', '_TYPE_', 1)
+    return to_upper_str(typename).replace('_', '_TYPE_', 1)
 
 
 STATE_START = 0
diff --git a/codegen/defsgen.py b/codegen/defsgen.py
index 6c2e63d..de7c0de 100755
--- a/codegen/defsgen.py
+++ b/codegen/defsgen.py
@@ -220,7 +220,7 @@ def find_defs(buf, gobj, modlib, defs):
         func_name = m[1]
         for lib in modlib:
             if hasattr(lib, func_name):
-                objtype = apply(getattr(lib, func_name))
+                objtype = getattr(lib, func_name)()
                 obj_name = gobj.g_type_name(objtype)
                 parent = gobj.g_type_parent(objtype)
                 parent_name = gobj.g_type_name(parent)
@@ -504,7 +504,7 @@ class DefsWriter:
             func = m.group(1) + '_get_type'
             lib = [l for l in self.modlib if hasattr(l, func)]
             if lib:
-                cname = self.gobj.g_type_name(apply(getattr(lib[0], func)))
+                cname = self.gobj.g_type_name(getattr(lib[0], func)())
             if cname and self.gobj.g_type_from_name(r.group(1)):
                 self.fp.write('  (is-constructor-of "' + cname + '")\n')
         self._write_return(ret)
diff --git a/codegen/defsparser.py b/codegen/defsparser.py
index 37ba0a2..27b6b4d 100644
--- a/codegen/defsparser.py
+++ b/codegen/defsparser.py
@@ -1,153 +1 @@
-# -*- Mode: Python; py-indent-offset: 4 -*-
-import os, sys
-import scmexpr
-from definitions import BoxedDef, EnumDef, FlagsDef, FunctionDef, \
-     InterfaceDef, MethodDef, ObjectDef, PointerDef, VirtualDef
-
-include_path = ['.']
-
-class IncludeParser(scmexpr.Parser):
-    """A simple parser that follows include statements automatically"""
-    def include(self, input_filename):
-        global include_path
-        if os.path.isabs(input_filename):
-            filename = input_filename
-            # set self.filename to the include name, to handle recursive includes
-            oldfile = self.filename
-            self.filename = filename
-            self.startParsing()
-            self.filename = oldfile
-        else:
-            inc_path = [os.path.dirname(self.filename)] + include_path
-            for filename in [os.path.join(path_entry, input_filename)
-                             for path_entry in inc_path]:
-                if not os.path.exists(filename):
-                    continue
-                # set self.filename to the include name, to handle recursive includes
-                oldfile = self.filename
-                self.filename = filename
-                self.startParsing()
-                self.filename = oldfile
-                break
-            else:
-                raise IOError("%s not found in include path %s" % (input_filename, inc_path))
-
-class DefsParser(IncludeParser):
-    def __init__(self, arg, defines={}):
-        IncludeParser.__init__(self, arg)
-        self.objects = []
-        self.interfaces = []
-        self.enums = []      # enums and flags
-        self.boxes = []      # boxed types
-        self.pointers = []   # pointer types
-        self.functions = []  # functions and methods
-        self.virtuals = []   # virtual methods
-        self.c_name = {}     # hash of c names of functions
-        self.methods = {}    # hash of methods of particular objects
-        self.defines = defines      # -Dfoo=bar options, as dictionary
-
-    def define_object(self, *args):
-        odef = apply(ObjectDef, args)
-        self.objects.append(odef)
-        self.c_name[odef.c_name] = odef
-    def define_interface(self, *args):
-        idef = apply(InterfaceDef, args)
-        self.interfaces.append(idef)
-        self.c_name[idef.c_name] = idef
-    def define_enum(self, *args):
-        edef = apply(EnumDef, args)
-        self.enums.append(edef)
-        self.c_name[edef.c_name] = edef
-    def define_flags(self, *args):
-        fdef = apply(FlagsDef, args)
-        self.enums.append(fdef)
-        self.c_name[fdef.c_name] = fdef
-    def define_boxed(self, *args):
-        bdef = apply(BoxedDef, args)
-        self.boxes.append(bdef)
-        self.c_name[bdef.c_name] = bdef
-    def define_pointer(self, *args):
-        pdef = apply(PointerDef, args)
-        self.pointers.append(pdef)
-        self.c_name[pdef.c_name] = pdef
-    def define_function(self, *args):
-        fdef = apply(FunctionDef, args)
-        self.functions.append(fdef)
-        self.c_name[fdef.c_name] = fdef
-    def define_method(self, *args):
-        mdef = apply(MethodDef, args)
-        self.functions.append(mdef)
-        self.c_name[mdef.c_name] = mdef
-    def define_virtual(self, *args):
-        vdef = apply(VirtualDef, args)
-        self.virtuals.append(vdef)
-    def merge(self, old, parmerge):
-        for obj in self.objects:
-            if old.c_name.has_key(obj.c_name):
-                obj.merge(old.c_name[obj.c_name])
-        for f in self.functions:
-            if old.c_name.has_key(f.c_name):
-                f.merge(old.c_name[f.c_name], parmerge)
-
-    def printMissing(self, old):
-        for obj in self.objects:
-            if not old.c_name.has_key(obj.c_name):
-                obj.write_defs()
-        for f in self.functions:
-            if not old.c_name.has_key(f.c_name):
-                f.write_defs()
-
-    def write_defs(self, fp=sys.stdout):
-        for obj in self.objects:
-            obj.write_defs(fp)
-        for enum in self.enums:
-            enum.write_defs(fp)
-        for boxed in self.boxes:
-            boxed.write_defs(fp)
-        for pointer in self.pointers:
-            pointer.write_defs(fp)
-        for func in self.functions:
-            func.write_defs(fp)
-
-    def find_object(self, c_name):
-        for obj in self.objects:
-            if obj.c_name == c_name:
-                return obj
-        else:
-            raise ValueError('object %r not found' % c_name)
-
-    def find_constructor(self, obj, overrides):
-        for func in self.functions:
-            if isinstance(func, FunctionDef) and \
-               func.is_constructor_of == obj.c_name and \
-               not overrides.is_ignored(func.c_name):
-                return func
-
-    def find_methods(self, obj):
-        objname = obj.c_name
-        return filter(lambda func, on=objname: isinstance(func, MethodDef) and
-                      func.of_object == on, self.functions)
-
-    def find_virtuals(self, obj):
-        objname = obj.c_name
-        retval = filter(lambda func, on=objname: isinstance(func, VirtualDef) and
-                        func.of_object == on, self.virtuals)
-        return retval
-
-    def find_functions(self):
-        return filter(lambda func: isinstance(func, FunctionDef) and
-                      not func.is_constructor_of, self.functions)
-
-    def ifdef(self, *args):
-        if args[0] in self.defines:
-            for arg in args[1:]:
-                #print >> sys.stderr, "-----> Handling conditional definition (%s): %s" % (args[0], arg)
-                self.handle(arg)
-        else:
-            pass
-            #print >> sys.stderr, "-----> Conditional %s is not true" % (args[0],)
-
-    def ifndef(self, *args):
-        if args[0] not in self.defines:
-            for arg in args[1:]:
-                self.handle(arg)
+from .libcodegen.defsparser import *
diff --git a/codegen/docextract_to_xml.py b/codegen/docextract_to_xml.py
index 775b57d..f8d3bae 100755
--- a/codegen/docextract_to_xml.py
+++ b/codegen/docextract_to_xml.py
@@ -13,18 +13,6 @@ import sys
 
 import docextract
 
-def usage():
-    sys.stderr.write('usage: docextract_to_xml.py ' +
-        '[-s /src/dir | --source-dir=/src/dir] ' +
-        '[-a | --with-annotations] [-p | --with-properties] ' +
-        '[-i | --with-signals ]\n')
-    sys.exit(1)
-
-# Translates special texts to &... HTML acceptable format.  Also replace
-# occurrences of '/*' and '*/' with '/ *' and '* /' respectively to avoid
-# comment errors (note the spaces).  Some function descriptions include C++
-# multi-line comments which cause errors when the description is included in a
-# C++ Doxygen comment block.
 def escape_text(unescaped_text):
     # Escape every "&" not part of an entity reference
     escaped_text = re.sub(r'&(?![A-Za-z]+;)', '&amp;', unescaped_text)
@@ -34,51 +22,31 @@ def escape_text(unescaped_text):
     escaped_text = string.replace(escaped_text, '&ast;', '*')
     escaped_text = string.replace(escaped_text, '&percnt;', '%')
     escaped_text = string.replace(escaped_text, '&commat;', '@')
-    escaped_text = string.replace(escaped_text, '&num;', '')
-    escaped_text = string.replace(escaped_text, '&nbsp;', ' ')
-    # This represents a '/' before or after an '*' so replace with slash but
-    # with spaces.
-    escaped_text = string.replace(escaped_text, '&sol;', ' / ')
 
     # Escape for both tag contents and attribute values
     escaped_text = string.replace(escaped_text, '<', '&lt;')
     escaped_text = string.replace(escaped_text, '>', '&gt;')
     escaped_text = string.replace(escaped_text, '"', '&quot;')
 
-    # Replace C++ comment begin and ends to ones that don't affect Doxygen.
-    escaped_text = string.replace(escaped_text, '/*', '/ *')
-    escaped_text = string.replace(escaped_text, '*/', '* /')
-
     return escaped_text
 
-def print_annotations(annotations):
-    for annotation in annotations:
-        print "<annotation name=" + annotation[0] +  ">" + \
-                escape_text(annotation[1]) + "</annotation>"
-
 if __name__ == '__main__':
     try:
-        opts, args = getopt.getopt(sys.argv[1:], "d:s:o:api",
-                                   ["source-dir=", "with-annotations",
-                                     "with-properties", "with-signals"])
+        opts, args = getopt.getopt(sys.argv[1:], "d:s:o:",
+                                   ["source-dir="])
     except getopt.error, e:
-        sys.stderr.write('docextract_to_xml.py: %s\n' % e)
-        usage()
+        sys.stderr.write('docgen.py: %s\n' % e)
+        sys.stderr.write(
+            'usage: docgen.py [-s /src/dir]\n')
+        sys.exit(1)
     source_dirs = []
-    with_annotations = False
-    with_signals = False
-    with_properties = False
     for opt, arg in opts:
         if opt in ('-s', '--source-dir'):
             source_dirs.append(arg)
-        if opt in ('-a', '--with-annotations'):
-            with_annotations = True
-        if opt in ('-p', '--with-properties'):
-            with_properties = True
-        if opt in ('-i', '--with-signals'):
-            with_signals = True
     if len(args) != 0:
-        usage()
+        sys.stderr.write(
+            'usage: docgen.py  [-s /src/dir]\n')
+        sys.exit(1)
 
     docs = docextract.extract(source_dirs);
     docextract.extract_tmpl(source_dirs, docs); #Try the tmpl sgml files too.
@@ -90,50 +58,25 @@ if __name__ == '__main__':
         print "<root>"
 
         for name, value in docs.items():
-            # Get the type of comment block ('function', 'signal' or
-            # 'property') (the value is a GtkDoc).
-            block_type = value.get_type()
-
-            # Skip signals if the option was not specified.
-            if block_type == 'signal' and not with_signals:
-                continue
-            # Likewise for properties.
-            elif block_type == 'property' and not with_properties:
-                continue
-
-            print "<" + block_type + " name=\"" + escape_text(name) + "\">"
+            print "<function name=\"" + escape_text(name) + "\">"
 
             print "<description>"
-            print escape_text(value.get_description())
+            #The value is a docextract.FunctionDoc
+            print escape_text(value.description)
             print "</description>"
 
-            # Loop through the parameters if not dealing with a property:
-            if block_type != 'property':
-                print "<parameters>"
-                for name, description, annotations in value.params:
-                        print "<parameter name=\"" + escape_text(name) + "\">"
-                        print "<parameter_description>" + escape_text(description) + "</parameter_description>"
-
-                        if with_annotations:
-                            print_annotations(annotations)
-
-                        print "</parameter>"
-
-                print "</parameters>"
+             # Loop through the parameters:
+            print "<parameters>"
+            for name, description in value.params:
+                print "<parameter name=\"" + escape_text(name) + "\">"
+                print "<parameter_description>" + escape_text(description) + "</parameter_description>"
+                print "</parameter>"
 
-                # Show the return-type (also if not dealing with a property):
-                if with_annotations:
-                    print "<return>"
-                    print "<return_description>" + escape_text(value.ret[0]) + \
-                            "</return_description>"
-                    print_annotations(value.ret[1])
-                    print "</return>"
-                else:
-                    print "<return>" + escape_text(value.ret[0]) + "</return>"
+            print "</parameters>"
 
-            if with_annotations:
-                print_annotations(value.get_annotations())
+            # Show the return-type:
+            print "<return>" + escape_text(value.ret) + "</return>"
 
-            print "</" + block_type + ">\n"
+            print "</function>\n"
 
         print "</root>"
diff --git a/codegen/libcodegen/__init__.py b/codegen/libcodegen/__init__.py
new file mode 100644
index 0000000..86188f9
--- /dev/null
+++ b/codegen/libcodegen/__init__.py
@@ -0,0 +1,16 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+
+__all__ = [
+    'argtypes',
+    'codegen',
+    'definitions',
+    'defsparser',
+    'docextract',
+    'docgen',
+    'h2def',
+    'defsgen'
+    'mergedefs',
+    'mkskel',
+    'override',
+    'scmexpr'
+]
diff --git a/codegen/argtypes.py b/codegen/libcodegen/argtypes.py
similarity index 96%
rename from codegen/argtypes.py
rename to codegen/libcodegen/argtypes.py
index b35f6ef..c8252bb 100644
--- a/codegen/argtypes.py
+++ b/codegen/libcodegen/argtypes.py
@@ -1,5 +1,4 @@
 # -*- Mode: Python; py-indent-offset: 4 -*-
-import string
 import keyword
 import struct
 
@@ -20,7 +19,7 @@ class VarList:
     def __init__(self):
         self.vars = {}
     def add(self, ctype, name):
-        if self.vars.has_key(ctype):
+        if ctype in self.vars:
             self.vars[ctype] = self.vars[ctype] + (name,)
         else:
             self.vars[ctype] = (name,)
@@ -30,11 +29,11 @@ class VarList:
             ret.append('    ')
             ret.append(type)
             ret.append(' ')
-            ret.append(string.join(self.vars[type], ', '))
+            ret.append(', '.join(self.vars[type]))
             ret.append(';\n')
         if ret:
             ret.append('\n')
-            return string.join(ret, '')
+            return ''.join(ret)
         return ''
 
 class WrapperInfo:
@@ -50,18 +49,18 @@ class WrapperInfo:
         self.arglist = []
         self.kwlist = []
     def get_parselist(self):
-        return string.join(self.parselist, ', ')
+        return ', '.join(self.parselist)
     def get_codebefore(self):
-        return string.join(self.codebefore, '')
+        return ''.join(self.codebefore)
     def get_codeafter(self):
-        return string.join(self.codeafter, '')
+        return ''.join(self.codeafter)
     def get_arglist(self):
-        return string.join(self.arglist, ', ')
+        return ', '.join(self.arglist)
     def get_varlist(self):
         return str(self.varlist)
     def get_kwlist(self):
         ret = '    static char *kwlist[] = { %s };\n' % \
-              string.join(self.kwlist + [ 'NULL' ], ', ')
+              ', '.join(self.kwlist + [ 'NULL' ])
         if not self.get_varlist():
             ret = ret + '\n'
         return ret
@@ -79,14 +78,14 @@ class ArgType:
     def write_param(self, ptype, pname, pdflt, pnull, info):
         """Add code to the WrapperInfo instance to handle
         parameter."""
-        raise RuntimeError, "write_param not implemented for %s" % \
-              self.__class__.__name__
+        raise RuntimeError("write_param not implemented for %s" % \
+                           self.__class__.__name__)
     def write_return(self, ptype, ownsreturn, info):
         """Adds a variable named ret of the return type to
         info.varlist, and add any required code to info.codeafter to
         convert the return value to a python object."""
-        raise RuntimeError, "write_return not implemented for %s" % \
-              self.__class__.__name__
+        raise RuntimeError("write_return not implemented for %s" % \
+                           self.__class__.__name__)
 
 class NoneArg(ArgType):
     def write_return(self, ptype, ownsreturn, info):
@@ -110,7 +109,7 @@ class StringArg(ArgType):
             # have to free result ...
             info.varlist.add('gchar', '*ret')
             info.codeafter.append('    if (ret) {\n' +
-                                  '        PyObject *py_ret = PyString_FromString(ret);\n' +
+                                  '        PyObject *py_ret = _PyUnicode_FromString(ret);\n' +
                                   '        g_free(ret);\n' +
                                   '        return py_ret;\n' +
                                   '    }\n' +
@@ -119,7 +118,7 @@ class StringArg(ArgType):
         else:
             info.varlist.add('const gchar', '*ret')
             info.codeafter.append('    if (ret)\n' +
-                                  '        return PyString_FromString(ret);\n'+
+                                  '        return _PyUnicode_FromString(ret);\n'+
                                   '    Py_INCREF(Py_None);\n' +
                                   '    return Py_None;')
 
@@ -152,7 +151,7 @@ class CharArg(ArgType):
         info.add_parselist('c', ['&' + pname], [pname])
     def write_return(self, ptype, ownsreturn, info):
         info.varlist.add('gchar', 'ret')
-        info.codeafter.append('    return PyString_FromStringAndSize(&ret, 1);')
+        info.codeafter.append('    return _PyUnicode_FromStringAndSize(&ret, 1);')
 class GUniCharArg(ArgType):
     ret_tmpl = ('#if !defined(Py_UNICODE_SIZE) || Py_UNICODE_SIZE == 2\n'
                 '    if (ret > 0xffff) {\n'
@@ -185,14 +184,14 @@ class IntArg(ArgType):
         info.add_parselist('i', ['&' + pname], [pname])
     def write_return(self, ptype, ownsreturn, info):
         info.varlist.add('int', 'ret')
-        info.codeafter.append('    return PyInt_FromLong(ret);')
+        info.codeafter.append('    return _PyLong_FromLong(ret);')
 
 class UIntArg(ArgType):
     dflt = ('    if (py_%(name)s) {\n'
             '        if (PyLong_Check(py_%(name)s))\n'
             '            %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
-            '        else if (PyInt_Check(py_%(name)s))\n'
-            '            %(name)s = PyInt_AsLong(py_%(name)s);\n'
+            '        else if (_PyLong_Check(py_%(name)s))\n'
+            '            %(name)s = _PyLong_AsLong(py_%(name)s);\n'
             '        else\n'
             '            PyErr_SetString(PyExc_TypeError, "Parameter \'%(name)s\' must be an int or a long");\n'
             '        if (PyErr_Occurred())\n'
@@ -200,8 +199,8 @@ class UIntArg(ArgType):
             '    }\n')
     before = ('    if (PyLong_Check(py_%(name)s))\n'
               '        %(name)s = PyLong_AsUnsignedLong(py_%(name)s);\n'
-              '    else if (PyInt_Check(py_%(name)s))\n'
-              '        %(name)s = PyInt_AsLong(py_%(name)s);\n'
+              '    else if (_PyLong_Check(py_%(name)s))\n'
+              '        %(name)s = _PyLong_AsLong(py_%(name)s);\n'
               '    else\n'
               '        PyErr_SetString(PyExc_TypeError, "Parameter \'%(name)s\' must be an int or a long");\n'
               '    if (PyErr_Occurred())\n'
@@ -277,7 +276,7 @@ class LongArg(ArgType):
         info.add_parselist('l', ['&' + pname], [pname])
     def write_return(self, ptype, ownsreturn, info):
         info.varlist.add(ptype, 'ret')
-        info.codeafter.append('    return PyInt_FromLong(ret);\n')
+        info.codeafter.append('    return _PyLong_FromLong(ret);\n')
 
 class BoolArg(IntArg):
     def write_return(self, ptype, ownsreturn, info):
@@ -294,7 +293,7 @@ class TimeTArg(ArgType):
         info.add_parselist('i', ['&' + pname], [pname])
     def write_return(self, ptype, ownsreturn, info):
         info.varlist.add('time_t', 'ret')
-        info.codeafter.append('    return PyInt_FromLong(ret);')
+        info.codeafter.append('    return _PyLong_FromLong(ret);')
 
 class ULongArg(ArgType):
     def write_param(self, ptype, pname, pdflt, pnull, info):
@@ -475,7 +474,7 @@ class ObjectArg(ArgType):
            '        %(name)s = %(cast)s(py_%(name)s->obj);\n'
     def __init__(self, objname, parent, typecode):
         self.objname = objname
-        self.cast = string.replace(typecode, '_TYPE_', '_', 1)
+        self.cast = typecode.replace('_TYPE_', '_', 1)
         self.parent = parent
     def write_param(self, ptype, pname, pdflt, pnull, info):
         if pnull:
@@ -695,7 +694,7 @@ class AtomArg(IntArg):
         info.varlist.add('PyObject *', 'py_ret')
         info.varlist.add('gchar *', 'name')
         info.codeafter.append('    name = gdk_atom_name(ret);\n'
-                              '    py_ret = PyString_FromString(name);\n'
+                              '    py_ret = _PyUnicode_FromString(name);\n'
                               '    g_free(name);\n'
                               '    return py_ret;')
 
@@ -867,7 +866,7 @@ class ArgMatcher:
             self.register('GdkBitmap', oa)
             self.register('GdkBitmap*', oa)
     def register_boxed(self, ptype, typecode):
-        if self.argtypes.has_key(ptype): return
+        if ptype in self.argtypes: return
         arg = BoxedArg(ptype, typecode)
         self.register(ptype, arg)
         self.register(ptype+'*', arg)
@@ -934,7 +933,7 @@ class ArgMatcher:
     def object_is_a(self, otype, parent):
         if otype == None: return 0
         if otype == parent: return 1
-        if not self.argtypes.has_key(otype): return 0
+        if otype not in self.argtypes: return 0
         return self.object_is_a(self.get(otype).parent, parent)
 
 matcher = ArgMatcher()
diff --git a/codegen/libcodegen/codegen.py b/codegen/libcodegen/codegen.py
new file mode 100644
index 0000000..538a68c
--- /dev/null
+++ b/codegen/libcodegen/codegen.py
@@ -0,0 +1,1722 @@
+
+import getopt
+import keyword
+import os
+import string
+import sys
+
+from . import argtypes
+from . import definitions
+from . import defsparser
+from . import override
+from . import reversewrapper
+import warnings
+
+class Coverage(object):
+    def __init__(self, name):
+        self.name = name
+        self.wrapped = 0
+        self.not_wrapped = 0
+
+    def declare_wrapped(self):
+        self.wrapped += 1
+
+    def declare_not_wrapped(self):
+        self.not_wrapped += 1
+
+    def printstats(self):
+        total = self.wrapped + self.not_wrapped
+        fd = sys.stderr
+        if total:
+            fd.write("***INFO*** The coverage of %s is %.2f%% (%i/%i)\n" %
+                     (self.name,
+                      float(self.wrapped*100)/total,
+                      self.wrapped,
+                      total))
+        else:
+            fd.write("***INFO*** There are no declared %s.\n" % self.name)
+
+functions_coverage = Coverage("global functions")
+methods_coverage = Coverage("methods")
+vproxies_coverage = Coverage("virtual proxies")
+vaccessors_coverage = Coverage("virtual accessors")
+iproxies_coverage = Coverage("interface proxies")
+
+def exc_info():
+    warnings.warn("deprecated", DeprecationWarning, stacklevel=2)
+    #traceback.print_exc()
+    etype, value, tb = sys.exc_info()
+    ret = ""
+    try:
+        sval = str(value)
+        if etype == argtypes.ArgTypeError:
+            ret = "No ArgType for %s" % (sval,)
+        else:
+            ret = sval
+    finally:
+        del etype, value, tb
+    return ret
+
+def fixname(name):
+    if keyword.iskeyword(name):
+        return name + '_'
+    return name
+
+class FileOutput:
+    '''Simple wrapper for file object, that makes writing #line
+    statements easier.''' # "
+    def __init__(self, fp, filename=None):
+        self.fp = fp
+        self.lineno = 1
+        if filename:
+            self.filename = filename
+        else:
+            self.filename = self.fp.name
+    # handle writing to the file, and keep track of the line number ...
+    def write(self, str):
+        self.fp.write(str)
+        self.lineno = self.lineno + str.count('\n')
+    def writelines(self, sequence):
+        for line in sequence:
+            self.write(line)
+    def close(self):
+        self.fp.close()
+    def flush(self):
+        self.fp.flush()
+
+    def setline(self, linenum, filename):
+        '''writes out a #line statement, for use by the C
+        preprocessor.''' # "
+        self.write('#line %d "%s"\n' % (linenum, filename))
+    def resetline(self):
+        '''resets line numbering to the original file'''
+        self.setline(self.lineno + 1, self.filename)
+
+class Wrapper:
+    type_tmpl = (
+        'PyTypeObject G_GNUC_INTERNAL Py%(typename)s_Type = {\n'
+        '    PyVarObject_HEAD_INIT(NULL, 0)'
+        '    "%(classname)s",                   /* tp_name */\n'
+        '    sizeof(%(tp_basicsize)s),          /* tp_basicsize */\n'
+        '    0,                                 /* tp_itemsize */\n'
+        '    /* methods */\n'
+        '    (destructor)%(tp_dealloc)s,        /* tp_dealloc */\n'
+        '    (printfunc)0,                      /* tp_print */\n'
+        '    (getattrfunc)%(tp_getattr)s,       /* tp_getattr */\n'
+        '    (setattrfunc)%(tp_setattr)s,       /* tp_setattr */\n'
+        '    NULL, //%(tp_compare)s,                    /* tp_compare */\n'
+        '    (reprfunc)%(tp_repr)s,             /* tp_repr */\n'
+        '    (PyNumberMethods*)%(tp_as_number)s,     /* tp_as_number */\n'
+        '    (PySequenceMethods*)%(tp_as_sequence)s, /* tp_as_sequence */\n'
+        '    (PyMappingMethods*)%(tp_as_mapping)s,   /* tp_as_mapping */\n'
+        '    (hashfunc)%(tp_hash)s,             /* tp_hash */\n'
+        '    (ternaryfunc)%(tp_call)s,          /* tp_call */\n'
+        '    (reprfunc)%(tp_str)s,              /* tp_str */\n'
+        '    (getattrofunc)%(tp_getattro)s,     /* tp_getattro */\n'
+        '    (setattrofunc)%(tp_setattro)s,     /* tp_setattro */\n'
+        '    (PyBufferProcs*)%(tp_as_buffer)s,  /* tp_as_buffer */\n'
+        '    %(tp_flags)s,                      /* tp_flags */\n'
+        '    %(tp_doc)s,                        /* Documentation string */\n'
+        '    (traverseproc)%(tp_traverse)s,     /* tp_traverse */\n'
+        '    (inquiry)%(tp_clear)s,             /* tp_clear */\n'
+        '    (richcmpfunc)%(tp_richcompare)s,   /* tp_richcompare */\n'
+        '    %(tp_weaklistoffset)s,             /* tp_weaklistoffset */\n'
+        '    (getiterfunc)%(tp_iter)s,          /* tp_iter */\n'
+        '    (iternextfunc)%(tp_iternext)s,     /* tp_iternext */\n'
+        '    (struct PyMethodDef*)%(tp_methods)s, /* tp_methods */\n'
+        '    (struct PyMemberDef*)0,              /* tp_members */\n'
+        '    (struct PyGetSetDef*)%(tp_getset)s,  /* tp_getset */\n'
+        '    NULL,                              /* tp_base */\n'
+        '    NULL,                              /* tp_dict */\n'
+        '    (descrgetfunc)%(tp_descr_get)s,    /* tp_descr_get */\n'
+        '    (descrsetfunc)%(tp_descr_set)s,    /* tp_descr_set */\n'
+        '    %(tp_dictoffset)s,                 /* tp_dictoffset */\n'
+        '    (initproc)%(tp_init)s,             /* tp_init */\n'
+        '    (allocfunc)%(tp_alloc)s,           /* tp_alloc */\n'
+        '    (newfunc)%(tp_new)s,               /* tp_new */\n'
+        '    (freefunc)%(tp_free)s,             /* tp_free */\n'
+        '    (inquiry)%(tp_is_gc)s              /* tp_is_gc */\n'
+        '};\n\n'
+        )
+
+    slots_list = [
+        'tp_getattr', 'tp_setattr', 'tp_getattro', 'tp_setattro',
+        'tp_compare', 'tp_repr',
+        'tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'tp_hash',
+        'tp_call', 'tp_str', 'tp_as_buffer', 'tp_richcompare', 'tp_iter',
+        'tp_iternext', 'tp_descr_get', 'tp_descr_set', 'tp_init',
+        'tp_alloc', 'tp_new', 'tp_free', 'tp_is_gc',
+        'tp_traverse', 'tp_clear', 'tp_dealloc', 'tp_flags', 'tp_doc'
+        ]
+
+    getter_tmpl = (
+        'static PyObject *\n'
+        '%(funcname)s(PyObject *self, void *closure)\n'
+        '{\n'
+        '%(varlist)s'
+        '    ret = %(field)s;\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+
+    parse_tmpl = (
+        '    if (!PyArg_ParseTupleAndKeywords(args, kwargs,'
+        '"%(typecodes)s:%(name)s"%(parselist)s))\n'
+        '        return %(errorreturn)s;\n'
+        )
+
+    deprecated_tmpl = (
+        '    if (PyErr_Warn(PyExc_DeprecationWarning, '
+        '"%(deprecationmsg)s") < 0)\n'
+        '        return %(errorreturn)s;\n'
+        )
+
+    methdef_tmpl = (
+        '    { "%(name)s", (PyCFunction)%(cname)s, %(flags)s,\n'
+        '      %(docstring)s },\n'
+        )
+
+    noconstructor = (
+        'static int\n'
+        'pygobject_no_constructor(PyObject *self, PyObject *args, '
+        'PyObject *kwargs)\n'
+        '{\n'
+        '    gchar buf[512];\n'
+        '\n'
+        '    g_snprintf(buf, sizeof(buf), "%s is an abstract widget", '
+        'Py_TYPE(self)->tp_name);\n'
+        '    PyErr_SetString(PyExc_NotImplementedError, buf);\n'
+        '    return -1;\n'
+        '}\n\n'
+        )
+
+    function_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    %(begin_allow_threads)s\n'
+        '    %(setreturn)s%(cname)s(%(arglist)s);\n'
+        '    %(end_allow_threads)s\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+
+    virtual_accessor_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyObject *cls%(extraparams)s)\n'
+        '{\n'
+        '    gpointer klass;\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    klass = g_type_class_ref(pyg_type_from_object(cls));\n'
+        '    if (%(class_cast_macro)s(klass)->%(virtual)s)\n'
+        '        %(setreturn)s%(class_cast_macro)s(klass)->'
+        '%(virtual)s(%(arglist)s);\n'
+        '    else {\n'
+        '        PyErr_SetString(PyExc_NotImplementedError, '
+        '"virtual method %(name)s not implemented");\n'
+        '        g_type_class_unref(klass);\n'
+        '        return NULL;\n'
+        '    }\n'
+        '    g_type_class_unref(klass);\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+
+    # template for method calls
+    constructor_tmpl = None
+    method_tmpl = None
+
+    def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)):
+        self.parser = parser
+        self.objinfo = objinfo
+        self.overrides = overrides
+        self.fp = fp
+
+    def get_lower_name(self):
+        return self.objinfo.typecode.replace('_TYPE_', '_', 1).lower()
+
+    def get_field_accessor(self, fieldname):
+        raise NotImplementedError
+
+    def get_initial_class_substdict(self): return {}
+
+    def get_initial_constructor_substdict(self, constructor):
+        return { 'name': '%s.__init__' % self.objinfo.py_name,
+                 'errorreturn': '-1' }
+
+    def get_initial_method_substdict(self, method):
+        substdict = { 'name': '%s.%s' % (self.objinfo.py_name, method.name) }
+        if method.unblock_threads:
+            substdict['begin_allow_threads'] = 'pyg_begin_allow_threads;'
+            substdict['end_allow_threads'] = 'pyg_end_allow_threads;'
+        else:
+            substdict['begin_allow_threads'] = ''
+            substdict['end_allow_threads'] = ''
+        return substdict
+
+    def write_class(self):
+        if self.overrides.is_type_ignored(self.objinfo.c_name):
+            return
+        self.fp.write('\n/* ----------- %s ----------- */\n\n' %
+                      self.objinfo.c_name)
+        substdict = self.get_initial_class_substdict()
+        if 'tp_flags' not in substdict:
+            substdict['tp_flags'] = 'Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE'
+        substdict['typename'] = self.objinfo.c_name
+        if self.overrides.modulename:
+            substdict['classname'] = '%s.%s' % (self.overrides.modulename,
+                                           self.objinfo.name)
+        else:
+            substdict['classname'] = self.objinfo.name
+        substdict['tp_doc'] = self.objinfo.docstring
+
+        # Maybe this could be done in a nicer way, but I'll leave it as it is
+        # for now: -- Johan
+        if not self.overrides.slot_is_overriden('%s.tp_init' %
+                                                self.objinfo.c_name):
+            substdict['tp_init'] = self.write_constructor()
+        substdict['tp_methods'] = self.write_methods()
+        substdict['tp_getset'] = self.write_getsets()
+
+        # handle slots ...
+        for slot in self.slots_list:
+
+            slotname = '%s.%s' % (self.objinfo.c_name, slot)
+            slotfunc = '_wrap_%s_%s' % (self.get_lower_name(), slot)
+            if slot[:6] == 'tp_as_':
+                slotfunc = '&' + slotfunc
+            if self.overrides.slot_is_overriden(slotname):
+                data = self.overrides.slot_override(slotname)
+                self.write_function(slotname, data)
+                substdict[slot] = slotfunc
+            else:
+                if slot not in substdict:
+                    substdict[slot] = '0'
+
+        self.fp.write(self.type_tmpl % substdict)
+
+        self.write_virtuals()
+
+    def write_function_wrapper(self, function_obj, template,
+                               handle_return=0, is_method=0, kwargs_needed=0,
+                               substdict=None):
+        '''This function is the guts of all functions that generate
+        wrappers for functions, methods and constructors.'''
+        if not substdict: substdict = {}
+
+        info = argtypes.WrapperInfo()
+
+        substdict.setdefault('errorreturn', 'NULL')
+
+        # for methods, we want the leading comma
+        if is_method:
+            info.arglist.append('')
+
+        if function_obj.varargs:
+            raise argtypes.ArgTypeNotFoundError("varargs functions not supported")
+
+        for param in function_obj.params:
+            if param.pdflt != None and '|' not in info.parsestr:
+                info.add_parselist('|', [], [])
+            handler = argtypes.matcher.get(param.ptype)
+            handler.write_param(param.ptype, param.pname, param.pdflt,
+                                param.pnull, info)
+
+        substdict['setreturn'] = ''
+        if handle_return:
+            if function_obj.ret not in ('none', None):
+                substdict['setreturn'] = 'ret = '
+            handler = argtypes.matcher.get(function_obj.ret)
+            handler.write_return(function_obj.ret,
+                                 function_obj.caller_owns_return, info)
+
+        if function_obj.deprecated != None:
+            deprecated = self.deprecated_tmpl % {
+                'deprecationmsg': function_obj.deprecated,
+                'errorreturn': substdict['errorreturn'] }
+        else:
+            deprecated = ''
+
+        # if name isn't set, set it to function_obj.name
+        substdict.setdefault('name', function_obj.name)
+
+        if function_obj.unblock_threads:
+            substdict['begin_allow_threads'] = 'pyg_begin_allow_threads;'
+            substdict['end_allow_threads'] = 'pyg_end_allow_threads;'
+        else:
+            substdict['begin_allow_threads'] = ''
+            substdict['end_allow_threads'] = ''
+
+        if self.objinfo:
+            substdict['typename'] = self.objinfo.c_name
+        substdict.setdefault('cname',  function_obj.c_name)
+        substdict['varlist'] = info.get_varlist()
+        substdict['typecodes'] = info.parsestr
+        substdict['parselist'] = info.get_parselist()
+        substdict['arglist'] = info.get_arglist()
+        substdict['codebefore'] = deprecated + (
+            info.get_codebefore().replace(
+            'return NULL', 'return ' + substdict['errorreturn'])
+            )
+        substdict['codeafter'] = (
+            info.get_codeafter().replace(
+                           'return NULL',
+                           'return ' + substdict['errorreturn']))
+
+        if info.parsestr or kwargs_needed:
+            substdict['parseargs'] = self.parse_tmpl % substdict
+            substdict['extraparams'] = ', PyObject *args, PyObject *kwargs'
+            flags = 'METH_VARARGS|METH_KEYWORDS'
+
+            # prepend the keyword list to the variable list
+            substdict['varlist'] = info.get_kwlist() + substdict['varlist']
+        else:
+            substdict['parseargs'] = ''
+            substdict['extraparams'] = ''
+            flags = 'METH_NOARGS'
+
+        return template % substdict, flags
+
+    def write_constructor(self):
+        initfunc = '0'
+        constructor = self.parser.find_constructor(self.objinfo,self.overrides)
+        if not constructor:
+            return self.write_default_constructor()
+
+        funcname = constructor.c_name
+        try:
+            if self.overrides.is_overriden(funcname):
+                data = self.overrides.override(funcname)
+                self.write_function(funcname, data)
+                self.objinfo.has_new_constructor_api = (
+                    self.objinfo.typecode in
+                    self.overrides.newstyle_constructors)
+            else:
+                # ok, a hack to determine if we should use
+                # new-style constructores :P
+                property_based = getattr(self,
+                                         'write_property_based_constructor',
+                                         None)
+                if property_based:
+                    if (len(constructor.params) == 0 or
+                        isinstance(constructor.params[0],
+                                   definitions.Property)):
+                        # write_property_based_constructor is only
+                        # implemented in GObjectWrapper
+                        return self.write_property_based_constructor(
+                            constructor)
+                    else:
+                        sys.stderr.write(
+                            "Warning: generating old-style constructor for:" +
+                            constructor.c_name + '\n')
+
+                # write constructor from template ...
+                code = self.write_function_wrapper(constructor,
+                    self.constructor_tmpl,
+                    handle_return=0, is_method=0, kwargs_needed=1,
+                    substdict=self.get_initial_constructor_substdict(
+                    constructor))[0]
+                self.fp.write(code)
+            initfunc = '_wrap_' + funcname
+        except argtypes.ArgTypeError:
+            ex = sys.exc_info()[1]
+            sys.stderr.write('Could not write constructor for %s: %s\n'
+                             % (self.objinfo.c_name, str(ex)))
+
+            initfunc = self.write_noconstructor()
+        return initfunc
+
+    def write_noconstructor(self):
+        # this is a hack ...
+        if not hasattr(self.overrides, 'no_constructor_written'):
+            self.fp.write(self.noconstructor)
+            self.overrides.no_constructor_written = 1
+        initfunc = 'pygobject_no_constructor'
+        return initfunc
+
+    def write_default_constructor(self):
+        return self.write_noconstructor()
+
+    def get_methflags(self, funcname):
+        if self.overrides.wants_kwargs(funcname):
+            flags = 'METH_VARARGS|METH_KEYWORDS'
+        elif self.overrides.wants_noargs(funcname):
+            flags = 'METH_NOARGS'
+        elif self.overrides.wants_onearg(funcname):
+            flags = 'METH_O'
+        else:
+            flags = 'METH_VARARGS'
+        if self.overrides.is_staticmethod(funcname):
+            flags += '|METH_STATIC'
+        elif self.overrides.is_classmethod(funcname):
+            flags += '|METH_CLASS'
+        return flags
+
+    def write_function(self, funcname, data):
+        lineno, filename = self.overrides.getstartline(funcname)
+        self.fp.setline(lineno, filename)
+        self.fp.write(data)
+        self.fp.resetline()
+        self.fp.write('\n\n')
+
+    def _get_class_virtual_substdict(self, meth, cname, parent):
+        substdict = self.get_initial_method_substdict(meth)
+        substdict['virtual'] = meth.name
+        substdict['cname'] = cname
+        substdict['class_cast_macro'] = parent.typecode.replace(
+            '_TYPE_', '_', 1) + "_CLASS"
+        substdict['typecode'] = self.objinfo.typecode
+        substdict['cast'] = parent.typecode.replace('_TYPE_', '_', 1)
+        return substdict
+
+    def write_methods(self):
+        methods = []
+        klass = self.objinfo.c_name
+        # First, get methods from the defs files
+        for meth in self.parser.find_methods(self.objinfo):
+            method_name = meth.c_name
+            if self.overrides.is_ignored(method_name):
+                continue
+            try:
+                if self.overrides.is_overriden(method_name):
+                    if not self.overrides.is_already_included(method_name):
+                        data = self.overrides.override(method_name)
+                        self.write_function(method_name, data)
+
+                    methflags = self.get_methflags(method_name)
+                else:
+                    # write constructor from template ...
+                    code, methflags = self.write_function_wrapper(meth,
+                        self.method_tmpl, handle_return=1, is_method=1,
+                        substdict=self.get_initial_method_substdict(meth))
+                    self.fp.write(code)
+                methods.append(self.methdef_tmpl %
+                               { 'name':  fixname(meth.name),
+                                 'cname': '_wrap_' + method_name,
+                                 'flags': methflags,
+                                 'docstring': meth.docstring })
+                methods_coverage.declare_wrapped()
+            except argtypes.ArgTypeError:
+                ex = sys.exc_info()[1]
+                methods_coverage.declare_not_wrapped()
+                sys.stderr.write('Could not write method %s.%s: %s\n'
+                                % (klass, meth.name, str(ex)))
+
+        # Now try to see if there are any defined in the override
+        for method_name in self.overrides.get_defines_for(klass):
+            c_name = override.class2cname(klass, method_name)
+            if self.overrides.is_already_included(method_name):
+                continue
+
+            try:
+                data = self.overrides.define(klass, method_name)
+                self.write_function(method_name, data)
+                methflags = self.get_methflags(method_name)
+
+                methods.append(self.methdef_tmpl %
+                               { 'name':  method_name,
+                                 'cname': '_wrap_' + c_name,
+                                 'flags': methflags,
+                                 'docstring': 'NULL' })
+                methods_coverage.declare_wrapped()
+            except argtypes.ArgTypeError:
+                ex = sys.exc_info()[1]
+                methods_coverage.declare_not_wrapped()
+                sys.stderr.write('Could not write method %s.%s: %s\n'
+                                % (klass, method_name, str(ex)))
+
+        # Add GObject virtual method accessors, for chaining to parent
+        # virtuals from subclasses
+        methods += self.write_virtual_accessors()
+
+        if methods:
+            methoddefs = '_Py%s_methods' % self.objinfo.c_name
+            # write the PyMethodDef structure
+            methods.append('    { NULL, NULL, 0, NULL }\n')
+            self.fp.write('static const PyMethodDef %s[] = {\n' % methoddefs)
+            self.fp.write(''.join(methods))
+            self.fp.write('};\n\n')
+        else:
+            methoddefs = 'NULL'
+        return methoddefs
+
+    def write_virtual_accessors(self):
+        klass = self.objinfo.c_name
+        methods = []
+        for meth in self.parser.find_virtuals(self.objinfo):
+            method_name = self.objinfo.c_name + "__do_" + meth.name
+            if self.overrides.is_ignored(method_name):
+                continue
+            try:
+                if self.overrides.is_overriden(method_name):
+                    if not self.overrides.is_already_included(method_name):
+                        data = self.overrides.override(method_name)
+                        self.write_function(method_name, data)
+                    methflags = self.get_methflags(method_name)
+                else:
+                    # temporarily add a 'self' parameter as first argument
+                    meth.params.insert(0, definitions.Parameter(
+                        ptype=(self.objinfo.c_name + '*'),
+                        pname='self', pdflt=None, pnull=None))
+                    try:
+                        # write method from template ...
+                        code, methflags = self.write_function_wrapper(
+                            meth, self.virtual_accessor_tmpl,
+                            handle_return=True, is_method=False,
+                            substdict=self._get_class_virtual_substdict(
+                            meth, method_name, self.objinfo))
+                        self.fp.write(code)
+                    finally:
+                        del meth.params[0]
+                methods.append(self.methdef_tmpl %
+                               { 'name':  "do_" + fixname(meth.name),
+                                 'cname': '_wrap_' + method_name,
+                                 'flags': methflags + '|METH_CLASS',
+                                 'docstring': 'NULL'})
+                vaccessors_coverage.declare_wrapped()
+            except argtypes.ArgTypeError:
+                ex = sys.exc_info()[1]
+                vaccessors_coverage.declare_not_wrapped()
+                sys.stderr.write(
+                    'Could not write virtual accessor method %s.%s: %s\n'
+                    % (klass, meth.name, str(ex)))
+        return methods
+
+    def write_virtuals(self):
+        '''
+        Write _wrap_FooBar__proxy_do_zbr() reverse wrapers for
+        GObject virtuals
+        '''
+        klass = self.objinfo.c_name
+        virtuals = []
+        for meth in self.parser.find_virtuals(self.objinfo):
+            method_name = self.objinfo.c_name + "__proxy_do_" + meth.name
+            if self.overrides.is_ignored(method_name):
+                continue
+            try:
+                if self.overrides.is_overriden(method_name):
+                    if not self.overrides.is_already_included(method_name):
+                        data = self.overrides.override(method_name)
+                        self.write_function(method_name, data)
+                else:
+                    # write virtual proxy ...
+                    ret, props = argtypes.matcher.get_reverse_ret(meth.ret)
+                    wrapper = reversewrapper.ReverseWrapper(
+                        '_wrap_' + method_name, is_static=True)
+                    wrapper.set_return_type(ret(wrapper, **props))
+                    wrapper.add_parameter(reversewrapper.PyGObjectMethodParam(
+                        wrapper, "self", method_name="do_" + meth.name,
+                        c_type=(klass + ' *')))
+                    for param in meth.params:
+                        handler, props = argtypes.matcher.get_reverse(
+                            param.ptype)
+                        props["direction"] = param.pdir
+                        wrapper.add_parameter(handler(wrapper,
+                                                      param.pname, **props))
+                    buf = reversewrapper.MemoryCodeSink()
+                    wrapper.generate(buf)
+                    self.fp.write(buf.flush())
+                virtuals.append((fixname(meth.name), '_wrap_' + method_name))
+                vproxies_coverage.declare_wrapped()
+            except argtypes.ArgTypeError:
+                ex = sys.exc_info()[1]
+                vproxies_coverage.declare_not_wrapped()
+                virtuals.append((fixname(meth.name), None))
+                sys.stderr.write('Could not write virtual proxy %s.%s: %s\n'
+                                % (klass, meth.name, str(ex)))
+        if virtuals:
+            # Write a 'pygtk class init' function for this object,
+            # except when the object type is explicitly ignored (like
+            # GtkPlug and GtkSocket on win32).
+            if self.overrides.is_ignored(self.objinfo.typecode):
+                return
+            class_cast_macro = self.objinfo.typecode.replace(
+                '_TYPE_', '_', 1) + "_CLASS"
+            cast_macro = self.objinfo.typecode.replace('_TYPE_', '_', 1)
+            funcname = "__%s_class_init" % klass
+            self.objinfo.class_init_func = funcname
+            have_implemented_virtuals = not not [True
+                                                 for name, cname in virtuals
+                                                     if cname is not None]
+            self.fp.write(
+            ('\nstatic int\n'
+             '%(funcname)s(gpointer gclass, PyTypeObject *pyclass)\n'
+             '{\n') % vars())
+
+            if have_implemented_virtuals:
+                self.fp.write('    PyObject *o;\n')
+                self.fp.write(
+                    '    %(klass)sClass *klass = '
+                    '%(class_cast_macro)s(gclass);\n'
+                    '    PyObject *gsignals = '
+                    'PyDict_GetItemString(pyclass->tp_dict, "__gsignals__");\n'
+                    % vars())
+
+            for name, cname in virtuals:
+                do_name = 'do_' + name
+                if cname is None:
+                    self.fp.write('\n    /* overriding %(do_name)s '
+                                  'is currently not supported */\n' % vars())
+                else:
+                    self.fp.write('''
+    o = PyObject_GetAttrString((PyObject *) pyclass, "%(do_name)s");
+    if (o == NULL)
+        PyErr_Clear();
+    else {
+        if (!PyObject_TypeCheck(o, &PyCFunction_Type)
+            && !(gsignals && PyDict_GetItemString(gsignals, "%(name)s")))
+            klass->%(name)s = %(cname)s;
+        Py_DECREF(o);
+    }
+''' % vars())
+            self.fp.write('    return 0;\n}\n')
+
+    def write_getsets(self):
+        lower_name = self.get_lower_name()
+        getsets_name = lower_name + '_getsets'
+        getterprefix = '_wrap_' + lower_name + '__get_'
+        setterprefix = '_wrap_' + lower_name + '__set_'
+
+        # no overrides for the whole function.  If no fields,
+        # don't write a func
+        if not self.objinfo.fields:
+            return '0'
+        getsets = []
+        for ftype, cfname in self.objinfo.fields:
+            fname = cfname.replace('.', '_')
+            gettername = '0'
+            settername = '0'
+            attrname = self.objinfo.c_name + '.' + fname
+            if self.overrides.attr_is_overriden(attrname):
+                code = self.overrides.attr_override(attrname)
+                self.write_function(attrname, code)
+                if code.find(getterprefix + fname) >= 0:
+                    gettername = getterprefix + fname
+                if code.find(setterprefix + fname) >= 0:
+                    settername = setterprefix + fname
+            if gettername == '0':
+                try:
+                    funcname = getterprefix + fname
+                    info = argtypes.WrapperInfo()
+                    handler = argtypes.matcher.get(ftype)
+                    # for attributes, we don't own the "return value"
+                    handler.write_return(ftype, 0, info)
+                    self.fp.write(self.getter_tmpl %
+                                  { 'funcname': funcname,
+                                    'varlist': info.varlist,
+                                    'field': self.get_field_accessor(cfname),
+                                    'codeafter': info.get_codeafter() })
+                    gettername = funcname
+                except argtypes.ArgTypeError:
+                    ex = sys.exc_info()[1]
+                    sys.stderr.write(
+                        "Could not write getter for %s.%s: %s\n"
+                        % (self.objinfo.c_name, fname, str(ex)))
+            if gettername != '0' or settername != '0':
+                getsets.append('    { "%s", (getter)%s, (setter)%s },\n' %
+                               (fixname(fname), gettername, settername))
+
+        if not getsets:
+            return '0'
+        self.fp.write('static const PyGetSetDef %s[] = {\n' % getsets_name)
+        for getset in getsets:
+            self.fp.write(getset)
+        self.fp.write('    { NULL, (getter)0, (setter)0 },\n')
+        self.fp.write('};\n\n')
+
+        return getsets_name
+
+    def _write_get_symbol_names(self, writer, functions):
+        self.fp.write("""static PyObject *
+_wrap__get_symbol_names(PyObject *self)
+{
+    PyObject *pylist = PyList_New(0);
+
+""")
+        for obj, bases in writer.get_classes():
+            self.fp.write('    PyList_Append(pylist, '
+                          '_PyUnicode_FromString("%s"));\n' % (obj.name))
+
+        for name, cname, flags, docstring in functions:
+            self.fp.write('    PyList_Append(pylist, '
+                          '_PyUnicode_FromString("%s"));\n' % (name))
+
+        for enum in writer.get_enums():
+            self.fp.write('    PyList_Append(pylist, '
+                          '_PyUnicode_FromString("%s"));\n' % (enum.name))
+            for nick, value in enum.values:
+                name = value[len(self.overrides.modulename)+1:]
+                self.fp.write('    PyList_Append(pylist, '
+                              '_PyUnicode_FromString("%s"));\n' % (name))
+
+        self.fp.write("    return pylist;\n}\n\n");
+
+    def _write_get_symbol(self, writer, functions):
+        self.fp.write("""static PyObject *
+_wrap__get_symbol(PyObject *self, PyObject *args)
+{
+    PyObject *d;
+    char *name;
+    static PyObject *modulename = NULL;
+    static PyObject *module = NULL;
+    static char *strip_prefix = "%s";
+
+    if (!PyArg_ParseTuple(args, "Os", &d, &name))
+        return NULL;
+
+    if (!modulename)
+       modulename = _PyUnicode_FromString("%s");
+
+    if (!module)
+       module = PyDict_GetItemString(d, "__module__");
+
+""" % (self.overrides.modulename.upper() + '_',
+       self.overrides.modulename))
+
+        first = True
+        # Classes / GObjects
+        for obj, bases in writer.get_classes():
+            if first:
+                self.fp.write('    if (!strcmp(name, "%s")) {\n' % obj.name)
+                first = False
+            else:
+                self.fp.write('    } else if (!strcmp(name, "%s")) {\n' % obj.name)
+            self.fp.write(
+                '       return (PyObject*)pygobject_lookup_class(%s);\n' %
+                obj.typecode)
+        self.fp.write('    }\n')
+
+        # Functions
+        for name, cname, flags, docstring in functions:
+            self.fp.write('    else if (!strcmp(name, "%s")) {\n' % name)
+            self.fp.write('        static PyMethodDef ml = { '
+                          '"%s", (PyCFunction)%s, %s, "%s"};\n' % (
+                name, cname, flags, docstring))
+            self.fp.write('        return PyCFunction_NewEx(&ml, NULL, modulename);\n')
+            self.fp.write('    }\n')
+
+        # Enums
+        def write_enum(enum, returnobj=False):
+            if returnobj:
+                ret = 'return '
+            else:
+                ret = ''
+            if enum.deftype == 'enum':
+                self.fp.write(
+                    '        %spyg_enum_add(module, "%s", strip_prefix, %s);\n'
+                    % (ret, enum.name, enum.typecode))
+            else:
+                self.fp.write(
+                    '    %spyg_flags_add(module, "%s", strip_prefix, %s);\n'
+                    % (ret, enum.name, enum.typecode))
+
+        strip_len = len(self.overrides.modulename)+1 # GTK_
+        for enum in writer.get_enums():
+            # XXX: Implement without typecodes
+            self.fp.write('    else if (!strcmp(name, "%s")) {\n' % enum.name)
+            write_enum(enum, returnobj=True)
+            self.fp.write('    }\n')
+
+            for nick, value in enum.values:
+                value = value[strip_len:]
+                self.fp.write('    else if (!strcmp(name, "%s")) {\n' % value)
+                write_enum(enum)
+                self.fp.write('        return PyObject_GetAttrString(module, "%s");\n' %
+                              value)
+                self.fp.write('    }\n')
+
+        self.fp.write('    return Py_None;\n}\n\n');
+
+    def _write_function_bodies(self):
+        functions = []
+        # First, get methods from the defs files
+        for func in self.parser.find_functions():
+            funcname = func.c_name
+            if self.overrides.is_ignored(funcname):
+                continue
+            try:
+                if self.overrides.is_overriden(funcname):
+                    data = self.overrides.override(funcname)
+                    self.write_function(funcname, data)
+
+                    methflags = self.get_methflags(funcname)
+                else:
+                    # write constructor from template ...
+                    code, methflags = self.write_function_wrapper(func,
+                        self.function_tmpl, handle_return=1, is_method=0)
+                    self.fp.write(code)
+                functions.append((func.name, '_wrap_' + funcname,
+                                  methflags, func.docstring))
+                functions_coverage.declare_wrapped()
+            except argtypes.ArgTypeError:
+                ex = sys.exc_info()[1]
+                functions_coverage.declare_not_wrapped()
+                sys.stderr.write('Could not write function %s: %s\n'
+                                 % (func.name, str(ex)))
+
+        # Now try to see if there are any defined in the override
+        for funcname in self.overrides.get_functions():
+            try:
+                data = self.overrides.function(funcname)
+                self.write_function(funcname, data)
+                methflags = self.get_methflags(funcname)
+                functions.append((funcname, '_wrap_' + funcname,
+                                  methflags, 'NULL'))
+                functions_coverage.declare_wrapped()
+            except argtypes.ArgTypeError:
+                ex = sys.exc_info()[1]
+                functions_coverage.declare_not_wrapped()
+                sys.stderr.write('Could not write function %s: %s\n'
+                                 % (funcname, str(ex)))
+        return functions
+
+    def write_functions(self, writer, prefix):
+        self.fp.write('\n/* ----------- functions ----------- */\n\n')
+        functions = []
+        func_infos = self._write_function_bodies()
+
+        # If we have a dynamic namespace, write symbol and attribute getter
+        if self.overrides.dynamicnamespace:
+            self._write_get_symbol_names(writer, func_infos)
+            self._write_get_symbol(writer, func_infos)
+            for obj, bases in writer.get_classes():
+                self.fp.write("""static PyTypeObject *
+%s_register_type(const gchar *name, PyObject *unused)
+{
+    PyObject *m = PyImport_ImportModule("gtk");
+    PyObject *d = PyModule_GetDict(m);
+""" % obj.c_name)
+                writer.write_class(obj, bases, indent=1)
+                self.fp.write(
+                    '    return (%s)PyDict_GetItemString(d, "%s");\n' % (
+                    'PyTypeObject*', obj.name))
+                self.fp.write("}\n")
+
+            functions.append('    { "_get_symbol_names", '
+                             '(PyCFunction)_wrap__get_symbol_names, '
+                             'METH_NOARGS, NULL },\n')
+            functions.append('    { "_get_symbol", '
+                             '(PyCFunction)_wrap__get_symbol, '
+                             'METH_VARARGS, NULL },\n')
+        else:
+            for name, cname, flags, docstring in func_infos:
+                functions.append(self.methdef_tmpl % dict(name=name,
+                                                          cname=cname,
+                                                          flags=flags,
+                                                          docstring=docstring))
+
+        # write the PyMethodDef structure
+        functions.append('    { NULL, NULL, 0, NULL }\n')
+
+        self.fp.write('const PyMethodDef ' + prefix + '_functions[] = {\n')
+        self.fp.write(''.join(functions))
+        self.fp.write('};\n\n')
+
+class GObjectWrapper(Wrapper):
+    constructor_tmpl = (
+        'static int\n'
+        '_wrap_%(cname)s(PyGObject *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    self->obj = (GObject *)%(cname)s(%(arglist)s);\n'
+        '%(codeafter)s\n'
+        '    if (!self->obj) {\n'
+        '        PyErr_SetString(PyExc_RuntimeError, '
+        '"could not create %(typename)s object");\n'
+        '        return -1;\n'
+        '    }\n'
+        '%(aftercreate)s'
+        '    pygobject_register_wrapper((PyObject *)self);\n'
+        '    return 0;\n'
+        '}\n\n'
+        )
+
+    method_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyGObject *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    %(begin_allow_threads)s\n'
+        '    %(setreturn)s%(cname)s(%(cast)s(self->obj)%(arglist)s);\n'
+        '    %(end_allow_threads)s\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+    def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)):
+        Wrapper.__init__(self, parser, objinfo, overrides, fp)
+        if self.objinfo:
+            self.castmacro = self.objinfo.typecode.replace(
+                                            '_TYPE_', '_', 1)
+
+    def get_initial_class_substdict(self):
+        return { 'tp_basicsize'      : 'PyGObject',
+                 'tp_weaklistoffset' : 'offsetof(PyGObject, weakreflist)',
+                 'tp_dictoffset'     : 'offsetof(PyGObject, inst_dict)' }
+
+    def get_field_accessor(self, fieldname):
+        castmacro = self.objinfo.typecode.replace('_TYPE_', '_', 1)
+        return '%s(pygobject_get(self))->%s' % (castmacro, fieldname)
+
+    def get_initial_constructor_substdict(self, constructor):
+        substdict = Wrapper.get_initial_constructor_substdict(self,
+                                                              constructor)
+        if not constructor.caller_owns_return:
+            substdict['aftercreate'] = "    g_object_ref(self->obj);\n"
+        else:
+            substdict['aftercreate'] = ''
+        return substdict
+
+    def get_initial_method_substdict(self, method):
+        substdict = Wrapper.get_initial_method_substdict(self, method)
+        substdict['cast'] = self.objinfo.typecode.replace(
+                                           '_TYPE_', '_', 1)
+        return substdict
+
+    def write_default_constructor(self):
+        try:
+            parent = self.parser.find_object(self.objinfo.parent)
+        except ValueError:
+            parent = None
+        if parent is not None:
+            ## just like the constructor is inheritted, we should
+            # inherit the new API compatibility flag
+            self.objinfo.has_new_constructor_api = (
+                parent.has_new_constructor_api)
+        elif self.objinfo.parent == 'GObject':
+            self.objinfo.has_new_constructor_api = True
+        return '0'
+
+    def write_property_based_constructor(self, constructor):
+        self.objinfo.has_new_constructor_api = True
+        out = self.fp
+        out.write("static int\n")
+        out.write('_wrap_%s(PyGObject *self, PyObject *args,' \
+              ' PyObject *kwargs)\n{\n\n' % constructor.c_name)
+        if constructor.params:
+            s = "    GType obj_type = pyg_type_from_object((PyObject *) self);\n"
+            out.write(s)
+
+        def py_str_list_to_c(arg):
+            if arg:
+                return "{" + ", ".join(
+                    map(lambda s: '"' + s + '"', arg)) + ", NULL }"
+            else:
+                return "{ NULL }"
+
+        classname = '%s.%s' % (self.overrides.modulename,
+                               self.objinfo.name)
+
+        if constructor.params:
+            mandatory_arguments = [param for param in constructor.params
+                                             if not param.optional]
+            optional_arguments = [param for param in constructor.params
+                                            if param.optional]
+            arg_names = py_str_list_to_c(
+            [param.argname
+             for param in mandatory_arguments + optional_arguments])
+
+            prop_names = py_str_list_to_c(
+            [param.pname
+             for param in mandatory_arguments + optional_arguments])
+
+            out.write("    GParameter params[%i];\n" % \
+                  len(constructor.params))
+            out.write("    PyObject *parsed_args[%i] = {NULL, };\n" % \
+                  len(constructor.params))
+            out.write("    char *arg_names[] = %s;\n" % arg_names)
+            out.write("    char *prop_names[] = %s;\n" % prop_names)
+            out.write("    guint nparams, i;\n\n")
+            if constructor.deprecated is not None:
+                out.write(
+                    '    if (PyErr_Warn(PyExc_DeprecationWarning, '
+                    '"%s") < 0)\n' %
+                    constructor.deprecated)
+                out.write('        return -1;\n\n')
+            out.write("    if (!PyArg_ParseTupleAndKeywords(args, kwargs, \n")
+            template = '"'
+            if mandatory_arguments:
+                template += "O"*len(mandatory_arguments)
+            if optional_arguments:
+                template += "|" + "O"*len(optional_arguments)
+            template += ':%s.__init__"' % classname
+            out.write(template + " , arg_names")
+            for i in range(len(constructor.params)):
+                out.write(", &parsed_args[%i]" % i)
+
+            out.write(
+                "))\n"
+                "        return -1;\n"
+                "\n"
+                "    memset(params, 0, sizeof(GParameter)*%i);\n"
+                "    if (!pyg_parse_constructor_args(obj_type, arg_names,\n"
+                "                                    prop_names, params, \n"
+                "                                    &nparams, parsed_args))\n"
+                "        return -1;\n"
+                "    pygobject_constructv(self, nparams, params);\n"
+                "    for (i = 0; i < nparams; ++i)\n"
+                "        g_value_unset(&params[i].value);\n\n"
+                % len(constructor.params))
+        else:
+            out.write(
+                "    static char* kwlist[] = { NULL };\n"
+                "\n")
+
+            if constructor.deprecated is not None:
+                out.write(
+                    '    if (PyErr_Warn(PyExc_DeprecationWarning, "%s") < 0)\n'
+                    '        return -1;\n'
+                    '\n' % constructor.deprecated)
+
+            out.write(
+                '    if (!PyArg_ParseTupleAndKeywords(args, kwargs,\n'
+                '                                     ":%s.__init__",\n'
+                '                                     kwlist))\n'
+                '        return -1;\n'
+                '\n'
+                '    pygobject_constructv(self, 0, NULL);\n' % classname)
+        out.write(
+            '    if (!self->obj) {\n'
+            '        PyErr_SetString(\n'
+            '            PyExc_RuntimeError, \n'
+            '            "could not create %s object");\n'
+            '        return -1;\n'
+            '    }\n' % classname)
+
+        if not constructor.caller_owns_return:
+            out.write("    g_object_ref(self->obj);\n\n")
+
+        out.write(
+            '    return 0;\n'
+            '}\n\n')
+
+        return "_wrap_%s" % constructor.c_name
+
+
+class GInterfaceWrapper(GObjectWrapper):
+    virtual_accessor_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyObject *cls%(extraparams)s)\n'
+        '{\n'
+        '    %(vtable)s *iface;\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    iface = g_type_interface_peek('
+        'g_type_class_peek(pyg_type_from_object(cls)), %(typecode)s);\n'
+        '    if (iface->%(virtual)s)\n'
+        '        %(setreturn)siface->%(virtual)s(%(arglist)s);\n'
+        '    else {\n'
+        '        PyErr_SetString(PyExc_NotImplementedError, '
+        '"interface method %(name)s not implemented");\n'
+        '        return NULL;\n'
+        '    }\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+
+    def get_initial_class_substdict(self):
+        return { 'tp_basicsize'      : 'PyObject',
+                 'tp_weaklistoffset' : '0',
+                 'tp_dictoffset'     : '0'}
+
+    def write_constructor(self):
+        # interfaces have no constructors ...
+        return '0'
+    def write_getsets(self):
+        # interfaces have no fields ...
+        return '0'
+
+    def _get_class_virtual_substdict(self, meth, cname, parent):
+        substdict = self.get_initial_method_substdict(meth)
+        substdict['virtual'] = meth.name
+        substdict['cname'] = cname
+        substdict['typecode'] = self.objinfo.typecode
+        substdict['vtable'] = self.objinfo.vtable
+        return substdict
+
+    def write_virtuals(self):
+        ## Now write reverse method wrappers, which let python code
+        ## implement interface methods.
+        # First, get methods from the defs files
+        klass = self.objinfo.c_name
+        proxies = []
+        for meth in self.parser.find_virtuals(self.objinfo):
+            method_name = self.objinfo.c_name + "__proxy_do_" + meth.name
+            if self.overrides.is_ignored(method_name):
+                continue
+            try:
+                if self.overrides.is_overriden(method_name):
+                    if not self.overrides.is_already_included(method_name):
+                        data = self.overrides.override(method_name)
+                        self.write_function(method_name, data)
+                else:
+                    # write proxy ...
+                    ret, props = argtypes.matcher.get_reverse_ret(meth.ret)
+                    wrapper = reversewrapper.ReverseWrapper(
+                        '_wrap_' + method_name, is_static=True)
+                    wrapper.set_return_type(ret(wrapper, **props))
+                    wrapper.add_parameter(reversewrapper.PyGObjectMethodParam(
+                        wrapper, "self", method_name="do_" + meth.name,
+                        c_type=(klass + ' *')))
+                    for param in meth.params:
+                        handler, props = argtypes.matcher.get_reverse(
+                            param.ptype)
+                        props["direction"] = param.pdir
+                        wrapper.add_parameter(
+                            handler(wrapper, param.pname, **props))
+                    buf = reversewrapper.MemoryCodeSink()
+                    wrapper.generate(buf)
+                    self.fp.write(buf.flush())
+                proxies.append((fixname(meth.name), '_wrap_' + method_name))
+                iproxies_coverage.declare_wrapped()
+            except argtypes.ArgTypeError:
+                ex = sys.exc_info()[1]
+                iproxies_coverage.declare_not_wrapped()
+                proxies.append((fixname(meth.name), None))
+                sys.stderr.write('Could not write interface proxy %s.%s: %s\n'
+                                % (klass, meth.name, str(ex)))
+
+        if not proxies or not [cname for name, cname in proxies if cname]:
+            return
+
+        ## Write an interface init function for this object
+        funcname = "__%s__interface_init" % klass
+        vtable = self.objinfo.vtable
+        self.fp.write(
+            '\nstatic void\n'
+            '%(funcname)s(%(vtable)s *iface, PyTypeObject *pytype)\n'
+            '{\n'
+            '    %(vtable)s *parent_iface = '
+            'g_type_interface_peek_parent(iface);\n'
+            '    PyObject *py_method;\n'
+            '\n'
+            % vars())
+
+        for name, cname in proxies:
+            do_name = 'do_' + name
+            if cname is None:
+                continue
+
+            self.fp.write((
+                '    py_method = pytype? PyObject_GetAttrString('
+                '(PyObject *) pytype, "%(do_name)s") : NULL;\n'
+                '    if (py_method && !PyObject_TypeCheck(py_method, '
+                '&PyCFunction_Type)) {\n'
+                '        iface->%(name)s = %(cname)s;\n'
+                '    } else {\n'
+                '        PyErr_Clear();\n'
+                '        if (parent_iface) {\n'
+                '            iface->%(name)s = parent_iface->%(name)s;\n'
+                '        }\n'
+                '    Py_XDECREF(py_method);\n'
+                '    }\n'
+                ) % vars())
+        self.fp.write('}\n\n')
+        interface_info = "__%s__iinfo" % klass
+        self.fp.write('''
+static const GInterfaceInfo %s = {
+    (GInterfaceInitFunc) %s,
+    NULL,
+    NULL
+};
+''' % (interface_info, funcname))
+        self.objinfo.interface_info = interface_info
+
+class GBoxedWrapper(Wrapper):
+    constructor_tmpl = (
+        'static int\n'
+        '_wrap_%(cname)s(PyGBoxed *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    self->gtype = %(typecode)s;\n'
+        '    self->free_on_dealloc = FALSE;\n'
+        '    self->boxed = %(cname)s(%(arglist)s);\n'
+        '%(codeafter)s\n'
+        '    if (!self->boxed) {\n'
+        '        PyErr_SetString(PyExc_RuntimeError, '
+        '"could not create %(typename)s object");\n'
+        '        return -1;\n'
+        '    }\n'
+        '    self->free_on_dealloc = TRUE;\n'
+        '    return 0;\n'
+        '}\n\n'
+        )
+
+    method_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    %(begin_allow_threads)s\n'
+        '    %(setreturn)s%(cname)s(pyg_boxed_get(self, '
+        '%(typename)s)%(arglist)s);\n'
+        '    %(end_allow_threads)s\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+
+    def get_initial_class_substdict(self):
+        return { 'tp_basicsize'      : 'PyGBoxed',
+                 'tp_weaklistoffset' : '0',
+                 'tp_dictoffset'     : '0' }
+
+    def get_field_accessor(self, fieldname):
+        return 'pyg_boxed_get(self, %s)->%s' % (self.objinfo.c_name, fieldname)
+
+    def get_initial_constructor_substdict(self, constructor):
+        substdict = Wrapper.get_initial_constructor_substdict(
+            self, constructor)
+        substdict['typecode'] = self.objinfo.typecode
+        return substdict
+
+class GPointerWrapper(GBoxedWrapper):
+    constructor_tmpl = (
+        'static int\n'
+        '_wrap_%(cname)s(PyGPointer *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    self->gtype = %(typecode)s;\n'
+        '    self->pointer = %(cname)s(%(arglist)s);\n'
+        '%(codeafter)s\n'
+        '    if (!self->pointer) {\n'
+        '        PyErr_SetString(PyExc_RuntimeError, '
+        '"could not create %(typename)s object");\n'
+        '        return -1;\n'
+        '    }\n'
+        '    return 0;\n'
+        '}\n\n'
+        )
+
+    method_tmpl = (
+        'static PyObject *\n'
+        '_wrap_%(cname)s(PyObject *self%(extraparams)s)\n'
+        '{\n'
+        '%(varlist)s'
+        '%(parseargs)s'
+        '%(codebefore)s'
+        '    %(setreturn)s%(cname)s(pyg_pointer_get(self, '
+        '%(typename)s)%(arglist)s);\n'
+        '%(codeafter)s\n'
+        '}\n\n'
+        )
+
+    def get_initial_class_substdict(self):
+        return { 'tp_basicsize'      : 'PyGPointer',
+                 'tp_weaklistoffset' : '0',
+                 'tp_dictoffset'     : '0' }
+
+    def get_field_accessor(self, fieldname):
+        return 'pyg_pointer_get(self, %s)->%s' % (self.objinfo.c_name,
+                                                  fieldname)
+
+    def get_initial_constructor_substdict(self, constructor):
+        substdict = Wrapper.get_initial_constructor_substdict(
+            self, constructor)
+        substdict['typecode'] = self.objinfo.typecode
+        return substdict
+
+class SourceWriter:
+    def __init__(self, parser, overrides, prefix, fp=FileOutput(sys.stdout)):
+        self.parser = parser
+        self.overrides = overrides
+        self.prefix = prefix
+        self.fp = fp
+
+    def write(self, py_ssize_t_clean=False):
+        argtypes.py_ssize_t_clean = py_ssize_t_clean
+
+        self.write_headers(py_ssize_t_clean)
+        self.write_imports()
+        self.write_type_declarations()
+        self.write_body()
+        self.write_classes()
+
+        wrapper = Wrapper(self.parser, None, self.overrides, self.fp)
+        wrapper.write_functions(self, self.prefix)
+
+        if not self.overrides.dynamicnamespace:
+            self.write_enums()
+        self.write_extension_init()
+        self.write_registers()
+        
+        argtypes.py_ssize_t_clean = False
+
+    def write_headers(self, py_ssize_t_clean):
+        self.fp.write('/* -- THIS FILE IS GENERATED - DO NOT EDIT */')
+        self.fp.write('/* -*- Mode: C; c-basic-offset: 4 -*- */\n\n')
+        if py_ssize_t_clean:
+            self.fp.write('#define PY_SSIZE_T_CLEAN\n')
+        self.fp.write('#include <Python.h>\n\n\n')
+        if py_ssize_t_clean:
+            self.fp.write('''
+
+#if PY_VERSION_HEX < 0x02050000
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+typedef inquiry lenfunc;
+typedef intargfunc ssizeargfunc;
+typedef intobjargproc ssizeobjargproc;
+#endif
+
+''')
+        self.fp.write(self.overrides.get_headers())
+        self.fp.resetline()
+        self.fp.write('\n\n')
+
+    def write_imports(self):
+        self.fp.write('/* ---------- types from other modules ---------- */\n')
+        for module, pyname, cname, importing_for in self.overrides.get_imports():
+            if importing_for is None or is_registered_object(importing_for):
+                self.fp.write('static PyTypeObject *_%s;\n' % cname)
+                self.fp.write('#define %s (*_%s)\n' % (cname, cname))
+        self.fp.write('\n\n')
+
+    def write_type_declarations(self):
+        #todo use 'static' if used only in one file
+        self.fp.write('/* ---------- forward type declarations ---------- */\n')
+        for obj in self.parser.boxes:
+            if not self.overrides.is_type_ignored(obj.c_name):
+                self.fp.write('PyTypeObject G_GNUC_INTERNAL Py' + obj.c_name + '_Type;\n')
+        for obj in self.parser.objects:
+            if not self.overrides.is_type_ignored(obj.c_name):
+                self.fp.write('PyTypeObject G_GNUC_INTERNAL Py' + obj.c_name + '_Type;\n')
+        for interface in self.parser.interfaces:
+            if not self.overrides.is_type_ignored(interface.c_name):
+                self.fp.write('PyTypeObject G_GNUC_INTERNAL Py' + interface.c_name + '_Type;\n')
+        self.fp.write('\n')
+
+    def write_body(self):
+        self.fp.write(self.overrides.get_body())
+        self.fp.resetline()
+        self.fp.write('\n\n')
+
+    def _sort_parent_children(self, objects):
+        objects = list(objects)
+        modified = True
+        while modified:
+            modified = False
+            parent_index = None
+            child_index = None
+            for i, obj in enumerate(objects):
+                if obj.parent == 'GObject':
+                    continue
+                if obj.parent not in [info.c_name for info in objects[:i]]:
+                    for j, info in enumerate(objects[i+1:]):
+                        if info.c_name == obj.parent:
+                            parent_index = i + 1 + j
+                            child_index = i
+                            break
+                    else:
+                        continue
+                    break
+            if child_index is not None and parent_index is not None:
+                if child_index != parent_index:
+                    objects.insert(child_index, objects.pop(parent_index))
+                    modified = True
+        return objects
+
+    def write_classes(self):
+        ## Sort the objects, so that we generate code for the parent types
+        ## before their children.
+        objects = self._sort_parent_children(self.parser.objects)
+
+        for klass, items in ((GBoxedWrapper, self.parser.boxes),
+                             (GPointerWrapper, self.parser.pointers),
+                             (GObjectWrapper, objects),
+                             (GInterfaceWrapper, self.parser.interfaces)):
+            for item in items:
+                instance = klass(self.parser, item, self.overrides, self.fp)
+                instance.write_class()
+                self.fp.write('\n')
+
+    def get_enums(self):
+        enums = []
+        for enum in self.parser.enums:
+            if self.overrides.is_type_ignored(enum.c_name):
+                continue
+            enums.append(enum)
+        return enums
+
+    def write_enums(self):
+        if not self.parser.enums:
+            return
+
+        self.fp.write('\n/* ----------- enums and flags ----------- */\n\n')
+        self.fp.write(
+            'void\n' + self.prefix +
+            '_add_constants(PyObject *module, const gchar *strip_prefix)\n{\n')
+
+        self.fp.write(
+            '#ifdef VERSION\n'
+            '    PyModule_AddStringConstant(module, "__version__", VERSION);\n'
+            '#endif\n')
+
+        for enum in self.get_enums():
+            if enum.typecode is None:
+                for nick, value in enum.values:
+                    self.fp.write(
+                        '    PyModule_AddIntConstant(module, '
+                        '(char *) pyg_constant_strip_prefix("%s", strip_prefix), %s);\n'
+                        % (value, value))
+            else:
+                if enum.deftype == 'enum':
+                    self.fp.write('  pyg_enum_add(module, "%s", strip_prefix, %s);\n'
+                                  % (enum.name, enum.typecode))
+                else:
+                    self.fp.write('  pyg_flags_add(module, "%s", strip_prefix, %s);\n'
+                                  % (enum.name, enum.typecode))
+
+        self.fp.write('\n')
+        self.fp.write('  if (PyErr_Occurred())\n')
+        self.fp.write('    PyErr_Print();\n')
+        self.fp.write('}\n\n')
+
+    def write_object_imports(self, retval=''):
+        imports = self.overrides.get_imports()[:]
+        if not imports:
+            return
+
+        bymod = {}
+        for module, pyname, cname, importing_for in imports:
+            if importing_for is None or is_registered_object(importing_for):
+                bymod.setdefault(module, []).append((pyname, cname))
+        self.fp.write('    PyObject *module;\n\n')
+        for module in bymod:
+            self.fp.write(
+                '    if ((module = PyImport_ImportModule("%s")) != NULL) {\n'
+                % module)
+            #self.fp.write(
+            #    '        PyObject *moddict = PyModule_GetDict(module);\n\n')
+            for pyname, cname in bymod[module]:
+                #self.fp.write(
+                #    '        _%s = (PyTypeObject *)PyDict_GetItemString('
+                #    'moddict, "%s");\n' % (cname, pyname))
+                self.fp.write(
+                    '        _%s = (PyTypeObject *)PyObject_GetAttrString('
+                    'module, "%s");\n' % (cname, pyname))
+                self.fp.write('        if (_%s == NULL) {\n' % cname)
+                self.fp.write('            PyErr_SetString(PyExc_ImportError,\n')
+                self.fp.write('                "cannot import name %s from %s");\n'
+                         % (pyname, module))
+                self.fp.write('            return %s;\n' % retval)
+                self.fp.write('        }\n')
+            self.fp.write('    } else {\n')
+            self.fp.write('        PyErr_SetString(PyExc_ImportError,\n')
+            self.fp.write('            "could not import %s");\n' % module)
+            self.fp.write('        return %s;\n' % retval)
+            self.fp.write('    }\n')
+        self.fp.write('\n')
+
+    def write_extension_init(self):
+        self.fp.write('/* initialise stuff extension classes */\n')
+        self.fp.write('void\n' + self.prefix + '_register_classes(PyObject *d)\n{\n')
+        self.write_object_imports()
+        self.fp.write(self.overrides.get_init() + '\n')
+        self.fp.resetline()
+
+    def get_classes(self):
+        objects = self.parser.objects[:]
+        pos = 0
+        while pos < len(objects):
+            parent = objects[pos].parent
+            for i in range(pos+1, len(objects)):
+                if objects[i].c_name == parent:
+                    objects.insert(i+1, objects[pos])
+                    del objects[pos]
+                    break
+            else:
+                pos = pos + 1
+
+        retval = []
+        for obj in objects:
+            if self.overrides.is_type_ignored(obj.c_name):
+                continue
+            bases = []
+            if obj.parent != None:
+                bases.append(obj.parent)
+            bases = bases + obj.implements
+            retval.append((obj, bases))
+
+        return retval
+
+    def write_registers(self):
+        for boxed in self.parser.boxes:
+            if not self.overrides.is_type_ignored(boxed.c_name):
+                self.fp.write('    pyg_register_boxed(d, "' + boxed.name +
+                              '", ' + boxed.typecode +
+                              ', &Py' + boxed.c_name +
+                          '_Type);\n')
+        for pointer in self.parser.pointers:
+            if not self.overrides.is_type_ignored(pointer.c_name):
+                self.fp.write('    pyg_register_pointer(d, "' + pointer.name +
+                              '", ' + pointer.typecode +
+                              ', &Py' + pointer.c_name + '_Type);\n')
+        for interface in self.parser.interfaces:
+            if not self.overrides.is_type_ignored(interface.c_name):
+                self.fp.write('    pyg_register_interface(d, "'
+                              + interface.name + '", '+ interface.typecode
+                              + ', &Py' + interface.c_name + '_Type);\n')
+                if interface.interface_info is not None:
+                    self.fp.write('    pyg_register_interface_info(%s, &%s);\n' %
+                                  (interface.typecode, interface.interface_info))
+
+        if not self.overrides.dynamicnamespace:
+            for obj, bases in self.get_classes():
+                self.write_class(obj, bases)
+        else:
+            for obj, bases in self.get_classes():
+                self.fp.write(
+                    '    pyg_type_register_custom_callback("%s", '
+                    '(PyGTypeRegistrationFunction)%s_register_type, d);\n' %
+                    (obj.c_name, obj.c_name))
+
+        self.fp.write('}\n')
+
+    def _can_direct_ref(self, base):
+        if not self.overrides.dynamicnamespace:
+            return True
+        if base == 'GObject':
+            return True
+        obj = get_object_by_name(base)
+        if obj.module.lower() != self.overrides.modulename:
+            return True
+        return False
+
+    def write_class(self, obj, bases, indent=1):
+        indent_str = ' ' * (indent * 4)
+        if bases:
+            bases_str = 'Py_BuildValue("(%s)"' % (len(bases) * 'O')
+
+            for base in bases:
+                if self._can_direct_ref(base):
+                    bases_str += ', &Py%s_Type' % base
+                else:
+                    baseobj = get_object_by_name(base)
+                    bases_str += ', PyObject_GetAttrString(m, "%s")' % baseobj.name
+            bases_str += ')'
+        else:
+            bases_str = 'NULL'
+
+        self.fp.write(
+                '%(indent)spygobject_register_class(d, "%(c_name)s", %(typecode)s, &Py%(c_name)s_Type, %(bases)s);\n'
+                % dict(indent=indent_str, c_name=obj.c_name, typecode=obj.typecode, bases=bases_str))
+
+        if obj.has_new_constructor_api:
+            self.fp.write(
+                indent_str + 'pyg_set_object_has_new_constructor(%s);\n' %
+                obj.typecode)
+        else:
+            sys.stderr.write(
+                "Warning: Constructor for %s needs to be updated to new API\n"
+                "         See http://live.gnome.org/PyGTK_2fWhatsNew28";
+                "#update-constructors\n" % obj.c_name)
+
+        if obj.class_init_func is not None:
+            self.fp.write(
+                indent_str + 'pyg_register_class_init(%s, %s);\n' %
+                (obj.typecode, obj.class_init_func))
+
+_objects = {}
+
+def is_registered_object(c_name):
+    return c_name in _objects
+
+def get_object_by_name(c_name):
+    global _objects
+    return _objects[c_name]
+
+def register_types(parser):
+    global _objects
+    for boxed in parser.boxes:
+        argtypes.matcher.register_boxed(boxed.c_name, boxed.typecode)
+        _objects[boxed.c_name] = boxed
+    for pointer in parser.pointers:
+        argtypes.matcher.register_pointer(pointer.c_name, pointer.typecode)
+    for obj in parser.objects:
+        argtypes.matcher.register_object(obj.c_name, obj.parent, obj.typecode)
+        _objects[obj.c_name] = obj
+    for iface in parser.interfaces:
+        argtypes.matcher.register_object(iface.c_name, None, iface.typecode)
+        _objects[iface.c_name] = iface
+    for enum in parser.enums:
+        if enum.deftype == 'flags':
+            argtypes.matcher.register_flag(enum.c_name, enum.typecode)
+        else:
+            argtypes.matcher.register_enum(enum.c_name, enum.typecode)
+
+usage = 'usage: codegen.py [-o overridesfile] [-p prefix] defsfile'
+def main(argv):
+    o = override.Overrides()
+    prefix = 'pygtk'
+    outfilename = None
+    errorfilename = None
+    opts, args = getopt.getopt(argv[1:], "o:p:r:t:D:I:",
+                        ["override=", "prefix=", "register=", "outfilename=",
+                         "load-types=", "errorfilename=", "py_ssize_t-clean"])
+    defines = {} # -Dkey[=val] options
+    py_ssize_t_clean = False
+    for opt, arg in opts:
+        if opt in ('-o', '--override'):
+            o = override.Overrides(arg)
+        elif opt in ('-p', '--prefix'):
+            prefix = arg
+        elif opt in ('-r', '--register'):
+            # Warning: user has to make sure all -D options appear before -r
+            p = defsparser.DefsParser(arg, defines)
+            p.startParsing()
+            register_types(p)
+            del p
+        elif opt == '--outfilename':
+            outfilename = arg
+        elif opt == '--errorfilename':
+            errorfilename = arg
+        elif opt in ('-t', '--load-types'):
+            globals = {}
+            execfile(arg, globals)
+        elif opt == '-D':
+            nameval = arg.split('=')
+            try:
+                defines[nameval[0]] = nameval[1]
+            except IndexError:
+                defines[nameval[0]] = None
+        elif opt == '-I':
+            defsparser.include_path.insert(0, arg)
+        elif opt == '--py_ssize_t-clean':
+            py_ssize_t_clean = True
+    if len(args) < 1:
+        print >> sys.stderr, usage
+        return 1
+    if errorfilename:
+        sys.stderr = open(errorfilename, "w")
+    p = defsparser.DefsParser(args[0], defines)
+    if not outfilename:
+        outfilename = os.path.splitext(args[0])[0] + '.c'
+
+    p.startParsing()
+
+    register_types(p)
+    sw = SourceWriter(p, o, prefix, FileOutput(sys.stdout, outfilename))
+    sw.write(py_ssize_t_clean)
+
+    functions_coverage.printstats()
+    methods_coverage.printstats()
+    vproxies_coverage.printstats()
+    vaccessors_coverage.printstats()
+    iproxies_coverage.printstats()
+
diff --git a/codegen/definitions.py b/codegen/libcodegen/definitions.py
similarity index 97%
rename from codegen/definitions.py
rename to codegen/libcodegen/definitions.py
index aca5adb..bab0ecb 100644
--- a/codegen/definitions.py
+++ b/codegen/libcodegen/definitions.py
@@ -71,15 +71,15 @@ class Definition(object):
     def __init__(self, *args):
         """Create a new defs object of this type.  The arguments are the
         components of the definition"""
-        raise RuntimeError, "this is an abstract class"
+        raise RuntimeError("this is an abstract class")
 
     def merge(self, old):
         """Merge in customisations from older version of definition"""
-        raise RuntimeError, "this is an abstract class"
+        raise RuntimeError("this is an abstract class")
 
     def write_defs(self, fp=sys.stdout):
         """write out this definition in defs file format"""
-        raise RuntimeError, "this is an abstract class"
+        raise RuntimeError("this is an abstract class")
 
     def guess_return_value_ownership(self):
         "return 1 if caller owns return value"
@@ -210,7 +210,7 @@ class EnumDef(Definition):
 
 class FlagsDef(EnumDef):
     def __init__(self, *args):
-        apply(EnumDef.__init__, (self,) + args)
+        EnumDef.__init__(self, *args)
         self.deftype = 'flags'
 
 class BoxedDef(Definition):
@@ -407,7 +407,7 @@ class MethodDef(MethodDefBase):
         for item in ('c_name', 'of_object'):
             if self.__dict__[item] == None:
                 self.write_defs(sys.stderr)
-                raise RuntimeError, "definition missing required %s" % (item,)
+                raise RuntimeError("definition missing required %s" % (item,))
 
     def write_defs(self, fp=sys.stdout):
         fp.write('(define-method ' + self.name + '\n')
@@ -491,7 +491,7 @@ class FunctionDef(Definition):
         for item in ('c_name',):
             if self.__dict__[item] == None:
                 self.write_defs(sys.stderr)
-                raise RuntimeError, "definition missing required %s" % (item,)
+                raise RuntimeError("definition missing required %s" % (item,))
 
     _method_write_defs = MethodDef.__dict__['write_defs']
 
@@ -513,8 +513,8 @@ class FunctionDef(Definition):
                     else:
                         param.merge(old_param)
                         return param
-            raise RuntimeError, "could not find %s in old_parameters %r" % (
-                param.pname, [p.pname for p in old.params])
+            raise RuntimeError("could not find %s in old_parameters %r" % (
+                param.pname, [p.pname for p in old.params]))
         try:
             self.params = map(merge_param, self.params)
         except RuntimeError:
diff --git a/codegen/libcodegen/defsparser.py b/codegen/libcodegen/defsparser.py
new file mode 100644
index 0000000..b901f31
--- /dev/null
+++ b/codegen/libcodegen/defsparser.py
@@ -0,0 +1,153 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+import os, sys
+from . import scmexpr
+from .definitions import BoxedDef, EnumDef, FlagsDef, FunctionDef, \
+     InterfaceDef, MethodDef, ObjectDef, PointerDef, VirtualDef
+
+include_path = ['.']
+
+class IncludeParser(scmexpr.Parser):
+    """A simple parser that follows include statements automatically"""
+    def include(self, input_filename):
+        global include_path
+        if os.path.isabs(input_filename):
+            filename = input_filename
+            # set self.filename to the include name, to handle recursive includes
+            oldfile = self.filename
+            self.filename = filename
+            self.startParsing()
+            self.filename = oldfile
+        else:
+            inc_path = [os.path.dirname(self.filename)] + include_path
+            for filename in [os.path.join(path_entry, input_filename)
+                             for path_entry in inc_path]:
+                if not os.path.exists(filename):
+                    continue
+                # set self.filename to the include name, to handle recursive includes
+                oldfile = self.filename
+                self.filename = filename
+                self.startParsing()
+                self.filename = oldfile
+                break
+            else:
+                raise IOError("%s not found in include path %s" % (input_filename, inc_path))
+
+class DefsParser(IncludeParser):
+    def __init__(self, arg, defines={}):
+        IncludeParser.__init__(self, arg)
+        self.objects = []
+        self.interfaces = []
+        self.enums = []      # enums and flags
+        self.boxes = []      # boxed types
+        self.pointers = []   # pointer types
+        self.functions = []  # functions and methods
+        self.virtuals = []   # virtual methods
+        self.c_name = {}     # hash of c names of functions
+        self.methods = {}    # hash of methods of particular objects
+        self.defines = defines      # -Dfoo=bar options, as dictionary
+
+    def define_object(self, *args):
+        odef = ObjectDef(*args)
+        self.objects.append(odef)
+        self.c_name[odef.c_name] = odef
+    def define_interface(self, *args):
+        idef = InterfaceDef(*args)
+        self.interfaces.append(idef)
+        self.c_name[idef.c_name] = idef
+    def define_enum(self, *args):
+        edef = EnumDef(*args)
+        self.enums.append(edef)
+        self.c_name[edef.c_name] = edef
+    def define_flags(self, *args):
+        fdef = FlagsDef(*args)
+        self.enums.append(fdef)
+        self.c_name[fdef.c_name] = fdef
+    def define_boxed(self, *args):
+        bdef = BoxedDef(*args)
+        self.boxes.append(bdef)
+        self.c_name[bdef.c_name] = bdef
+    def define_pointer(self, *args):
+        pdef = PointerDef(*args)
+        self.pointers.append(pdef)
+        self.c_name[pdef.c_name] = pdef
+    def define_function(self, *args):
+        fdef = FunctionDef(*args)
+        self.functions.append(fdef)
+        self.c_name[fdef.c_name] = fdef
+    def define_method(self, *args):
+        mdef = MethodDef(*args)
+        self.functions.append(mdef)
+        self.c_name[mdef.c_name] = mdef
+    def define_virtual(self, *args):
+        vdef = VirtualDef(*args)
+        self.virtuals.append(vdef)
+    def merge(self, old, parmerge):
+        for obj in self.objects:
+            if obj.c_name in old.c_name:
+                obj.merge(old.c_name[obj.c_name])
+        for f in self.functions:
+            if f.c_name in old.c_name:
+                f.merge(old.c_name[f.c_name], parmerge)
+
+    def printMissing(self, old):
+        for obj in self.objects:
+            if obj.c_name not in old.c_name:
+                obj.write_defs()
+        for f in self.functions:
+            if f.c_name not in old.c_name:
+                f.write_defs()
+
+    def write_defs(self, fp=sys.stdout):
+        for obj in self.objects:
+            obj.write_defs(fp)
+        for enum in self.enums:
+            enum.write_defs(fp)
+        for boxed in self.boxes:
+            boxed.write_defs(fp)
+        for pointer in self.pointers:
+            pointer.write_defs(fp)
+        for func in self.functions:
+            func.write_defs(fp)
+
+    def find_object(self, c_name):
+        for obj in self.objects:
+            if obj.c_name == c_name:
+                return obj
+        else:
+            raise ValueError('object %r not found' % c_name)
+
+    def find_constructor(self, obj, overrides):
+        for func in self.functions:
+            if isinstance(func, FunctionDef) and \
+               func.is_constructor_of == obj.c_name and \
+               not overrides.is_ignored(func.c_name):
+                return func
+
+    def find_methods(self, obj):
+        objname = obj.c_name
+        return filter(lambda func, on=objname: isinstance(func, MethodDef) and
+                      func.of_object == on, self.functions)
+
+    def find_virtuals(self, obj):
+        objname = obj.c_name
+        retval = filter(lambda func, on=objname: isinstance(func, VirtualDef) and
+                        func.of_object == on, self.virtuals)
+        return retval
+
+    def find_functions(self):
+        return filter(lambda func: isinstance(func, FunctionDef) and
+                      not func.is_constructor_of, self.functions)
+
+    def ifdef(self, *args):
+        if args[0] in self.defines:
+            for arg in args[1:]:
+                #print >> sys.stderr, "-----> Handling conditional definition (%s): %s" % (args[0], arg)
+                self.handle(arg)
+        else:
+            pass
+            #print >> sys.stderr, "-----> Conditional %s is not true" % (args[0],)
+
+    def ifndef(self, *args):
+        if args[0] not in self.defines:
+            for arg in args[1:]:
+                self.handle(arg)
diff --git a/codegen/libcodegen/docextract.py b/codegen/libcodegen/docextract.py
new file mode 100644
index 0000000..027afbc
--- /dev/null
+++ b/codegen/libcodegen/docextract.py
@@ -0,0 +1,185 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+'''Simple module for extracting GNOME style doc comments from C
+sources, so I can use them for other purposes.'''
+
+import sys, os, string, re
+
+__all__ = ['extract']
+
+class FunctionDoc:
+    def __init__(self):
+        self.name = None
+        self.params = []
+        self.description = ''
+        self.ret = ''
+    def set_name(self, name):
+        self.name = name
+    def add_param(self, name, description):
+        if name == '...':
+            name = 'Varargs'
+        self.params.append((name, description))
+    def append_to_last_param(self, extra):
+        self.params[-1] = (self.params[-1][0], self.params[-1][1] + extra)
+    def append_to_named_param(self, name, extra):
+        for i in range(len(self.params)):
+            if self.params[i][0] == name:
+                self.params[i] = (name, self.params[i][1] + extra)
+                return
+        # fall through to adding extra parameter ...
+        self.add_param(name, extra)
+    def append_description(self, extra):
+        self.description = self.description + extra
+    def append_return(self, extra):
+        self.ret = self.ret + extra
+
+    def get_param_description(self, name):
+        for param, description in self.params:
+            if param == name:
+                return description
+        else:
+            return ''
+
+comment_start_pat = re.compile(r'^\s*/\*\*\s')
+comment_end_pat = re.compile(r'^\s*\*+/')
+comment_line_lead = re.compile(r'^\s*\*\s*')
+funcname_pat = re.compile(r'^(\w+)\s*:?')
+return_pat = re.compile(r'^(returns:|return\s+value:|returns\s*)(.*\n?)$',
+                        re.IGNORECASE)
+param_pat = re.compile(r'^@(\S+)\s*:(.*\n?)$')
+
+def parse_file(fp, doc_dict):
+    line = fp.readline()
+    in_comment_block = 0
+    while line:
+        if not in_comment_block:
+            if comment_start_pat.match(line):
+                in_comment_block = 1
+                cur_doc = FunctionDoc()
+                in_description = 0
+                in_return = 0
+            line = fp.readline()
+            continue
+
+        # we are inside a comment block ...
+        if comment_end_pat.match(line):
+            if not cur_doc.name:
+                sys.stderr.write("no function name found in doc comment\n")
+            else:
+                doc_dict[cur_doc.name] = cur_doc
+            in_comment_block = 0
+            line = fp.readline()
+            continue
+
+        # inside a comment block, and not the end of the block ...
+        line = comment_line_lead.sub('', line)
+        if not line: line = '\n'
+
+        if not cur_doc.name:
+            match = funcname_pat.match(line)
+            if match:
+                cur_doc.set_name(match.group(1))
+        elif in_return:
+            match = return_pat.match(line)
+            if match:
+                # assume the last return statement was really part of the
+                # description
+                return_start = match.group(1)
+                cur_doc.ret = match.group(2)
+                cur_doc.description = cur_doc.description + return_start + \
+                                      cur_doc.ret
+            else:
+                cur_doc.append_return(line)
+        elif in_description:
+            if line[:12] == 'Description:':
+                line = line[12:]
+            match = return_pat.match(line)
+            if match:
+                in_return = 1
+                return_start = match.group(1)
+                cur_doc.append_return(match.group(2))
+            else:
+                cur_doc.append_description(line)
+        elif line == '\n':
+            # end of parameters
+            in_description = 1
+        else:
+            match = param_pat.match(line)
+            if match:
+                param = match.group(1)
+                desc = match.group(2)
+                if param == 'returns':
+                    cur_doc.ret = desc
+                else:
+                    cur_doc.add_param(param, desc)
+            else:
+                # must be continuation
+                try:
+                    if param == 'returns':
+                        cur_doc.append_return(line)
+                    else:
+                        cur_doc.append_to_last_param(line)
+                except:
+                    sys.stderr.write('something weird while reading param\n')
+        line = fp.readline()
+
+def parse_dir(dir, doc_dict):
+    for file in os.listdir(dir):
+        if file in ('.', '..'): continue
+        path = os.path.join(dir, file)
+        if os.path.isdir(path):
+            parse_dir(path, doc_dict)
+        if len(file) > 2 and file[-2:] == '.c':
+            parse_file(open(path, 'r'), doc_dict)
+
+def extract(dirs, doc_dict=None):
+    if not doc_dict: doc_dict = {}
+    for dir in dirs:
+        parse_dir(dir, doc_dict)
+    return doc_dict
+
+tmpl_section_pat = re.compile(r'^<!-- ##### (\w+) (\w+) ##### -->$')
+def parse_tmpl(fp, doc_dict):
+    cur_doc = None
+
+    line = fp.readline()
+    while line:
+        match = tmpl_section_pat.match(line)
+        if match:
+            cur_doc = None  # new input shouldn't affect the old doc dict
+            sect_type = match.group(1)
+            sect_name = match.group(2)
+
+            if sect_type == 'FUNCTION':
+                cur_doc = doc_dict.get(sect_name)
+                if not cur_doc:
+                    cur_doc = FunctionDoc()
+                    cur_doc.set_name(sect_name)
+                    doc_dict[sect_name] = cur_doc
+        elif line == '<!-- # Unused Parameters # -->\n':
+            cur_doc = None # don't worry about unused params.
+        elif cur_doc:
+            if line[:10] == '@Returns: ':
+                if line[10:].strip():
+                    cur_doc.append_return(line[10:])
+            elif line[0] == '@':
+                pos = line.find(':')
+                if pos >= 0:
+                    cur_doc.append_to_named_param(line[1:pos], line[pos+1:])
+                else:
+                    cur_doc.append_description(line)
+            else:
+                cur_doc.append_description(line)
+
+        line = fp.readline()
+
+def extract_tmpl(dirs, doc_dict=None):
+    if not doc_dict: doc_dict = {}
+    for dir in dirs:
+        for file in os.listdir(dir):
+            if file in ('.', '..'): continue
+            path = os.path.join(dir, file)
+            if os.path.isdir(path):
+                continue
+            if len(file) > 2 and file[-2:] == '.sgml':
+                parse_tmpl(open(path, 'r'), doc_dict)
+    return doc_dict
diff --git a/codegen/libcodegen/override.py b/codegen/libcodegen/override.py
new file mode 100644
index 0000000..5caa893
--- /dev/null
+++ b/codegen/libcodegen/override.py
@@ -0,0 +1,285 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+
+# this file contains code for loading up an override file.  The override file
+# provides implementations of functions where the code generator could not
+# do its job correctly.
+
+import fnmatch
+import os
+import re
+import string
+import sys
+
+def class2cname(klass, method):
+    c_name = ''
+    for c in klass:
+        if c.isupper():
+            c_name += '_' + c.lower()
+        else:
+            c_name += c
+    return c_name[1:] + '_'  + method
+
+# import python_type as c_name [for arg_type]
+# Last ('for') clause is optional.  If present, the type will be
+# imported only if given 'arg_type' is registered.
+import_pat = re.compile(r'\s*import\s+(\S+)\.([^\s.]+)\s+as\s+(\S+)(\s+for\s+(\S+))?')
+
+class Overrides:
+    def __init__(self, filename=None):
+        self.modulename = None
+        self.ignores = {}
+        self.glob_ignores = []
+        self.type_ignores = {}
+        self.overrides = {}
+        self.overridden = {}
+        self.kwargs = {}
+        self.noargs = {}
+        self.onearg = {}
+        self.staticmethod = {}
+        self.classmethod = {}
+        self.startlines = {}
+        self.override_attrs = {}
+        self.override_slots = {}
+        self.headers = ''
+        self.body = ''
+        self.init = ''
+        self.imports = []
+        self.defines = {}
+        self.functions = {}
+        self.newstyle_constructors = {}
+        self.dynamicnamespace = False
+        if filename:
+            self.handle_file(filename)
+
+    def handle_file(self, filename):
+        oldpath = os.getcwd()
+
+        fp = open(filename, 'r')
+        dirname = os.path.dirname(os.path.abspath(filename))
+
+        if dirname != oldpath:
+            os.chdir(dirname)
+
+        # read all the components of the file ...
+        bufs = []
+        startline = 1
+        lines = []
+        line = fp.readline()
+        linenum = 1
+        while line:
+            if line == '%%\n' or line == '%%':
+                if lines:
+                    bufs.append((''.join(lines), startline))
+                startline = linenum + 1
+                lines = []
+            else:
+                lines.append(line)
+            line = fp.readline()
+            linenum = linenum + 1
+        if lines:
+            bufs.append((''.join(lines), startline))
+        if not bufs: return
+
+        for buf, startline in bufs:
+            self.__parse_override(buf, startline, filename)
+
+        os.chdir(oldpath)
+
+    def __parse_override(self, buffer, startline, filename):
+        pos = buffer.find('\n')
+        if pos >= 0:
+            line = buffer[:pos]
+            rest = buffer[pos+1:]
+        else:
+            line = buffer ; rest = ''
+        words = line.split()
+        command = words[0]
+        if (command == 'ignore' or
+            command == 'ignore-' + sys.platform):
+            "ignore/ignore-platform [functions..]"
+            for func in words[1:]:
+                self.ignores[func] = 1
+            for func in rest.split():
+                self.ignores[func] = 1
+        elif (command == 'ignore-glob' or
+              command == 'ignore-glob-' + sys.platform):
+            "ignore-glob/ignore-glob-platform [globs..]"
+            for func in words[1:]:
+                self.glob_ignores.append(func)
+            for func in rest.split():
+                self.glob_ignores.append(func)
+        elif (command == 'ignore-type' or
+              command == 'ignore-type-' + sys.platform):
+            "ignore-type/ignore-type-platform [typenames..]"
+            for typename in words[1:]:
+                self.type_ignores[typename] = 1
+            for typename in rest.split():
+                self.type_ignores[typename] = 1
+        elif command == 'override':
+            "override function/method [kwargs|noargs|onearg] [staticmethod|classmethod]"
+            func = words[1]
+            if 'kwargs' in words[1:]:
+                self.kwargs[func] = 1
+            elif 'noargs' in words[1:]:
+                self.noargs[func] = 1
+            elif 'onearg' in words[1:]:
+                self.onearg[func] = True
+
+            if 'staticmethod' in words[1:]:
+                self.staticmethod[func] = True
+            elif 'classmethod' in words[1:]:
+                self.classmethod[func] = True
+            if func in self.overrides:
+                raise RuntimeError("Function %s is being overridden more than once" % (func,))
+            self.overrides[func] = rest
+            self.startlines[func] = (startline + 1, filename)
+        elif command == 'override-attr':
+            "override-slot Class.attr"
+            attr = words[1]
+            self.override_attrs[attr] = rest
+            self.startlines[attr] = (startline + 1, filename)
+        elif command == 'override-slot':
+            "override-slot Class.slot"
+            slot = words[1]
+            self.override_slots[slot] = rest
+            self.startlines[slot] = (startline + 1, filename)
+        elif command == 'headers':
+            "headers"
+            self.headers = '%s\n#line %d "%s"\n%s' % \
+                           (self.headers, startline + 1, filename, rest)
+        elif command == 'body':
+            "body"
+            self.body = '%s\n#line %d "%s"\n%s' % \
+                           (self.body, startline + 1, filename, rest)
+        elif command == 'init':
+            "init"
+            self.init = '%s\n#line %d "%s"\n%s' % \
+                        (self.init, startline + 1, filename, rest)
+        elif command == 'modulename':
+            "modulename name"
+            self.modulename = words[1]
+        elif command == 'include':
+            "include filename"
+            for filename in words[1:]:
+                self.handle_file(filename)
+            for filename in rest.split():
+                self.handle_file(filename)
+        elif command == 'import':
+            "import module1 [\n module2, \n module3 ...]"
+            for line in buffer.split('\n'):
+                match = import_pat.match(line)
+                if match:
+                    module, pyname, cname, conditional, importing_for = match.groups()
+                    self.imports.append((module, pyname, cname, importing_for or None))
+        elif command == 'define':
+            "define funcname [kwargs|noargs|onearg] [classmethod|staticmethod]"
+            "define Class.method [kwargs|noargs|onearg] [classmethod|staticmethod]"
+            func = words[1]
+            klass = None
+            if func.find('.') != -1:
+                klass, func = func.split('.', 1)
+
+                if klass not in self.defines:
+                    self.defines[klass] = {}
+                self.defines[klass][func] = rest
+            else:
+                self.functions[func] = rest
+
+            if 'kwargs' in words[1:]:
+                self.kwargs[func] = 1
+            elif 'noargs' in words[1:]:
+                self.noargs[func] = 1
+            elif 'onearg' in words[1:]:
+                self.onearg[func] = 1
+
+            if 'staticmethod' in words[1:]:
+                self.staticmethod[func] = True
+            elif 'classmethod' in words[1:]:
+                self.classmethod[func] = True
+
+            self.startlines[func] = (startline + 1, filename)
+
+        elif command == 'new-constructor':
+            "new-constructor GType"
+            gtype, = words[1:]
+            self.newstyle_constructors[gtype] = True
+        elif command == 'options':
+            for option in words[1:]:
+                if option == 'dynamicnamespace':
+                    self.dynamicnamespace = True
+
+    def is_ignored(self, name):
+        if name in self.ignores:
+            return 1
+        for glob in self.glob_ignores:
+            if fnmatch.fnmatchcase(name, glob):
+                return 1
+        return 0
+
+    def is_type_ignored(self, name):
+        return name in self.type_ignores
+
+    def is_overriden(self, name):
+        return name in self.overrides
+
+    def is_already_included(self, name):
+        return name in self.overridden
+
+    def override(self, name):
+        self.overridden[name] = 1
+        return self.overrides[name]
+
+    def define(self, klass, name):
+        self.overridden[class2cname(klass, name)] = 1
+        return self.defines[klass][name]
+
+    def function(self, name):
+        return self.functions[name]
+
+    def getstartline(self, name):
+        return self.startlines[name]
+
+    def wants_kwargs(self, name):
+        return name in self.kwargs
+
+    def wants_noargs(self, name):
+        return name in self.noargs
+
+    def wants_onearg(self, name):
+        return name in self.onearg
+
+    def is_staticmethod(self, name):
+        return name in self.staticmethod
+
+    def is_classmethod(self, name):
+        return name in self.classmethod
+
+    def attr_is_overriden(self, attr):
+        return attr in self.override_attrs
+
+    def attr_override(self, attr):
+        return self.override_attrs[attr]
+
+    def slot_is_overriden(self, slot):
+        return slot in self.override_slots
+
+    def slot_override(self, slot):
+        return self.override_slots[slot]
+
+    def get_headers(self):
+        return self.headers
+
+    def get_body(self):
+        return self.body
+
+    def get_init(self):
+        return self.init
+
+    def get_imports(self):
+        return self.imports
+
+    def get_defines_for(self, klass):
+        return self.defines.get(klass, {})
+
+    def get_functions(self):
+        return self.functions
diff --git a/codegen/reversewrapper.py b/codegen/libcodegen/reversewrapper.py
similarity index 99%
rename from codegen/reversewrapper.py
rename to codegen/libcodegen/reversewrapper.py
index ed48629..27ebb2e 100644
--- a/codegen/reversewrapper.py
+++ b/codegen/libcodegen/reversewrapper.py
@@ -1,7 +1,7 @@
 ### -*- python -*-
 ### Code to generate "Reverse Wrappers", i.e. C->Python wrappers
 ### (C) 2004 Gustavo Carneiro <gjc gnome org>
-import argtypes
+from . import argtypes
 import os
 
 DEBUG_MODE = ('PYGTK_CODEGEN_DEBUG' in os.environ)
@@ -404,13 +404,13 @@ class StringParam(Parameter):
         if self.props.get('optional', False):
             self.wrapper.add_declaration("PyObject *py_%s = NULL;" % self.name)
             self.wrapper.write_code(code=("if (%s)\n"
-                                          "    py_%s = PyString_FromString(%s);\n"
+                                          "    py_%s = _PyUnicode_FromString(%s);\n"
                                           % (self.name, self.name, self.name)),
                                     cleanup=("Py_XDECREF(py_%s);" % self.name))
             self.wrapper.add_pyargv_item("py_%s" % self.name, optional=True)
         else:
             self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
-            self.wrapper.write_code(code=("py_%s = PyString_FromString(%s);" %
+            self.wrapper.write_code(code=("py_%s = _PyUnicode_FromString(%s);" %
                                           (self.name, self.name)),
                                     cleanup=("Py_DECREF(py_%s);" % self.name),
                                     failure_expression=("!py_%s" % self.name))
@@ -526,7 +526,7 @@ class IntParam(Parameter):
 
     def convert_c2py(self):
         self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
-        self.wrapper.write_code(code=("py_%s = PyInt_FromLong(%s);" %
+        self.wrapper.write_code(code=("py_%s = _PyLong_FromLong(%s);" %
                                       (self.name, self.name)),
                                 cleanup=("Py_DECREF(py_%s);" % self.name))
         self.wrapper.add_pyargv_item("py_%s" % self.name)
@@ -563,7 +563,7 @@ class IntPtrParam(Parameter):
     def convert_c2py(self):
         if self.props["direction"] == "inout":
             self.wrapper.add_declaration("PyObject *py_%s;" % self.name)
-            self.wrapper.write_code(code=("py_%s = PyInt_FromLong(*%s);" %
+            self.wrapper.write_code(code=("py_%s = _PyLong_FromLong(*%s);" %
                                           (self.name, self.name)),
                                     cleanup=("Py_DECREF(py_%s);" % self.name))
             self.wrapper.add_pyargv_item("py_%s" % self.name)
diff --git a/codegen/libcodegen/scmexpr.py b/codegen/libcodegen/scmexpr.py
new file mode 100644
index 0000000..0f38063
--- /dev/null
+++ b/codegen/libcodegen/scmexpr.py
@@ -0,0 +1,147 @@
+# -*- Mode: Python; py-indent-offset: 4 -*-
+from __future__ import generators
+
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from io import StringIO
+    
+try:
+    _unicode = unicode
+except NameError:
+    _unicode = str
+    
+class error(Exception):
+    def __init__(self, filename, lineno, msg):
+        Exception.__init__(self, msg)
+        self.filename = filename
+        self.lineno = lineno
+        self.msg = msg
+    def __str__(self):
+        return '%s:%d: error: %s' % (self.filename, self.lineno, self.msg)
+
+trans = {}
+for i in range(256):
+    c = chr(i)
+    if not c.isalnum() and c != '_':
+        trans[i] = _unicode('_')
+
+def parse(filename):
+    if isinstance(filename, str):
+        fp = open(filename, 'r')
+    else: # if not string, assume it is some kind of iterator
+        fp = filename
+        filename = getattr(fp, 'name', '<unknown>')
+    whitespace = ' \t\n\r\x0b\x0c'
+    nonsymbol = whitespace + '();\'"'
+    stack = []
+    openlines = []
+    lineno = 0
+    for line in fp:
+        pos = 0
+        lineno += 1
+        while pos < len(line):
+            if line[pos] in whitespace: # ignore whitespace
+                pass
+            elif line[pos] == ';': # comment
+                break
+            elif line[pos:pos+2] == "'(":
+                pass # the open parenthesis will be handled next iteration
+            elif line[pos] == '(':
+                stack.append(())
+                openlines.append(lineno)
+            elif line[pos] == ')':
+                if len(stack) == 0:
+                    raise error(filename, lineno, 'close parenthesis found when none open')
+                closed = stack[-1]
+                del stack[-1]
+                del openlines[-1]
+                if stack:
+                    stack[-1] += (closed,)
+                else:
+                    yield closed
+            elif line[pos] == '"': # quoted string
+                if not stack:
+                    raise error(filename, lineno,
+                                'string found outside of s-expression')
+                endpos = pos + 1
+                chars = []
+                while endpos < len(line):
+                    if endpos+1 < len(line) and line[endpos] == '\\':
+                        endpos += 1
+                        if line[endpos] == 'n':
+                            chars.append('\n')
+                        elif line[endpos] == 'r':
+                            chars.append('\r')
+                        elif line[endpos] == 't':
+                            chars.append('\t')
+                        else:
+                            chars.append('\\')
+                            chars.append(line[endpos])
+                    elif line[endpos] == '"':
+                        break
+                    else:
+                        chars.append(line[endpos])
+                    endpos += 1
+                if endpos >= len(line):
+                    raise error(filename, lineno, "unclosed quoted string")
+                pos = endpos
+                stack[-1] += (''.join(chars),)
+            else: # symbol/number
+                if not stack:
+                    raise error(filename, lineno,
+                                'identifier found outside of s-expression')
+                endpos = pos
+                while endpos < len(line) and line[endpos] not in nonsymbol:
+                    endpos += 1
+                symbol = line[pos:endpos]
+                pos = max(pos, endpos-1)
+                try: symbol = int(symbol)
+                except ValueError:
+                    try: symbol = float(symbol)
+                    except ValueError: pass
+                stack[-1] += (symbol,)
+            pos += 1
+    if len(stack) != 0:
+        msg = '%d unclosed parentheses found at end of ' \
+              'file (opened on line(s) %s)' % (len(stack),
+                                               ', '.join(map(str, openlines)))
+        raise error(filename, lineno, msg)
+
+class Parser:
+    def __init__(self, filename):
+        """Argument is either a string, a parse tree, or file object"""
+        self.filename = filename
+    def startParsing(self, filename=None):
+        statements = parse(filename or self.filename)
+        for statement in statements:
+            self.handle(statement)
+    def handle(self, tup):
+        cmd = _unicode(tup[0]).translate(trans)
+        if hasattr(self, cmd):
+            getattr(self, cmd)(*tup[1:])
+        else:
+            self.unknown(tup)
+    def unknown(self, tup):
+        pass
+
+_testString = """; a scheme file
+(define-func gdk_font_load    ; a comment at end of line
+  GdkFont
+  ((string name)))
+
+(define-boxed GdkEvent
+  gdk_event_copy
+  gdk_event_free
+  "sizeof(GdkEvent)")
+"""
+
+if __name__ == '__main__':
+    import sys
+    if sys.argv[1:]:
+        fp = open(sys.argv[1])
+    else:
+        fp = StringIO(_testString)
+    statements = parse(fp)
+    for s in statements:
+        sys.stdout.write(repr(s) + '\n')
diff --git a/codegen/override.py b/codegen/override.py
index bba5e42..71082ed 100644
--- a/codegen/override.py
+++ b/codegen/override.py
@@ -1,285 +1 @@
-# -*- Mode: Python; py-indent-offset: 4 -*-
-
-# this file contains code for loading up an override file.  The override file
-# provides implementations of functions where the code generator could not
-# do its job correctly.
-
-import fnmatch
-import os
-import re
-import string
-import sys
-
-def class2cname(klass, method):
-    c_name = ''
-    for c in klass:
-        if c.isupper():
-            c_name += '_' + c.lower()
-        else:
-            c_name += c
-    return c_name[1:] + '_'  + method
-
-# import python_type as c_name [for arg_type]
-# Last ('for') clause is optional.  If present, the type will be
-# imported only if given 'arg_type' is registered.
-import_pat = re.compile(r'\s*import\s+(\S+)\.([^\s.]+)\s+as\s+(\S+)(\s+for\s+(\S+))?')
-
-class Overrides:
-    def __init__(self, filename=None):
-        self.modulename = None
-        self.ignores = {}
-        self.glob_ignores = []
-        self.type_ignores = {}
-        self.overrides = {}
-        self.overridden = {}
-        self.kwargs = {}
-        self.noargs = {}
-        self.onearg = {}
-        self.staticmethod = {}
-        self.classmethod = {}
-        self.startlines = {}
-        self.override_attrs = {}
-        self.override_slots = {}
-        self.headers = ''
-        self.body = ''
-        self.init = ''
-        self.imports = []
-        self.defines = {}
-        self.functions = {}
-        self.newstyle_constructors = {}
-        self.dynamicnamespace = False
-        if filename:
-            self.handle_file(filename)
-
-    def handle_file(self, filename):
-        oldpath = os.getcwd()
-
-        fp = open(filename, 'r')
-        dirname = os.path.dirname(os.path.abspath(filename))
-
-        if dirname != oldpath:
-            os.chdir(dirname)
-
-        # read all the components of the file ...
-        bufs = []
-        startline = 1
-        lines = []
-        line = fp.readline()
-        linenum = 1
-        while line:
-            if line == '%%\n' or line == '%%':
-                if lines:
-                    bufs.append((string.join(lines, ''), startline))
-                startline = linenum + 1
-                lines = []
-            else:
-                lines.append(line)
-            line = fp.readline()
-            linenum = linenum + 1
-        if lines:
-            bufs.append((string.join(lines, ''), startline))
-        if not bufs: return
-
-        for buf, startline in bufs:
-            self.__parse_override(buf, startline, filename)
-
-        os.chdir(oldpath)
-
-    def __parse_override(self, buffer, startline, filename):
-        pos = string.find(buffer, '\n')
-        if pos >= 0:
-            line = buffer[:pos]
-            rest = buffer[pos+1:]
-        else:
-            line = buffer ; rest = ''
-        words = string.split(line)
-        command = words[0]
-        if (command == 'ignore' or
-            command == 'ignore-' + sys.platform):
-            "ignore/ignore-platform [functions..]"
-            for func in words[1:]:
-                self.ignores[func] = 1
-            for func in string.split(rest):
-                self.ignores[func] = 1
-        elif (command == 'ignore-glob' or
-              command == 'ignore-glob-' + sys.platform):
-            "ignore-glob/ignore-glob-platform [globs..]"
-            for func in words[1:]:
-                self.glob_ignores.append(func)
-            for func in string.split(rest):
-                self.glob_ignores.append(func)
-        elif (command == 'ignore-type' or
-              command == 'ignore-type-' + sys.platform):
-            "ignore-type/ignore-type-platform [typenames..]"
-            for typename in words[1:]:
-                self.type_ignores[typename] = 1
-            for typename in string.split(rest):
-                self.type_ignores[typename] = 1
-        elif command == 'override':
-            "override function/method [kwargs|noargs|onearg] [staticmethod|classmethod]"
-            func = words[1]
-            if 'kwargs' in words[1:]:
-                self.kwargs[func] = 1
-            elif 'noargs' in words[1:]:
-                self.noargs[func] = 1
-            elif 'onearg' in words[1:]:
-                self.onearg[func] = True
-
-            if 'staticmethod' in words[1:]:
-                self.staticmethod[func] = True
-            elif 'classmethod' in words[1:]:
-                self.classmethod[func] = True
-            if func in self.overrides:
-                raise RuntimeError("Function %s is being overridden more than once" % (func,))
-            self.overrides[func] = rest
-            self.startlines[func] = (startline + 1, filename)
-        elif command == 'override-attr':
-            "override-slot Class.attr"
-            attr = words[1]
-            self.override_attrs[attr] = rest
-            self.startlines[attr] = (startline + 1, filename)
-        elif command == 'override-slot':
-            "override-slot Class.slot"
-            slot = words[1]
-            self.override_slots[slot] = rest
-            self.startlines[slot] = (startline + 1, filename)
-        elif command == 'headers':
-            "headers"
-            self.headers = '%s\n#line %d "%s"\n%s' % \
-                           (self.headers, startline + 1, filename, rest)
-        elif command == 'body':
-            "body"
-            self.body = '%s\n#line %d "%s"\n%s' % \
-                           (self.body, startline + 1, filename, rest)
-        elif command == 'init':
-            "init"
-            self.init = '%s\n#line %d "%s"\n%s' % \
-                        (self.init, startline + 1, filename, rest)
-        elif command == 'modulename':
-            "modulename name"
-            self.modulename = words[1]
-        elif command == 'include':
-            "include filename"
-            for filename in words[1:]:
-                self.handle_file(filename)
-            for filename in string.split(rest):
-                self.handle_file(filename)
-        elif command == 'import':
-            "import module1 [\n module2, \n module3 ...]"
-            for line in string.split(buffer, '\n'):
-                match = import_pat.match(line)
-                if match:
-                    module, pyname, cname, conditional, importing_for = match.groups()
-                    self.imports.append((module, pyname, cname, importing_for or None))
-        elif command == 'define':
-            "define funcname [kwargs|noargs|onearg] [classmethod|staticmethod]"
-            "define Class.method [kwargs|noargs|onearg] [classmethod|staticmethod]"
-            func = words[1]
-            klass = None
-            if func.find('.') != -1:
-                klass, func = func.split('.', 1)
-
-                if not self.defines.has_key(klass):
-                    self.defines[klass] = {}
-                self.defines[klass][func] = rest
-            else:
-                self.functions[func] = rest
-
-            if 'kwargs' in words[1:]:
-                self.kwargs[func] = 1
-            elif 'noargs' in words[1:]:
-                self.noargs[func] = 1
-            elif 'onearg' in words[1:]:
-                self.onearg[func] = 1
-
-            if 'staticmethod' in words[1:]:
-                self.staticmethod[func] = True
-            elif 'classmethod' in words[1:]:
-                self.classmethod[func] = True
-
-            self.startlines[func] = (startline + 1, filename)
-
-        elif command == 'new-constructor':
-            "new-constructor GType"
-            gtype, = words[1:]
-            self.newstyle_constructors[gtype] = True
-        elif command == 'options':
-            for option in words[1:]:
-                if option == 'dynamicnamespace':
-                    self.dynamicnamespace = True
-
-    def is_ignored(self, name):
-        if self.ignores.has_key(name):
-            return 1
-        for glob in self.glob_ignores:
-            if fnmatch.fnmatchcase(name, glob):
-                return 1
-        return 0
-
-    def is_type_ignored(self, name):
-        return name in self.type_ignores
-
-    def is_overriden(self, name):
-        return self.overrides.has_key(name)
-
-    def is_already_included(self, name):
-        return self.overridden.has_key(name)
-
-    def override(self, name):
-        self.overridden[name] = 1
-        return self.overrides[name]
-
-    def define(self, klass, name):
-        self.overridden[class2cname(klass, name)] = 1
-        return self.defines[klass][name]
-
-    def function(self, name):
-        return self.functions[name]
-
-    def getstartline(self, name):
-        return self.startlines[name]
-
-    def wants_kwargs(self, name):
-        return self.kwargs.has_key(name)
-
-    def wants_noargs(self, name):
-        return self.noargs.has_key(name)
-
-    def wants_onearg(self, name):
-        return self.onearg.has_key(name)
-
-    def is_staticmethod(self, name):
-        return self.staticmethod.has_key(name)
-
-    def is_classmethod(self, name):
-        return self.classmethod.has_key(name)
-
-    def attr_is_overriden(self, attr):
-        return self.override_attrs.has_key(attr)
-
-    def attr_override(self, attr):
-        return self.override_attrs[attr]
-
-    def slot_is_overriden(self, slot):
-        return self.override_slots.has_key(slot)
-
-    def slot_override(self, slot):
-        return self.override_slots[slot]
-
-    def get_headers(self):
-        return self.headers
-
-    def get_body(self):
-        return self.body
-
-    def get_init(self):
-        return self.init
-
-    def get_imports(self):
-        return self.imports
-
-    def get_defines_for(self, klass):
-        return self.defines.get(klass, {})
-
-    def get_functions(self):
-        return self.functions
+from .libcodegen.override import *
diff --git a/codegen/scmexpr.py b/codegen/scmexpr.py
old mode 100755
new mode 100644
index 02f2e4b..2ba30e1
--- a/codegen/scmexpr.py
+++ b/codegen/scmexpr.py
@@ -1,143 +1,11 @@
 #!/usr/bin/env python
-# -*- Mode: Python; py-indent-offset: 4 -*-
-from __future__ import generators
-
-import string
-from cStringIO import StringIO
-
-class error(Exception):
-    def __init__(self, filename, lineno, msg):
-        Exception.__init__(self, msg)
-        self.filename = filename
-        self.lineno = lineno
-        self.msg = msg
-    def __str__(self):
-        return '%s:%d: error: %s' % (self.filename, self.lineno, self.msg)
-
-trans = [' '] * 256
-for i in range(256):
-    if chr(i) in string.letters + string.digits + '_':
-        trans[i] = chr(i)
-    else:
-        trans[i] = '_'
-trans = string.join(trans, '')
-
-def parse(filename):
-    if isinstance(filename, str):
-        fp = open(filename, 'r')
-    else: # if not string, assume it is some kind of iterator
-        fp = filename
-        filename = getattr(fp, 'name', '<unknown>')
-    whitespace = ' \t\n\r\x0b\x0c'
-    nonsymbol = whitespace + '();\'"'
-    stack = []
-    openlines = []
-    lineno = 0
-    for line in fp:
-        pos = 0
-        lineno += 1
-        while pos < len(line):
-            if line[pos] in whitespace: # ignore whitespace
-                pass
-            elif line[pos] == ';': # comment
-                break
-            elif line[pos:pos+2] == "'(":
-                pass # the open parenthesis will be handled next iteration
-            elif line[pos] == '(':
-                stack.append(())
-                openlines.append(lineno)
-            elif line[pos] == ')':
-                if len(stack) == 0:
-                    raise error(filename, lineno, 'close parenthesis found when none open')
-                closed = stack[-1]
-                del stack[-1]
-                del openlines[-1]
-                if stack:
-                    stack[-1] += (closed,)
-                else:
-                    yield closed
-            elif line[pos] == '"': # quoted string
-                if not stack:
-                    raise error(filename, lineno,
-                                'string found outside of s-expression')
-                endpos = pos + 1
-                chars = []
-                while endpos < len(line):
-                    if endpos+1 < len(line) and line[endpos] == '\\':
-                        endpos += 1
-                        if line[endpos] == 'n':
-                            chars.append('\n')
-                        elif line[endpos] == 'r':
-                            chars.append('\r')
-                        elif line[endpos] == 't':
-                            chars.append('\t')
-                        else:
-                            chars.append('\\')
-                            chars.append(line[endpos])
-                    elif line[endpos] == '"':
-                        break
-                    else:
-                        chars.append(line[endpos])
-                    endpos += 1
-                if endpos >= len(line):
-                    raise error(filename, lineno, "unclosed quoted string")
-                pos = endpos
-                stack[-1] += (''.join(chars),)
-            else: # symbol/number
-                if not stack:
-                    raise error(filename, lineno,
-                                'identifier found outside of s-expression')
-                endpos = pos
-                while endpos < len(line) and line[endpos] not in nonsymbol:
-                    endpos += 1
-                symbol = line[pos:endpos]
-                pos = max(pos, endpos-1)
-                try: symbol = int(symbol)
-                except ValueError:
-                    try: symbol = float(symbol)
-                    except ValueError: pass
-                stack[-1] += (symbol,)
-            pos += 1
-    if len(stack) != 0:
-        msg = '%d unclosed parentheses found at end of ' \
-              'file (opened on line(s) %s)' % (len(stack),
-                                               ', '.join(map(str, openlines)))
-        raise error(filename, lineno, msg)
-
-class Parser:
-    def __init__(self, filename):
-        """Argument is either a string, a parse tree, or file object"""
-        self.filename = filename
-    def startParsing(self, filename=None):
-        statements = parse(filename or self.filename)
-        for statement in statements:
-            self.handle(statement)
-    def handle(self, tup):
-        cmd = string.translate(tup[0], trans)
-        if hasattr(self, cmd):
-            getattr(self, cmd)(*tup[1:])
-        else:
-            self.unknown(tup)
-    def unknown(self, tup):
-        pass
-
-_testString = """; a scheme file
-(define-func gdk_font_load    ; a comment at end of line
-  GdkFont
-  ((string name)))
-
-(define-boxed GdkEvent
-  gdk_event_copy
-  gdk_event_free
-  "sizeof(GdkEvent)")
-"""
 
+# scmexpr.py is runnable as a script and available as module in codegen package
 if __name__ == '__main__':
+    from libcodegen import scmrexpr
     import sys
-    if sys.argv[1:]:
-        fp = open(sys.argv[1])
-    else:
-        fp = StringIO(_testString)
-    statements = parse(fp)
-    for s in statements:
-        print `s`
+    sys.exit(scmrexpr.main(sys.argv))
+else:
+    from codegen.libcodegen.scmexpr import *
+
+
diff --git a/dsextras.py b/dsextras.py
index 10973e2..d3e0d2e 100644
--- a/dsextras.py
+++ b/dsextras.py
@@ -48,7 +48,10 @@ def getstatusoutput(cmd):
             text = text[:-1]
         return sts, text
     else:
-        from commands import getstatusoutput
+        try:
+            from subprocess import getstatusoutput
+        except:
+            from commands import getstatusoutput
         return getstatusoutput(cmd)
 
 def have_pkgconfig():
@@ -122,8 +125,8 @@ class BuildExt(build_ext):
             msnative_struct = { '2' : '-fnative-struct',
                                 '3' : '-mms-bitfields' }
             gcc_version = getoutput('gcc -dumpversion')
-            print 'using MinGW GCC version %s with %s option' % \
-                  (gcc_version, msnative_struct[gcc_version[0]])
+            print ('using MinGW GCC version %s with %s option' % \
+                   (gcc_version, msnative_struct[gcc_version[0]]))
             self.extra_compile_args.append(msnative_struct[gcc_version[0]])
 
     def modify_compiler(self):
@@ -307,14 +310,14 @@ class PkgConfigExtension(Extension):
 
             orig_version = getoutput('pkg-config --modversion %s' %
                                      package)
-            if (map(int, orig_version.split('.')) >=
-                map(int, version.split('.'))):
+            if (tuple(map(int, orig_version.split('.'))) >=
+                tuple(map(int, version.split('.')))):
                 self.can_build_ok = 1
                 return 1
             else:
-                print "Warning: Too old version of %s" % self.pkc_name
-                print "         Need %s, but %s is installed" % \
-                      (version, orig_version)
+                print ("Warning: Too old version of %s" % self.pkc_name)
+                print ("         Need %s, but %s is installed" % \
+                       (version, orig_version))
                 self.can_build_ok = 0
                 return 0
 
@@ -343,7 +346,8 @@ try:
     from codegen.codegen import register_types, SourceWriter, \
          FileOutput
     import codegen.createdefs
-except ImportError, e:
+except ImportError:
+    raise
     template_classes_enabled=False
 
 class Template(object):
@@ -445,7 +449,7 @@ class TemplateExtension(PkgConfigExtension):
         if load_types:
             del kwargs['load_types']
 
-        if kwargs.has_key('output'):
+        if 'output' in kwargs:
             kwargs['name'] = kwargs['output']
             del kwargs['output']
 
diff --git a/setup.py b/setup.py
index 50f7abe..633e19d 100755
--- a/setup.py
+++ b/setup.py
@@ -20,21 +20,24 @@ from dsextras import get_m4_define, getoutput, have_pkgconfig, \
 if '--yes-i-know-its-not-supported' in sys.argv:
     sys.argv.remove('--yes-i-know-its-not-supported')
 else:
-    print '*'*70
-    print 'Building PyGObject using distutils is NOT SUPPORTED.'
-    print "It's mainly included to be able to easily build win32 installers"
-    print "You may continue, but only if you agree to not ask any questions"
-    print "To build PyGObject in a supported way, read the INSTALL file"
-    print
-    print "Build fixes are of course welcome and should be filed in bugzilla"
-    print '*'*70
-    input = raw_input('Not supported, ok [y/N]? ')
+    print ('*'*70)
+    print ('Building PyGObject using distutils is NOT SUPPORTED.')
+    print ("It's mainly included to be able to easily build win32 installers")
+    print ("You may continue, but only if you agree to not ask any questions")
+    print ("To build PyGObject in a supported way, read the INSTALL file")
+    print ("")
+    print ("Build fixes are of course welcome and should be filed in bugzilla")
+    print ('*'*70)
+    if sys.version_info < (3, 0):
+        input = raw_input('Not supported, ok [y/N]? ')
+    else:
+        input = input('Not supported, ok [y/N]? ')
     if not input.startswith('y'):
         raise SystemExit
 
 if sys.version_info[:3] < (2, 3, 5):
-    raise SystemExit, \
-          "Python 2.3.5 or higher is required, %d.%d.%d found" % sys.version_info[:3]
+    raise SystemExit("Python 2.3.5 or higher is required, %d.%d.%d found"
+                     % sys.version_info[:3])
 
 MAJOR_VERSION = int(get_m4_define('pygobject_major_version'))
 MINOR_VERSION = int(get_m4_define('pygobject_minor_version'))
@@ -174,7 +177,7 @@ py_modules = ['dsextras']
 packages = ['codegen']
 
 if not have_pkgconfig():
-    print "Error, could not find pkg-config"
+    print ("Error, could not find pkg-config")
     raise SystemExit
 
 if glib.can_build():
@@ -197,8 +200,8 @@ if glib.can_build():
     ext_modules.append(glib)
     py_modules += ['glib.__init__', 'glib.option']
 else:
-    print
-    print 'ERROR: Nothing to do, glib could not be found and is essential.'
+    print ("")
+    print ('ERROR: Nothing to do, glib could not be found and is essential.')
     raise SystemExit
 
 if gobject.can_build():
@@ -209,8 +212,8 @@ if gobject.can_build():
     data_files.append((XSL_DIR,  glob.glob('docs/xsl/*.xsl')))
     py_modules += ['gobject.__init__', 'gobject.propertyhelper', 'gobject.constants']
 else:
-    print
-    print 'ERROR: Nothing to do, gobject could not be found and is essential.'
+    print ('')
+    print ('ERROR: Nothing to do, gobject could not be found and is essential.')
     raise SystemExit
 
 if gio.can_build():
@@ -218,8 +221,8 @@ if gio.can_build():
     py_modules += ['gio.__init__']
     data_files.append((DEFS_DIR,('gio/gio-types.defs',)))
 else:
-    print
-    print 'ERROR: Nothing to do, gio could not be found and is essential.'
+    print ('')
+    print ('ERROR: Nothing to do, gio could not be found and is essential.')
     raise SystemExit
 
 # Threading support
@@ -232,7 +235,7 @@ else:
     try:
         import thread
     except ImportError:
-        print "Warning: Could not import thread module, disabling threading"
+        print ("Warning: Could not import thread module, disabling threading")
         enable_threading = False
     else:
         enable_threading = True



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]