diff --git a/codegen/Makefile.am b/codegen/Makefile.am
index 9f3f033..a966d43 100644
--- a/codegen/Makefile.am
+++ b/codegen/Makefile.am
@@ -1,30 +1,24 @@
 PLATFORM_VERSION = 2.0
 
+SUBDIRS = libcodegen
+
 bin_SCRIPTS = pygobject-codegen-$(PLATFORM_VERSION)
 
 codegendir = $(pkgdatadir)/$(PLATFORM_VERSION)/codegen
 
 codegen_PYTHON = \
-	__init__.py \
-	argtypes.py \
-	reversewrapper.py \
 	code-coverage.py \
 	codegen.py \
-	definitions.py \
+	createdefs.py \
 	defsconvert.py \
 	defsgen.py \
-	defsparser.py \
-	docextract.py \
 	docextract_to_xml.py \
 	docgen.py \
 	h2def.py \
-	defsgen.py \
-	createdefs.py \
+	__init__.py \
 	mergedefs.py \
 	missingdefs.py \
 	mkskel.py \
-	override.py \
-	scanvirtuals.py \
-	scmexpr.py
+	scanvirtuals.py
 
 EXTRA_DIST = README.defs pygobject-codegen-$(PLATFORM_VERSION).in
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 fd15034..1f1803f 100755
--- a/codegen/code-coverage.py
+++ b/codegen/code-coverage.py
@@ -36,7 +36,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
+            sys.stdout.write("%s\n" % symbol)
 
 if __name__ == '__main__':
     main()
diff --git a/codegen/codegen.py b/codegen/codegen.py
index ab9153c..5027dc4 100644
--- a/codegen/codegen.py
+++ b/codegen/codegen.py
@@ -3,12 +3,10 @@ import keyword
 import os
 import string
 import sys
+import subprocess
 
-import argtypes
-import definitions
-import defsparser
-import override
-import reversewrapper
+from libcodegen import argtypes, definitions, defsparser, override, \
+     reversewrapper
 import warnings
 
 class Coverage(object):
@@ -94,8 +92,7 @@ class FileOutput:
 class Wrapper:
     type_tmpl = (
         'PyTypeObject G_GNUC_INTERNAL Py%(typename)s_Type = {\n'
-        '    PyObject_HEAD_INIT(NULL)\n'
-        '    0,                                 /* ob_size */\n'
+        '    PyVarObject_HEAD_INIT(NULL, 0)\n'
         '    "%(classname)s",                   /* tp_name */\n'
         '    sizeof(%(tp_basicsize)s),          /* tp_basicsize */\n'
         '    0,                                 /* tp_itemsize */\n'
@@ -104,7 +101,11 @@ class Wrapper:
         '    (printfunc)0,                      /* tp_print */\n'
         '    (getattrfunc)%(tp_getattr)s,       /* tp_getattr */\n'
         '    (setattrfunc)%(tp_setattr)s,       /* tp_setattr */\n'
+        '#if PY_VERSION_HEX < 0x03000000\n'
         '    (cmpfunc)%(tp_compare)s,           /* tp_compare */\n'
+        '#else\n'
+        '    NULL,\n'
+        '#endif\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'
@@ -265,7 +266,7 @@ class Wrapper:
         self.fp.write('\n/* ----------- %s ----------- */\n\n' %
                       self.objinfo.c_name)
         substdict = self.get_initial_class_substdict()
-        if not substdict.has_key('tp_flags'):
+        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:
@@ -295,7 +296,7 @@ class Wrapper:
                 self.write_function(slotname, data)
                 substdict[slot] = slotfunc
             else:
-                if not substdict.has_key(slot):
+                if slot not in substdict:
                     substdict[slot] = '0'
 
         self.fp.write(self.type_tmpl % substdict)
@@ -423,7 +424,8 @@ class Wrapper:
                     constructor))[0]
                 self.fp.write(code)
             initfunc = '_wrap_' + funcname
-        except argtypes.ArgTypeError, ex:
+        except argtypes.ArgTypeError:
+            exc_class, ex, tb = sys.exc_info()
             sys.stderr.write('Could not write constructor for %s: %s\n'
                              % (self.objinfo.c_name, str(ex)))
 
@@ -500,7 +502,8 @@ class Wrapper:
                                  'flags': methflags,
                                  'docstring': meth.docstring })
                 methods_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
+            except argtypes.ArgTypeError:
+                exc_class, ex, tb = sys.exc_info()
                 methods_coverage.declare_not_wrapped()
                 sys.stderr.write('Could not write method %s.%s: %s\n'
                                 % (klass, meth.name, str(ex)))
@@ -522,7 +525,8 @@ class Wrapper:
                                  'flags': methflags,
                                  'docstring': 'NULL' })
                 methods_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
+            except argtypes.ArgTypeError:
+                exc_class, ex, tb = sys.exc_info()
                 methods_coverage.declare_not_wrapped()
                 sys.stderr.write('Could not write method %s.%s: %s\n'
                                 % (klass, method_name, str(ex)))
@@ -576,7 +580,8 @@ class Wrapper:
                                  'flags': methflags + '|METH_CLASS',
                                  'docstring': 'NULL'})
                 vaccessors_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
+            except argtypes.ArgTypeError:
+                exc_class, ex, tb = sys.exc_info()
                 vaccessors_coverage.declare_not_wrapped()
                 sys.stderr.write(
                     'Could not write virtual accessor method %s.%s: %s\n'
@@ -619,7 +624,8 @@ class Wrapper:
                     self.fp.write(buf.flush())
                 virtuals.append((fixname(meth.name), '_wrap_' + method_name))
                 vproxies_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
+            except argtypes.ArgTypeError:
+                exc_class, ex, tb = sys.exc_info()
                 vproxies_coverage.declare_not_wrapped()
                 virtuals.append((fixname(meth.name), None))
                 sys.stderr.write('Could not write virtual proxy %s.%s: %s\n'
@@ -707,7 +713,8 @@ class Wrapper:
                                     'field': self.get_field_accessor(cfname),
                                     'codeafter': info.get_codeafter() })
                     gettername = funcname
-                except argtypes.ArgTypeError, ex:
+                except argtypes.ArgTypeError:
+                    exc_class, ex, tb = sys.exc_info()
                     sys.stderr.write(
                         "Could not write getter for %s.%s: %s\n"
                         % (self.objinfo.c_name, fname, str(ex)))
@@ -734,19 +741,19 @@ _wrap__get_symbol_names(PyObject *self)
 """)
         for obj, bases in writer.get_classes():
             self.fp.write('    PyList_Append(pylist, '
-                          'PyString_FromString("%s"));\n' % (obj.name))
+                          '_PyUnicode_FromString("%s"));\n' % (obj.name))
 
         for name, cname, flags, docstring in functions:
             self.fp.write('    PyList_Append(pylist, '
-                          'PyString_FromString("%s"));\n' % (name))
+                          '_PyUnicode_FromString("%s"));\n' % (name))
 
         for enum in writer.get_enums():
             self.fp.write('    PyList_Append(pylist, '
-                          'PyString_FromString("%s"));\n' % (enum.name))
+                          '_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, '
-                              'PyString_FromString("%s"));\n' % (name))
+                              '_PyUnicode_FromString("%s"));\n' % (name))
 
         self.fp.write("    return pylist;\n}\n\n");
 
@@ -764,7 +771,7 @@ _wrap__get_symbol(PyObject *self, PyObject *args)
         return NULL;
 
     if (!modulename)
-       modulename = PyString_FromString("%s");
+       modulename = _PyUnicode_FromString("%s");
 
     if (!module)
        module = PyDict_GetItemString(d, "__module__");
@@ -847,7 +854,8 @@ _wrap__get_symbol(PyObject *self, PyObject *args)
                 functions.append((func.name, '_wrap_' + funcname,
                                   methflags, func.docstring))
                 functions_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
+            except argtypes.ArgTypeError:
+                exc_class, ex, tb = sys.exc_info()
                 functions_coverage.declare_not_wrapped()
                 sys.stderr.write('Could not write function %s: %s\n'
                                  % (func.name, str(ex)))
@@ -861,7 +869,8 @@ _wrap__get_symbol(PyObject *self, PyObject *args)
                 functions.append((funcname, '_wrap_' + funcname,
                                   methflags, 'NULL'))
                 functions_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
+            except argtypes.ArgTypeError:
+                exc_class, ex, tb = sys.exc_info()
                 functions_coverage.declare_not_wrapped()
                 sys.stderr.write('Could not write function %s: %s\n'
                                  % (funcname, str(ex)))
@@ -990,17 +999,16 @@ class GObjectWrapper(Wrapper):
     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
+        out.write("static int\n")
+        out.write('_wrap_%s(PyGObject *self, PyObject *args,' \
+                  ' PyObject *kwargs)\n{\n' % constructor.c_name)
         if constructor.params:
-            s = "    GType obj_type = pyg_type_from_object((PyObject *) self);"
-            print >> out, s
+            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 }"
+                return "{" + ", ".join(['"%s"' % s for s in arg ]) + ", NULL }"
             else:
                 return "{ NULL }"
 
@@ -1020,21 +1028,19 @@ class GObjectWrapper(Wrapper):
             [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
+            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)
-                print >> out, '        return -1;'
-                print >> out
+                out.write('        return -1;\n\n')
+
             out.write("    if (!PyArg_ParseTupleAndKeywords(args, kwargs, ")
             template = '"'
             if mandatory_arguments:
@@ -1042,9 +1048,9 @@ class GObjectWrapper(Wrapper):
             if optional_arguments:
                 template += "|" + "O"*len(optional_arguments)
             template += ':%s.__init__"' % classname
-            print >> out, template, ", arg_names",
+            out.write("%s, arg_names" % template)
             for i in range(len(constructor.params)):
-                print >> out, ", &parsed_args[%i]" % i,
+                out.write(", &parsed_args[%i]" % i)
 
             out.write(
                 "))\n"
@@ -1086,7 +1092,7 @@ class GObjectWrapper(Wrapper):
             '    }\n' % classname)
 
         if not constructor.caller_owns_return:
-            print >> out, "    g_object_ref(self->obj);\n"
+            out.write("    g_object_ref(self->obj);\n")
 
         out.write(
             '    return 0;\n'
@@ -1172,7 +1178,8 @@ class GInterfaceWrapper(GObjectWrapper):
                     self.fp.write(buf.flush())
                 proxies.append((fixname(meth.name), '_wrap_' + method_name))
                 iproxies_coverage.declare_wrapped()
-            except argtypes.ArgTypeError, ex:
+            except argtypes.ArgTypeError:
+                exc_class, ex, tb = sys.exc_info()
                 iproxies_coverage.declare_not_wrapped()
                 proxies.append((fixname(meth.name), None))
                 sys.stderr.write('Could not write interface proxy %s.%s: %s\n'
@@ -1367,6 +1374,7 @@ typedef intargfunc ssizeargfunc;
 typedef intobjargproc ssizeobjargproc;
 #endif
 
+#include <pyglib.h>
 ''')
         self.fp.write(self.overrides.get_headers())
         self.fp.resetline()
@@ -1615,10 +1623,10 @@ typedef intobjargproc ssizeobjargproc;
                 indent_str + 'pyg_set_object_has_new_constructor(%s);\n' %
                 obj.typecode)
         else:
-            print >> sys.stderr, (
+            sys.stderr.write(
                 "Warning: Constructor for %s needs to be updated to new API\n"
                 "         See http://live.gnome.org/PyGTK_2fWhatsNew28"
-                "#update-constructors") % obj.c_name
+                "#update-constructors\n" % obj.c_name)
 
         if obj.class_init_func is not None:
             self.fp.write(
@@ -1680,8 +1688,7 @@ def main(argv):
         elif opt == '--errorfilename':
             errorfilename = arg
         elif opt in ('-t', '--load-types'):
-            globals = {}
-            execfile(arg, globals)
+            retcode = subprocess.call("%s %s" % (sys.executable, arg), shell=True)
         elif opt == '-D':
             nameval = arg.split('=')
             try:
@@ -1693,7 +1700,7 @@ def main(argv):
         elif opt == '--py_ssize_t-clean':
             py_ssize_t_clean = True
     if len(args) < 1:
-        print >> sys.stderr, usage
+        sys.stderr.write("%s\n" % usage)
         return 1
     if errorfilename:
         sys.stderr = open(errorfilename, "w")
diff --git a/codegen/defsgen.py b/codegen/defsgen.py
index 670d411..f761db9 100644
--- a/codegen/defsgen.py
+++ b/codegen/defsgen.py
@@ -86,7 +86,7 @@ import os
 import re, string
 import sys
 import ctypes
-import defsparser
+from libcodegen import defsparser
 
 #------------------ utility defs -----------------
 
@@ -409,7 +409,7 @@ class DefsWriter:
     def write_untyped_enum_defs(self, fp):
         fp.write(';; Untyped enumerations and flags ...\n\n')
         filter = self._c_names
-        for cname, (isflags, entries) in self.defs['untypedenums'].items():
+        for cname, (isflags, entries) in list(self.defs['untypedenums'].items()):
             if filter and cname in filter: continue
             module, name = split_prefix(cname, self.prefix, self.use_prefix)
             if isflags:
@@ -656,10 +656,10 @@ def main(args):
                 defines[nameval[0]] = None
 
     if not args[0:1]:
-        print 'Must specify at least one input file name'
+        sys.stdout.write('Must specify at least one input file name\n')
         return -1
     if not modulelibs:
-        print 'Must specify one or more modulelib names'
+        sys.stdout.write('Must specify one or more modulelib names\n')
         return -1
 
     # load the gobject and module libraries and init the gtype system
@@ -723,15 +723,15 @@ def main(args):
     if onlyobjdefs or all:
         dw.write_obj_defs(types)
         if separate:
-            print "Wrote object defs to %s-types.defs" % separate
+            sys.stdout.write("Wrote object defs to %s-types.defs\n" % separate)
     if onlyenums or all:
         dw.write_enum_defs(types)
         if separate:
-            print "Wrote enum and flags defs to %s-types.defs" % separate
+            sys.stdout.write("Wrote enum and flags defs to %s-types.defs\n" % separate)
     if onlyvirtuals or all:
         dw.write_func_defs(args, onlyvirtuals)
         if separate:
-            print "Wrote function and virtual defs to %s.defs" % separate
+            sys.stdout.write("Wrote function and virtual defs to %s.defs\n" % separate)
 
 if __name__ == '__main__':
     sys.exit(main(sys.argv))
diff --git a/codegen/docextract_to_xml.py b/codegen/docextract_to_xml.py
index f8d3bae..f05df56 100755
--- a/codegen/docextract_to_xml.py
+++ b/codegen/docextract_to_xml.py
@@ -11,7 +11,7 @@ import re
 import string
 import sys
 
-import docextract
+from libcodegen import docextract
 
 def escape_text(unescaped_text):
     # Escape every "&" not part of an entity reference
@@ -34,7 +34,8 @@ if __name__ == '__main__':
     try:
         opts, args = getopt.getopt(sys.argv[1:], "d:s:o:",
                                    ["source-dir="])
-    except getopt.error, e:
+    except getopt.error:
+        exc_class, e, tb = sys.exc_info()
         sys.stderr.write('docgen.py: %s\n' % e)
         sys.stderr.write(
             'usage: docgen.py [-s /src/dir]\n')
@@ -55,28 +56,28 @@ if __name__ == '__main__':
 
     if docs:
 
-        print "<root>"
+        sys.stdout.write("<root>\n")
 
-        for name, value in docs.items():
-            print "<function name=\"" + escape_text(name) + "\">"
+        for name, value in list(docs.items()):
+            sys.stdout.write("<function name=\"" + escape_text(name) + "\">\n")
 
-            print "<description>"
+            sys.stdout.write("<description>\n")
             #The value is a docextract.FunctionDoc
-            print escape_text(value.description)
-            print "</description>"
+            sys.stdout.write("%s\n" % escape_text(value.description))
+            sys.stdout.write("</description>\n")
 
              # Loop through the parameters:
-            print "<parameters>"
+            sys.stdout.write("<parameters>\n")
             for name, description in value.params:
-                print "<parameter name=\"" + escape_text(name) + "\">"
-                print "<parameter_description>" + escape_text(description) + "</parameter_description>"
-                print "</parameter>"
+                sys.stdout.write("<parameter name=\"" + escape_text(name) + "\">\n")
+                sys.stdout.write("<parameter_description>" + escape_text(description) + "</parameter_description>\n")
+                sys.stdout.write("</parameter>\n")
 
-            print "</parameters>"
+            sys.stdout.write("</parameters>\n")
 
             # Show the return-type:
-            print "<return>" + escape_text(value.ret) + "</return>"
+            sys.stdout.write("<return>" + escape_text(value.ret) + "</return>\n")
 
-            print "</function>\n"
+            sys.stdout.write("</function>\n\n")
 
-        print "</root>"
+        sys.stdout.write("</root>\n")
diff --git a/codegen/docgen.py b/codegen/docgen.py
index b9e2f67..5fc9045 100644
--- a/codegen/docgen.py
+++ b/codegen/docgen.py
@@ -4,10 +4,7 @@ import os
 import re
 import sys
 
-import definitions
-import defsparser
-import docextract
-import override
+from libcodegen import definitions, defsparser, docextract, override
 
 
 class Node:
@@ -180,9 +177,12 @@ class DocWriter:
                                    self.docs.get(constructor.c_name, None))
             self.close_section()
 
+        def _ignored(meth):
+            return not self.overrides.is_ignored(meth.c_name)
+
         methods = self.parser.find_methods(obj_def)
-        methods = filter(lambda meth, self=self:
-                         not self.overrides.is_ignored(meth.c_name), methods)
+        methods = list(filter(_ignored, methods))
+
         if methods:
             self.write_heading('Methods')
             for method in methods:
@@ -522,8 +522,11 @@ class DocbookDocWriter(DocWriter):
                     self._fp.write('\n')
 
                 indent = indent + '  '
-            node.subclasses.sort(lambda a, b:
-                                 cmp(self.pyname(a.name), self.pyname(b.name)))
+
+            def _sort_func(a, b):
+                return cmp(self.pyname(a.name), self.pyname(b.name))
+            node.subclasses.sort(_sort_func)
+
             for child in node.subclasses:
                 handle_node(child, indent)
 
@@ -731,7 +734,8 @@ def main(args):
         opts, args = getopt.getopt(args[1:], "d:s:o:",
                                    ["defs-file=", "override=", "source-dir=",
                                     "output-prefix="])
-    except getopt.error, e:
+    except getopt.error:
+        exc_class, e, tb = sys.exc_info()
         sys.stderr.write('docgen.py: %s\n' % e)
         sys.stderr.write(
             'usage: docgen.py -d file.defs [-s /src/dir] [-o output-prefix]\n')
diff --git a/codegen/h2def.py b/codegen/h2def.py
index 3ed3642..3fa2de0 100755
--- a/codegen/h2def.py
+++ b/codegen/h2def.py
@@ -16,7 +16,7 @@ import re
 import string
 import sys
 
-import defsparser
+from libcodegen import defsparser
 
 # ------------------ Create typecodes from typenames ---------
 
@@ -287,7 +287,7 @@ class DefsWriter:
         if defsfilter:
             filter = defsparser.DefsParser(defsfilter)
             filter.startParsing()
-            for func in filter.functions + filter.methods.values():
+            for func in filter.functions + list(filter.methods.values()):
                 self._functions[func.c_name] = func
             for obj in filter.objects + filter.boxes + filter.interfaces:
                 self._objects[obj.c_name] = obj
@@ -436,7 +436,7 @@ class DefsWriter:
         self._write_arguments(args)
 
     def _write_method(self, obj, name, ret, args):
-        regex = string.join(map(lambda x: x+'_?', string.lower(obj)),'')
+        regex = string.join([x+'_?' for x in string.lower(obj)],'')
         mname = re.sub(regex, '', name, 1)
         if self.prefix:
             l = len(self.prefix) + 1
@@ -502,7 +502,7 @@ def main(args):
             defsfilter = v
 
     if not args[0:1]:
-        print 'Must specify at least one input file name'
+        sys.stdout.write('Must specify at least one input file name\n')
         return -1
 
     # read all the object definitions in
@@ -522,11 +522,11 @@ def main(args):
                         defsfilter=defsfilter)
         dw.write_obj_defs(objdefs, types)
         dw.write_enum_defs(enums, types)
-        print "Wrote %s-types.defs" % separate
+        sys.stdout.write("Wrote %s-types.defs\n" % separate)
 
         for filename in args:
             dw.write_def(filename)
-        print "Wrote %s.defs" % separate
+        sys.stdout.write("Wrote %s.defs\nn" % separate)
     else:
         dw = DefsWriter(prefix=modulename, verbose=verbose,
                         defsfilter=defsfilter)
diff --git a/codegen/libcodegen/Makefile.am b/codegen/libcodegen/Makefile.am
new file mode 100644
index 0000000..d67a4ba
--- /dev/null
+++ b/codegen/libcodegen/Makefile.am
@@ -0,0 +1,14 @@
+PLATFORM_VERSION = 2.0
+libcodegendir = $(pkgdatadir)/$(PLATFORM_VERSION)/codegen/libcodegen
+
+libcodegen_PYTHON = \
+	__init__.py \
+	argtypes.py \
+	reversewrapper.py \
+	definitions.py \
+	defsparser.py \
+	docextract.py \
+	override.py \
+	scmexpr.py \
+	string_compat.py
+
diff --git a/codegen/libcodegen/__init__.py b/codegen/libcodegen/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/codegen/argtypes.py b/codegen/libcodegen/argtypes.py
similarity index 97%
rename from codegen/argtypes.py
rename to codegen/libcodegen/argtypes.py
index b35f6ef..a6ddb91 100644
--- a/codegen/argtypes.py
+++ b/codegen/libcodegen/argtypes.py
@@ -1,5 +1,5 @@
 # -*- Mode: Python; py-indent-offset: 4 -*-
-import string
+from libcodegen.string_compat import string
 import keyword
 import struct
 
@@ -20,13 +20,13 @@ 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,)
     def __str__(self):
         ret = []
-        for type in self.vars.keys():
+        for type in list(self.vars.keys()):
             ret.append('    ')
             ret.append(type)
             ret.append(' ')
@@ -79,14 +79,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 +110,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 +119,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 +152,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 +185,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 +200,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 +277,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 +294,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):
@@ -695,7 +695,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 +867,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 +934,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/definitions.py b/codegen/libcodegen/definitions.py
similarity index 96%
rename from codegen/definitions.py
rename to codegen/libcodegen/definitions.py
index 88b6cdb..a31d822 100644
--- a/codegen/definitions.py
+++ b/codegen/libcodegen/definitions.py
@@ -65,13 +65,13 @@ class Definition:
     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"
@@ -202,7 +202,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):
@@ -399,7 +399,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')
@@ -455,8 +455,8 @@ class FunctionDef(Definition):
                     self.params.append(Parameter(ptype, pname, pdflt, pnull))
             elif arg[0] == 'properties':
                 if self.is_constructor_of is None:
-                    print >> sys.stderr, "Warning: (properties ...) "\
-                          "is only valid for constructors"
+                    sys.stderr.write("Warning: (properties ...) "\
+                          "is only valid for constructors\n")
                 for prop in arg[1:]:
                     pname = prop[0]
                     optional = False
@@ -483,7 +483,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']
 
@@ -505,10 +505,10 @@ 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)
+            self.params = list(map(merge_param, self.params))
         except RuntimeError:
             # parameter names changed and we can't find a match; it's
             # safer to keep the old parameter list untouched.
diff --git a/codegen/defsparser.py b/codegen/libcodegen/defsparser.py
similarity index 81%
rename from codegen/defsparser.py
rename to codegen/libcodegen/defsparser.py
index 37ba0a2..8121161 100644
--- a/codegen/defsparser.py
+++ b/codegen/libcodegen/defsparser.py
@@ -1,7 +1,7 @@
 # -*- Mode: Python; py-indent-offset: 4 -*-
 import os, sys
-import scmexpr
-from definitions import BoxedDef, EnumDef, FlagsDef, FunctionDef, \
+from libcodegen import scmexpr
+from libcodegen.definitions import BoxedDef, EnumDef, FlagsDef, FunctionDef, \
      InterfaceDef, MethodDef, ObjectDef, PointerDef, VirtualDef
 
 include_path = ['.']
@@ -47,54 +47,54 @@ class DefsParser(IncludeParser):
         self.defines = defines      # -Dfoo=bar options, as dictionary
 
     def define_object(self, *args):
-        odef = apply(ObjectDef, args)
+        odef = ObjectDef(*args)
         self.objects.append(odef)
         self.c_name[odef.c_name] = odef
     def define_interface(self, *args):
-        idef = apply(InterfaceDef, args)
+        idef = InterfaceDef(*args)
         self.interfaces.append(idef)
         self.c_name[idef.c_name] = idef
     def define_enum(self, *args):
-        edef = apply(EnumDef, args)
+        edef = EnumDef(*args)
         self.enums.append(edef)
         self.c_name[edef.c_name] = edef
     def define_flags(self, *args):
-        fdef = apply(FlagsDef, args)
+        fdef = FlagsDef(*args)
         self.enums.append(fdef)
         self.c_name[fdef.c_name] = fdef
     def define_boxed(self, *args):
-        bdef = apply(BoxedDef, args)
+        bdef = BoxedDef(*args)
         self.boxes.append(bdef)
         self.c_name[bdef.c_name] = bdef
     def define_pointer(self, *args):
-        pdef = apply(PointerDef, args)
+        pdef = PointerDef(*args)
         self.pointers.append(pdef)
         self.c_name[pdef.c_name] = pdef
     def define_function(self, *args):
-        fdef = apply(FunctionDef, args)
+        fdef = FunctionDef(*args)
         self.functions.append(fdef)
         self.c_name[fdef.c_name] = fdef
     def define_method(self, *args):
-        mdef = apply(MethodDef, args)
+        mdef = MethodDef(*args)
         self.functions.append(mdef)
         self.c_name[mdef.c_name] = mdef
     def define_virtual(self, *args):
-        vdef = apply(VirtualDef, args)
+        vdef = 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):
+            if obj.c_name in old.c_name:
                 obj.merge(old.c_name[obj.c_name])
         for f in self.functions:
-            if old.c_name.has_key(f.c_name):
+            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 not old.c_name.has_key(obj.c_name):
+            if obj.c_name not in old.c_name:
                 obj.write_defs()
         for f in self.functions:
-            if not old.c_name.has_key(f.c_name):
+            if f.c_name not in old.c_name:
                 f.write_defs()
 
     def write_defs(self, fp=sys.stdout):
@@ -125,18 +125,21 @@ class DefsParser(IncludeParser):
 
     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_methods(func):
+            return isinstance(func, MethodDef) and func.of_object == objname
+        return list(filter(_find_methods, 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)
+        def _find_virtuals(func):
+            return isinstance(func, VirtualDef) and func.of_object == objname
+        retval = list(filter(_find_virtuals, self.virtuals))
         return retval
 
     def find_functions(self):
-        return filter(lambda func: isinstance(func, FunctionDef) and
-                      not func.is_constructor_of, self.functions)
+        def _find_functions(func):
+            return isinstance(func, FunctionDef) and not func.is_constructor_of
+        return list(filter(_find_functions, self.functions))
 
     def ifdef(self, *args):
         if args[0] in self.defines:
diff --git a/codegen/docextract.py b/codegen/libcodegen/docextract.py
similarity index 99%
rename from codegen/docextract.py
rename to codegen/libcodegen/docextract.py
index e6c6505..c0bc0fe 100644
--- a/codegen/docextract.py
+++ b/codegen/libcodegen/docextract.py
@@ -2,7 +2,8 @@
 '''Simple module for extracting GNOME style doc comments from C
 sources, so I can use them for other purposes.'''
 
-import sys, os, string, re
+import sys, os, re
+from libcodegen.string_compat import string
 
 __all__ = ['extract']
 
diff --git a/codegen/override.py b/codegen/libcodegen/override.py
similarity index 94%
rename from codegen/override.py
rename to codegen/libcodegen/override.py
index bba5e42..414d1a2 100644
--- a/codegen/override.py
+++ b/codegen/libcodegen/override.py
@@ -7,7 +7,7 @@
 import fnmatch
 import os
 import re
-import string
+from libcodegen.string_compat import string
 import sys
 
 def class2cname(klass, method):
@@ -179,7 +179,7 @@ class Overrides:
             if func.find('.') != -1:
                 klass, func = func.split('.', 1)
 
-                if not self.defines.has_key(klass):
+                if klass not in self.defines:
                     self.defines[klass] = {}
                 self.defines[klass][func] = rest
             else:
@@ -209,7 +209,7 @@ class Overrides:
                     self.dynamicnamespace = True
 
     def is_ignored(self, name):
-        if self.ignores.has_key(name):
+        if name in self.ignores:
             return 1
         for glob in self.glob_ignores:
             if fnmatch.fnmatchcase(name, glob):
@@ -220,10 +220,10 @@ class Overrides:
         return name in self.type_ignores
 
     def is_overriden(self, name):
-        return self.overrides.has_key(name)
+        return name in self.overrides
 
     def is_already_included(self, name):
-        return self.overridden.has_key(name)
+        return name in self.overridden
 
     def override(self, name):
         self.overridden[name] = 1
@@ -240,28 +240,28 @@ class Overrides:
         return self.startlines[name]
 
     def wants_kwargs(self, name):
-        return self.kwargs.has_key(name)
+        return name in self.kwargs
 
     def wants_noargs(self, name):
-        return self.noargs.has_key(name)
+        return name in self.noargs
 
     def wants_onearg(self, name):
-        return self.onearg.has_key(name)
+        return name in self.onearg
 
     def is_staticmethod(self, name):
-        return self.staticmethod.has_key(name)
+        return name in self.staticmethod
 
     def is_classmethod(self, name):
-        return self.classmethod.has_key(name)
+        return name in self.classmethod
 
     def attr_is_overriden(self, attr):
-        return self.override_attrs.has_key(attr)
+        return attr in self.override_attrs
 
     def attr_override(self, attr):
         return self.override_attrs[attr]
 
     def slot_is_overriden(self, slot):
-        return self.override_slots.has_key(slot)
+        return slot in self.override_slots
 
     def slot_override(self, slot):
         return self.override_slots[slot]
diff --git a/codegen/reversewrapper.py b/codegen/libcodegen/reversewrapper.py
similarity index 98%
rename from codegen/reversewrapper.py
rename to codegen/libcodegen/reversewrapper.py
index ed48629..5b69c17 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 libcodegen import argtypes
 import os
 
 DEBUG_MODE = ('PYGTK_CODEGEN_DEBUG' in os.environ)
@@ -215,7 +215,7 @@ class ReverseWrapper(object):
             sink.writeln('static %s' % self.return_type.get_c_type())
         else:
             sink.writeln(self.return_type.get_c_type())
-        c_proto_params = map(Parameter.format_for_c_proto, self.parameters)
+        c_proto_params = list(map(Parameter.format_for_c_proto, self.parameters))
         sink.writeln("%s(%s)\n{" % (self.cname, ", ".join(c_proto_params)))
 
         self.return_type.write_decl()
@@ -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/scmexpr.py b/codegen/libcodegen/scmexpr.py
similarity index 96%
rename from codegen/scmexpr.py
rename to codegen/libcodegen/scmexpr.py
index 02f2e4b..65a8f41 100644
--- a/codegen/scmexpr.py
+++ b/codegen/libcodegen/scmexpr.py
@@ -2,8 +2,12 @@
 # -*- Mode: Python; py-indent-offset: 4 -*-
 from __future__ import generators
 
-import string
-from cStringIO import StringIO
+from libcodegen.string_compat import string
+
+try:
+    from io import StringIO
+except ImportError:
+    from cStringIO import StringIO
 
 class error(Exception):
     def __init__(self, filename, lineno, msg):
@@ -140,4 +144,4 @@ if __name__ == '__main__':
         fp = StringIO(_testString)
     statements = parse(fp)
     for s in statements:
-        print `s`
+        sys.stdout.write("%s\n" % repr(s))
diff --git a/codegen/libcodegen/string_compat.py b/codegen/libcodegen/string_compat.py
new file mode 100644
index 0000000..220c900
--- /dev/null
+++ b/codegen/libcodegen/string_compat.py
@@ -0,0 +1,41 @@
+
+import string
+
+try:
+    string.letters
+except AttributeError:
+    string.letters = string.ascii_letters
+    def _join(some_list, sep=""):
+        return sep.join(some_list)
+    string.join = _join
+    del _join
+
+    def _translate(s, table, deletions=""):
+        return s.translate(table)
+    string.translate = _translate
+    del _translate
+
+    def _replace(*args): 
+        return args[0].replace(*args[1:])
+    string.replace = _replace
+    del _replace
+
+    def _find(s, something):
+        return s.find(something)
+    string.find = _find
+    del _find
+    
+    def _split(s, sep=None, maxsplit=-1):
+        return s.split(sep, maxsplit)
+    string.split = _split
+    del _split
+    
+    def _count(s, pattern):
+        return s.count(pattern)
+    string.count = _count
+    del _count
+    
+    def _lower(s):
+        return s.lower()
+    string.lower = _lower
+    del _lower
\ No newline at end of file
diff --git a/codegen/mergedefs.py b/codegen/mergedefs.py
index 773e499..a600200 100755
--- a/codegen/mergedefs.py
+++ b/codegen/mergedefs.py
@@ -3,7 +3,7 @@
 
 import optparse
 
-import defsparser
+from libcodegen import defsparser
 
 parser = optparse.OptionParser(
     usage="usage: %prog [options] generated-defs old-defs")
diff --git a/codegen/missingdefs.py b/codegen/missingdefs.py
index f0017e7..b71963b 100755
--- a/codegen/missingdefs.py
+++ b/codegen/missingdefs.py
@@ -2,7 +2,7 @@
 # -*- Mode: Python; py-indent-offset: 4 -*-
 
 import sys
-import defsparser
+from libcodegen import defsparser
 
 if len(sys.argv) < 3:
     sys.stderr.write("Usage: missingdefs.py generated-defs old-defs\n")
diff --git a/codegen/mkskel.py b/codegen/mkskel.py
index 61f520b..74db062 100755
--- a/codegen/mkskel.py
+++ b/codegen/mkskel.py
@@ -81,9 +81,9 @@ if __name__ == '__main__':
         elif opt in ('-m', '--module'):
             module = arg
         elif opt in ('-h', '--help'):
-            print 'usage: mkskel.py -f fileprefix -p prefix -m module'
+            sys.stdout.write('usage: mkskel.py -f fileprefix -p prefix -m module\n')
             sys.exit(0)
     if not fileprefix or not prefix or not module:
-        print 'usage: mkskel.py -f fileprefix -p prefix -m module'
+        sys.stdout.write('usage: mkskel.py -f fileprefix -p prefix -m module\n')
         sys.exit(1)
     write_skels(fileprefix, prefix, module)
diff --git a/codegen/scanvirtuals.py b/codegen/scanvirtuals.py
index c108737..22a91c5 100755
--- a/codegen/scanvirtuals.py
+++ b/codegen/scanvirtuals.py
@@ -21,7 +21,7 @@ def main():
                 continue
             params = []
             if not m[2]:
-                print >> sys.stderr, repr(m)
+                sys.stderr.write("%s\n" % repr(m))
                 continue
             for param in map(str.strip, m[2].split(',')):
                 if '*' in param:
@@ -31,7 +31,7 @@ def main():
                 else:
                     if param == 'void':
                         continue
-                    ptype, pname = map(str.strip, param.split())
+                    ptype, pname = list(map(str.strip, param.split()))
                 ptype = ptype.replace('const ', 'const-')
                 while '[]' in pname:
                     pname = pname.replace('[]', '')
@@ -40,15 +40,15 @@ def main():
             if not params:
                 continue
             objname = params[0][0].replace('*', '')
-            print '(define-virtual', virtual_name
-            print '  (of-object "%s")' % objname
-            print '  (return-type "%s")' % return_type
+            sys.stdout.write('(define-virtual %s\n' % virtual_name)
+            sys.stdout.write('  (of-object "%s")\n' % objname)
+            sys.stdout.write('  (return-type "%s")\n' % return_type)
             if len(params) > 1:
-                print '  (parameters'
+                sys.stdout.write('  (parameters\n')
                 for param in params[1:]:
-                    print '    \'("%s" "%s")' % param
-                print '  )'
-            print ')'
+                    swys.stdout.write('    \'("%s" "%s")\n' % param)
+                sys.stdout.write('  )\n')
+            sys.stdout.write(')\n')
 
 if __name__ == '__main__':
     main()
