[jhbuild/wip/sam/python3: 3/4] Initial conversion to Python3, not yet working



commit 419ae924a1b9e64a61d1bc79641a98ae1218fe18
Author: Sam Thursfield <sam thursfield codethink co uk>
Date:   Wed Jan 27 12:37:47 2016 +0100

    Initial conversion to Python3, not yet working
    
    Mostly converted using '2to3'

 configure.ac                             |    2 +-
 jhbuild/buildbot/changes.py              |    2 +-
 jhbuild/buildbot/factory.py              |    2 +-
 jhbuild/buildbot/status/web/__init__.py  |    8 +-
 jhbuild/buildbot/status/web/bot.py       |    2 +-
 jhbuild/buildbot/status/web/build.py     |   14 ++--
 jhbuild/buildbot/status/web/builder.py   |    4 +-
 jhbuild/buildbot/status/web/feeds.py     |    4 +-
 jhbuild/buildbot/status/web/step.py      |    6 +-
 jhbuild/buildbot/status/web/waterfall.py |   17 +++--
 jhbuild/buildbot/steps.py                |    4 +-
 jhbuild/commands/__init__.py             |   28 ++++----
 jhbuild/commands/base.py                 |   16 ++--
 jhbuild/commands/bot.py                  |   31 ++++----
 jhbuild/commands/checkmodulesets.py      |    2 +-
 jhbuild/commands/extdeps.py              |   42 ++++++------
 jhbuild/commands/goalreport.py           |  112 +++++++++++++++---------------
 jhbuild/commands/info.py                 |    8 +-
 jhbuild/commands/make.py                 |    2 +-
 jhbuild/commands/sanitycheck.py          |    2 +-
 jhbuild/commands/snapshot.py             |    6 +-
 jhbuild/commands/sysdeps.py              |   60 ++++++++--------
 jhbuild/commands/twoninetynine.py        |    2 +-
 jhbuild/config.py                        |   18 +++---
 jhbuild/defaults.jhbuildrc               |    2 +-
 jhbuild/environment.py                   |    4 +-
 jhbuild/frontends/autobuild.py           |   58 ++++++++--------
 jhbuild/frontends/buildscript.py         |    8 +-
 jhbuild/frontends/gtkui.py               |   16 ++--
 jhbuild/frontends/terminal.py            |   30 ++++----
 jhbuild/frontends/tinderbox.py           |   24 +++---
 jhbuild/main.py                          |   30 ++++----
 jhbuild/modtypes/__init__.py             |   16 ++--
 jhbuild/modtypes/autotools.py            |    8 +-
 jhbuild/modtypes/linux.py                |    3 +-
 jhbuild/modtypes/tarball.py              |    2 +-
 jhbuild/modtypes/testmodule.py           |   10 ++--
 jhbuild/moduleset.py                     |   38 +++++-----
 jhbuild/monkeypatch.py                   |    2 +-
 jhbuild/utils/cmds.py                    |    8 +-
 jhbuild/utils/fileutils.py               |    4 +-
 jhbuild/utils/httpcache.py               |   30 ++++----
 jhbuild/utils/packagedb.py               |    2 +-
 jhbuild/utils/sxml.py                    |    8 +-
 jhbuild/utils/systeminstall.py           |   14 ++--
 jhbuild/utils/trayicon.py                |    2 +-
 jhbuild/utils/unpack.py                  |    8 +-
 jhbuild/versioncontrol/__init__.py       |    8 ++-
 jhbuild/versioncontrol/bzr.py            |   37 +++++-----
 jhbuild/versioncontrol/cvs.py            |    2 +-
 jhbuild/versioncontrol/darcs.py          |    8 +-
 jhbuild/versioncontrol/fossil.py         |    6 +-
 jhbuild/versioncontrol/git.py            |   30 ++++----
 jhbuild/versioncontrol/hg.py             |    6 +-
 jhbuild/versioncontrol/svn.py            |   34 +++++-----
 jhbuild/versioncontrol/tarball.py        |   16 ++--
 scripts/changecvsroot.py                 |    3 +-
 scripts/hg-update.py                     |    8 +-
 scripts/jhbuild.in                       |   10 ++--
 scripts/mk-tarball-moduleset.py          |   20 +++---
 tests/tests.py                           |   26 ++++----
 61 files changed, 472 insertions(+), 463 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 08078a0..1c9067e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -13,7 +13,7 @@ AM_MAINTAINER_MODE([enable])
 
 # Check for programs
 AC_PROG_CC
-AM_PATH_PYTHON
+AM_PATH_PYTHON([3])
 PKG_PROG_PKG_CONFIG
 
 # i18n
diff --git a/jhbuild/buildbot/changes.py b/jhbuild/buildbot/changes.py
index 076d759..be23bcb 100644
--- a/jhbuild/buildbot/changes.py
+++ b/jhbuild/buildbot/changes.py
@@ -127,7 +127,7 @@ class GnomeMaildirSource(MaildirSource):
                 else:
                     comments += line[4:] + '\n'
 
-            comments = unicode(comments.strip(), m.get_content_charset() or 'ascii', 'ignore')
+            comments = str(comments.strip(), m.get_content_charset() or 'ascii', 'ignore')
 
         c = changes.Change(name, files, comments, isdir, revision=revision, links=links, when=when)
         c.project = project
diff --git a/jhbuild/buildbot/factory.py b/jhbuild/buildbot/factory.py
index cecd7b7..fcab807 100644
--- a/jhbuild/buildbot/factory.py
+++ b/jhbuild/buildbot/factory.py
@@ -18,7 +18,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #
 from buildbot.process import factory
-from steps import JHBuildSource, JHBuildCommand, JHBuildModulePathCommand, JHBuildCheckCommand
+from .steps import JHBuildSource, JHBuildCommand, JHBuildModulePathCommand, JHBuildCheckCommand
 
 class JHBuildFactory(factory.BuildFactory):
     module = None
diff --git a/jhbuild/buildbot/status/web/__init__.py b/jhbuild/buildbot/status/web/__init__.py
index 5a6b5a1..eba48b4 100644
--- a/jhbuild/buildbot/status/web/__init__.py
+++ b/jhbuild/buildbot/status/web/__init__.py
@@ -25,10 +25,10 @@ from buildbot import interfaces, util
 from buildbot.status.builder import SUCCESS, WARNINGS, FAILURE, EXCEPTION
 from buildbot.status.web.baseweb import WebStatus
 
-from waterfall import JhWaterfallStatusResource
-from changes import  ChangesResource
-from builder import JhBuildersResource
-from bot import JhBuildbotsResource
+from .waterfall import JhWaterfallStatusResource
+from .changes import  ChangesResource
+from .builder import JhBuildersResource
+from .bot import JhBuildbotsResource
 
 
 def content(self, request):
diff --git a/jhbuild/buildbot/status/web/bot.py b/jhbuild/buildbot/status/web/bot.py
index 2090ab2..76d7f11 100644
--- a/jhbuild/buildbot/status/web/bot.py
+++ b/jhbuild/buildbot/status/web/bot.py
@@ -17,7 +17,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-import urllib, time
+import urllib.request, urllib.parse, urllib.error, time
 
 from twisted.web import html
 from twisted.web.util import Redirect
diff --git a/jhbuild/buildbot/status/web/build.py b/jhbuild/buildbot/status/web/build.py
index dd8dce2..66f8889 100644
--- a/jhbuild/buildbot/status/web/build.py
+++ b/jhbuild/buildbot/status/web/build.py
@@ -17,7 +17,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-import urllib, time
+import urllib.request, urllib.parse, urllib.error, time
 
 from twisted.web import html
 from twisted.web.util import Redirect
@@ -26,7 +26,7 @@ from buildbot.status.web.build import BuildsResource, StatusResourceBuild
 from buildbot.status.web.base import HtmlResource, make_row, make_stop_form, \
      css_classes, make_name_user_passwd_form
 
-from step import JhStepsResource
+from .step import JhStepsResource
 
 
 class JhStatusResourceBuild(StatusResourceBuild):
@@ -64,7 +64,7 @@ class JhStatusResourceBuild(StatusResourceBuild):
                 data += '<div>ETA %ds (%s)</div>\n' % (when, when_time)
 
             if self.build_control is not None:
-                stopURL = urllib.quote(req.childLink("stop"))
+                stopURL = urllib.parse.quote(req.childLink("stop"))
                 data += make_stop_form(stopURL, self.isUsingUserPasswd(req))
 
         if b.isFinished():
@@ -113,7 +113,7 @@ class JhStatusResourceBuild(StatusResourceBuild):
             for s in b.getSteps():
                 name = s.getName()
                 data += (" <li><a href=\"%s\">%s</a> [%s]\n"
-                         % (req.childLink("steps/%s" % urllib.quote(name)),
+                         % (req.childLink("steps/%s" % urllib.parse.quote(name)),
                             name,
                             " ".join(s.getText())))
                 if s.getLogs():
@@ -121,8 +121,8 @@ class JhStatusResourceBuild(StatusResourceBuild):
                     for logfile in s.getLogs():
                         logname = logfile.getName()
                         logurl = req.childLink("steps/%s/logs/%s" %
-                                               (urllib.quote(name),
-                                                urllib.quote(logname)))
+                                               (urllib.parse.quote(name),
+                                                urllib.parse.quote(logname)))
                         data += ("   <li><a href=\"%s\">%s</a></li>\n" %
                                  (logurl, logfile.getName()))
                     data += "  </ul>\n"
@@ -165,7 +165,7 @@ class JhStatusResourceBuild(StatusResourceBuild):
                          "exactly. Any changes that have been committed \n"
                          "after this build was started <b>will</b> be \n"
                          "included in a rebuild.</p>\n")
-            rebuildURL = urllib.quote(req.childLink("rebuild"))
+            rebuildURL = urllib.parse.quote(req.childLink("rebuild"))
             data += ('<form method="post" action="%s" class="command rebuild">\n'
                      % rebuildURL)
             data += make_name_user_passwd_form(self.isUsingUserPasswd(req))
diff --git a/jhbuild/buildbot/status/web/builder.py b/jhbuild/buildbot/status/web/builder.py
index bce5b37..ad53151 100644
--- a/jhbuild/buildbot/status/web/builder.py
+++ b/jhbuild/buildbot/status/web/builder.py
@@ -17,7 +17,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-import urllib, time
+import urllib.request, urllib.parse, urllib.error, time
 
 from twisted.web import html
 from twisted.web.util import Redirect
@@ -26,7 +26,7 @@ from buildbot.status.web.builder import BuildersResource, StatusResourceBuilder
 from buildbot.status.web.base import make_row, make_force_build_form, \
              path_to_slave, path_to_builder
 
-from build import JhBuildsResource
+from .build import JhBuildsResource
 
 class JhStatusResourceBuilder(StatusResourceBuilder):
     def getTitle(self, request):
diff --git a/jhbuild/buildbot/status/web/feeds.py b/jhbuild/buildbot/status/web/feeds.py
index 4ae23db..5e9f00c 100644
--- a/jhbuild/buildbot/status/web/feeds.py
+++ b/jhbuild/buildbot/status/web/feeds.py
@@ -72,7 +72,7 @@ class FeedResource(XmlResource):
     def getBuilds(self):
         builds = []
         builderNames = self.status.getBuilderNames(categories=self.categories)
-        builders = map(lambda name: self.status.getBuilder(name), builderNames)
+        builders = [self.status.getBuilder(name) for name in builderNames]
         maxFeeds = 5
 
         # Copy all failed builds in a new list.
@@ -185,7 +185,7 @@ class FeedResource(XmlResource):
                               description = description,
                               link=link,pubDate=strFinished)
 
-        if type(data) is unicode:
+        if type(data) is str:
             data = data.encode('utf-8', 'ignore')
         return data
 
diff --git a/jhbuild/buildbot/status/web/step.py b/jhbuild/buildbot/status/web/step.py
index b333b4d..16fdcc8 100644
--- a/jhbuild/buildbot/status/web/step.py
+++ b/jhbuild/buildbot/status/web/step.py
@@ -17,7 +17,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-import urllib
+import urllib.request, urllib.parse, urllib.error
 
 from twisted.web.util import Redirect
 from twisted.web import html
@@ -26,7 +26,7 @@ from buildbot.status.web.base import HtmlResource
 from buildbot.status.web.step import StepsResource, StatusResourceBuildStep
 from buildbot.status.builder import SUCCESS, WARNINGS, FAILURE, EXCEPTION
 
-from logs import JhLogsResource
+from .logs import JhLogsResource
 
 class JhStatusResourceBuildStep(StatusResourceBuildStep):
     def getTitle(self, request):
@@ -87,7 +87,7 @@ class JhStatusResourceBuildStep(StatusResourceBuildStep):
                     # are not safe, it escapes the / that separates the
                     # step name from the log number.
                     logname = logfile.getName()
-                    logurl = req.childLink("logs/%s" % urllib.quote(logname))
+                    logurl = req.childLink("logs/%s" % urllib.parse.quote(logname))
                     data += ('<li><a href="%s">%s</a></li>\n' % 
                              (logurl, html.escape(logname)))
                 else:
diff --git a/jhbuild/buildbot/status/web/waterfall.py b/jhbuild/buildbot/status/web/waterfall.py
index c793011..0df24e3 100644
--- a/jhbuild/buildbot/status/web/waterfall.py
+++ b/jhbuild/buildbot/status/web/waterfall.py
@@ -20,7 +20,7 @@
 # heavily based on buildbot code,
 #   Copyright (C) Brian Warner <warner-buildbot lothar com>
 
-import time, urllib
+import time, urllib.request, urllib.parse, urllib.error
 
 from buildbot import version
 from buildbot.changes.changes import Change
@@ -31,14 +31,15 @@ from buildbot.status.web.waterfall import WaterfallStatusResource, Spacer
 from buildbot.status.web.base import Box, HtmlResource, IBox, ICurrentBox, \
      ITopBox, td, build_get_class, path_to_build, path_to_step, map_branches
 
-from feeds import Rss20StatusResource, Atom10StatusResource
+from .feeds import Rss20StatusResource, Atom10StatusResource
+from functools import reduce
 
 def insertGaps(g, lastEventTime, idleGap=2, showEvents=False):
     # summary of changes between this function and the one from buildbot:
     #  - do not insert time gaps for events that are not shown
     debug = False
 
-    e = g.next()
+    e = next(g)
     starts, finishes = e.getTimes()
     if debug: log.msg("E0", starts, finishes)
     if finishes == 0:
@@ -54,7 +55,7 @@ def insertGaps(g, lastEventTime, idleGap=2, showEvents=False):
     yield e
 
     while 1:
-        e = g.next()
+        e = next(g)
         if isinstance(e, builder.Event) and not showEvents:
             continue
         starts, finishes = e.getTimes()
@@ -127,7 +128,7 @@ class JhWaterfallStatusResource(WaterfallStatusResource):
         lastEventTime = util.now()
         sources = [commit_source] + builders
         changeNames = ["changes"]
-        builderNames = map(lambda builder: builder.getName(), builders)
+        builderNames = [builder.getName() for builder in builders]
         sourceNames = changeNames + builderNames
         sourceEvents = []
         sourceGenerators = []
@@ -136,7 +137,7 @@ class JhWaterfallStatusResource(WaterfallStatusResource):
         def get_event_from(g):
             try:
                 while True:
-                    e = g.next()
+                    e = next(g)
                     # e might be builder.BuildStepStatus,
                     # builder.BuildStatus, builder.Event,
                     # waterfall.Spacer(builder.Event), or changes.Change .
@@ -298,7 +299,7 @@ class JhWaterfallStatusResource(WaterfallStatusResource):
             builder_name = b.name[len(self.module_name)+1:]
             data += '<th class="%s" title="%s"><a href="%s">%s</a></th>' % (
                     state, state,
-                    request.childLink('../builders/%s' % urllib.quote(b.name, safe='')),
+                    request.childLink('../builders/%s' % urllib.parse.quote(b.name, safe='')),
                     builder_name)
         data += '</tr>\n'
 
@@ -383,7 +384,7 @@ class JhWaterfallStatusResource(WaterfallStatusResource):
             # is a vertical list of events, all for the same source.
             assert(len(chunkstrip) == len(sourceNames))
             maxRows = reduce(lambda x,y: max(x,y),
-                             map(lambda x: len(x), chunkstrip))
+                             [len(x) for x in chunkstrip])
             for i in range(maxRows):
                 if i != maxRows-1:
                     grid[0].append(None)
diff --git a/jhbuild/buildbot/steps.py b/jhbuild/buildbot/steps.py
index 9ad5520..21ba288 100644
--- a/jhbuild/buildbot/steps.py
+++ b/jhbuild/buildbot/steps.py
@@ -17,7 +17,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-import os, commands, re, StringIO
+import os, subprocess, re, io
 
 from buildbot.process import factory
 from buildbot.process import buildstep
@@ -247,7 +247,7 @@ class JHBuildModulePathCommand(steps.shell.ShellCommand):
             return SUCCESS     
 
     def createSummary(self, log):
-        output = StringIO.StringIO(log.getText())
+        output = io.StringIO(log.getText())
         warnings = []
         for line in output.readlines():
             if "warning:" in line:
diff --git a/jhbuild/commands/__init__.py b/jhbuild/commands/__init__.py
index 60621f7..ca5a486 100644
--- a/jhbuild/commands/__init__.py
+++ b/jhbuild/commands/__init__.py
@@ -68,7 +68,7 @@ class BuildCommand(Command):
     def required_system_dependencies_installed(self, module_state):
         '''Returns true if all required system dependencies are installed for
         modules in module_state.'''
-        for module, (req_version, installed_version, new_enough, systemmodule) in module_state.iteritems():
+        for module, (req_version, installed_version, new_enough, systemmodule) in module_state.items():
             if systemmodule:
                 if not new_enough:
                     return False
@@ -91,30 +91,30 @@ class BuildCommand(Command):
             else:
                 return ''
 
-        print _('Required packages:')
-        print _('  System installed packages which are too old:')
+        print(_('Required packages:'))
+        print(_('  System installed packages which are too old:'))
         have_too_old = False
-        for module, (req_version, installed_version, new_enough, systemmodule) in module_state.iteritems():
+        for module, (req_version, installed_version, new_enough, systemmodule) in module_state.items():
             if (installed_version is not None) and (not new_enough) and systemmodule:
                 have_too_old = True
-                print ('    %s %s' % (module.name,
+                print(('    %s %s' % (module.name,
                                       fmt_details(module.pkg_config,
                                                   req_version,
-                                                  installed_version)))
+                                                  installed_version))))
         if not have_too_old:
-            print _('    (none)')
+            print(_('    (none)'))
 
-        print _('  No matching system package installed:')
+        print(_('  No matching system package installed:'))
         have_missing = False
-        for module, (req_version, installed_version, new_enough, systemmodule) in module_state.iteritems():
+        for module, (req_version, installed_version, new_enough, systemmodule) in module_state.items():
             if installed_version is None and (not new_enough) and systemmodule:
                 have_missing = True
-                print ('    %s %s' % (module.name,
+                print(('    %s %s' % (module.name,
                                       fmt_details(module.pkg_config,
                                                   req_version,
-                                                  installed_version)))
+                                                  installed_version))))
         if not have_missing:
-            print _('    (none)')
+            print(_('    (none)'))
 
 
 def print_help():
@@ -132,11 +132,11 @@ def print_help():
             pass
 
     uprint(_('JHBuild commands are:'))
-    commands = [(x.name, x.doc) for x in get_commands().values()]
+    commands = [(x.name, x.doc) for x in list(get_commands().values())]
     commands.sort()
     for name, description in commands:
         uprint('  %-15s %s' % (name, description))
-    print
+    print()
     uprint(_('For more information run "jhbuild <command> --help"'))
 
 # handle registration of new commands
diff --git a/jhbuild/commands/base.py b/jhbuild/commands/base.py
index f66ac14..9cfa3f0 100644
--- a/jhbuild/commands/base.py
+++ b/jhbuild/commands/base.py
@@ -100,7 +100,7 @@ class cmd_updateone(Command):
         module_set = jhbuild.moduleset.load(config)
         try:
             module_list = [module_set.get_module(modname, ignore_case = True) for modname in args]
-        except KeyError, e:
+        except KeyError as e:
             raise FatalError(_("A module called '%s' could not be found.") % e)
 
         if not module_list:
@@ -138,7 +138,7 @@ class cmd_cleanone(Command):
         module_set = jhbuild.moduleset.load(config)
         try:
             module_list = [module_set.get_module(modname, ignore_case = True) for modname in args]
-        except KeyError, e:
+        except KeyError as e:
             raise FatalError(_("A module called '%s' could not be found.") % e)
 
         if not module_list:
@@ -325,7 +325,7 @@ class cmd_buildone(BuildCommand):
             modname = modname.rstrip(os.sep)
             try:
                 module = module_set.get_module(modname, ignore_case=True)
-            except KeyError, e:
+            except KeyError as e:
                 default_repo = jhbuild.moduleset.get_default_repo()
                 if not default_repo:
                     continue
@@ -369,7 +369,7 @@ class cmd_run(Command):
             return self.run(config, options, args)
         try:
             return os.execlp(args[0], *args)
-        except OSError, exc:
+        except OSError as exc:
             raise FatalError(_("Unable to execute the command '%(command)s': %(err)s") % {
                     'command':args[0], 'err':str(exc)})
 
@@ -379,7 +379,7 @@ class cmd_run(Command):
             module_set = jhbuild.moduleset.load(config)
             try:
                 module = module_set.get_module(module_name, ignore_case = True)
-            except KeyError, e:
+            except KeyError as e:
                 raise FatalError(_("A module called '%s' could not be found.") % e)
 
             build = jhbuild.frontends.get_buildscript(config, [module], module_set=module_set)
@@ -389,7 +389,7 @@ class cmd_run(Command):
                 workingdir = module.get_srcdir(build)
             try:
                 build.execute(args, cwd=workingdir)
-            except CommandError, exc:
+            except CommandError as exc:
                 if args:
                     raise FatalError(_("Unable to execute the command '%s'") % args[0])
                 else:
@@ -399,7 +399,7 @@ class cmd_run(Command):
                 os.execlp(args[0], *args)
             except IndexError:
                 raise FatalError(_('No command given'))
-            except OSError, exc:
+            except OSError as exc:
                 raise FatalError(_("Unable to execute the command '%(command)s': %(err)s") % {
                         'command':args[0], 'err':str(exc)})
 
@@ -459,7 +459,7 @@ class cmd_list(Command):
             raise UsageError(_('Conflicting options specified (\'--start-at\' and \'--all-modules\')'))
 
         if options.list_all_modules:
-            module_list = module_set.modules.values()
+            module_list = list(module_set.modules.values())
         else:
             module_list = module_set.get_module_list \
                               (args or config.modules, config.skip,
diff --git a/jhbuild/commands/bot.py b/jhbuild/commands/bot.py
index fce9497..f229f11 100644
--- a/jhbuild/commands/bot.py
+++ b/jhbuild/commands/bot.py
@@ -26,12 +26,13 @@
 import os
 import signal
 import sys
-import urllib
+import urllib.request, urllib.parse, urllib.error
 from optparse import make_option
 import socket
-import __builtin__
+import builtins
 import csv
 import logging
+import collections
 
 try:
     import elementtree.ElementTree as ET
@@ -116,7 +117,7 @@ class cmd_bot(Command):
 
         # make jhbuild config file accessible to buildbot files
         # (master.cfg , steps.py, etc.)
-        __builtin__.__dict__['jhbuild_config'] = config
+        builtins.__dict__['jhbuild_config'] = config
 
         daemonize = False
         pidfile = None
@@ -146,7 +147,7 @@ class cmd_bot(Command):
             os.environ['LC_ALL'] = 'C'
             os.environ['LANGUAGE'] = 'C'
             os.environ['LANG'] = 'C'
-            __builtin__.__dict__['_'] = lambda x: x
+            builtins.__dict__['_'] = lambda x: x
             config.interact = False
             config.nonetwork = True
             os.environ['TERM'] = 'dumb'
@@ -347,7 +348,7 @@ class cmd_bot(Command):
                 # have to copy all that code.]
                 localDict = {'basedir': os.path.expanduser(self.basedir)}
                 try:
-                    exec f in localDict
+                    exec(f, localDict)
                 except:
                     log.msg("error while parsing config file")
                     raise
@@ -371,7 +372,7 @@ class cmd_bot(Command):
                               "changeHorizon", "logMaxSize", "logMaxTailSize",
                               "logCompressionMethod",
                               )
-                for k in config.keys():
+                for k in list(config.keys()):
                     if k not in known_keys:
                         log.msg("unknown key '%s' defined in config dictionary" % k)
 
@@ -453,7 +454,7 @@ class cmd_bot(Command):
                         })
 
                 # Status targets
-                if not config.has_key('status'):
+                if 'status' not in config:
                     # let it be possible to define additional status in
                     # master.cfg
                     config['status'] = []
@@ -505,16 +506,16 @@ class cmd_bot(Command):
                             isinstance(logMaxTailSize, int):
                         raise ValueError("logMaxTailSize needs to be None or int")
                     mergeRequests = config.get('mergeRequests')
-                    if mergeRequests is not None and not callable(mergeRequests):
+                    if mergeRequests is not None and not isinstance(mergeRequests, collections.Callable):
                         raise ValueError("mergeRequests must be a callable")
                     prioritizeBuilders = config.get('prioritizeBuilders')
-                    if prioritizeBuilders is not None and not callable(prioritizeBuilders):
+                    if prioritizeBuilders is not None and not isinstance(prioritizeBuilders, 
collections.Callable):
                         raise ValueError("prioritizeBuilders must be callable")
                     changeHorizon = config.get("changeHorizon")
                     if changeHorizon is not None and not isinstance(changeHorizon, int):
                         raise ValueError("changeHorizon needs to be an int")
 
-                except KeyError, e:
+                except KeyError as e:
                     log.msg("config dictionary is missing a required parameter")
                     log.msg("leaving old configuration in place")
                     raise
@@ -561,7 +562,7 @@ class cmd_bot(Command):
                     if s.slavename in ("debug", "change", "status"):
                         raise KeyError(
                             "reserved name '%s' used for a bot" % s.slavename)
-                if config.has_key('interlocks'):
+                if 'interlocks' in config:
                     raise KeyError("c['interlocks'] is no longer accepted")
 
                 assert isinstance(change_sources, (list, tuple))
@@ -593,7 +594,7 @@ class cmd_bot(Command):
                 builders = builders_dicts
 
                 for b in builders:
-                    if b.has_key('slavename') and b['slavename'] not in slavenames:
+                    if 'slavename' in b and b['slavename'] not in slavenames:
                         raise ValueError("builder %s uses undefined slave %s" \
                                          % (b['name'], b['slavename']))
                     for n in b.get('slavenames', []):
@@ -652,7 +653,7 @@ class cmd_bot(Command):
                     for l in b.get('locks', []):
                         if isinstance(l, locks.LockAccess): # User specified access to the lock
                             l = l.lockid
-                        if lock_dict.has_key(l.name):
+                        if l.name in lock_dict:
                             if lock_dict[l.name] is not l:
                                 raise ValueError("Two different locks (%s and %s) "
                                                  "share the name %s"
@@ -666,7 +667,7 @@ class cmd_bot(Command):
                         for l in s[1].get('locks', []):
                             if isinstance(l, locks.LockAccess): # User specified access to the lock
                                 l = l.lockid
-                            if lock_dict.has_key(l.name):
+                            if l.name in lock_dict:
                                 if lock_dict[l.name] is not l:
                                     raise ValueError("Two different locks (%s and %s)"
                                                      " share the name %s"
@@ -702,7 +703,7 @@ class cmd_bot(Command):
                 # Update any of our existing builders with the current log parameters.
                 # This is required so that the new value is picked up after a
                 # reconfig.
-                for builder in self.botmaster.builders.values():
+                for builder in list(self.botmaster.builders.values()):
                     builder.builder_status.setLogCompressionLimit(logCompressionLimit)
                     builder.builder_status.setLogCompressionMethod(logCompressionMethod)
                     builder.builder_status.setLogMaxSize(logMaxSize)
diff --git a/jhbuild/commands/checkmodulesets.py b/jhbuild/commands/checkmodulesets.py
index 216a386..b94859f 100644
--- a/jhbuild/commands/checkmodulesets.py
+++ b/jhbuild/commands/checkmodulesets.py
@@ -19,7 +19,7 @@
 
 
 
-import urllib2
+import urllib.request, urllib.error, urllib.parse
 from optparse import make_option
 import logging
 
diff --git a/jhbuild/commands/extdeps.py b/jhbuild/commands/extdeps.py
index fa3fa26..9e310ee 100644
--- a/jhbuild/commands/extdeps.py
+++ b/jhbuild/commands/extdeps.py
@@ -24,9 +24,9 @@ import sys
 import time
 
 try:
-    from cStringIO import StringIO
+    from io import StringIO
 except ImportError:
-    from StringIO import StringIO
+    from io import StringIO
 
 import jhbuild.moduleset
 from jhbuild.commands import Command, register_command
@@ -87,7 +87,7 @@ class cmd_extdeps(Command):
         config.partial_build = False
         self.module_set = jhbuild.moduleset.load(config)
         if options.list_all_modules:
-            module_list = self.module_set.modules.values()
+            module_list = list(self.module_set.modules.values())
         else:
             module_list = self.module_set.get_module_list(args or config.modules, config.skip)
 
@@ -104,9 +104,9 @@ class cmd_extdeps(Command):
             title = _('External deps for GNOME %s') % gnome_ver
             break
 
-        print >> output, HTML_AT_TOP % {'title': title}
-        print >> output, '<table>'
-        print >> output, '<tbody>'
+        print(HTML_AT_TOP % {'title': title}, file=output)
+        print('<table>', file=output)
+        print('<tbody>', file=output)
 
         module_list.sort(lambda x,y: cmp(x.name.lower(), y.name.lower()))
         for mod in module_list:
@@ -131,28 +131,28 @@ class cmd_extdeps(Command):
                 if len(rdeps) > 5:
                     classes.append('many')
 
-            print >> output, '<tr class="%s">' % ' '.join(classes)
-            print >> output, '<th>%s</th>' % mod.name
+            print('<tr class="%s">' % ' '.join(classes), file=output)
+            print('<th>%s</th>' % mod.name, file=output)
             version = mod.branch.version
             if mod.branch.patches:
                 version = version + ' (%s)' % _('patched')
-            print >> output, '<td class="version">%s</td>' % version
-            print >> output, '<td class="url"><a href="%s">tarball</a></td>' % mod.branch.module
+            print('<td class="version">%s</td>' % version, file=output)
+            print('<td class="url"><a href="%s">tarball</a></td>' % mod.branch.module, file=output)
             if len(rdeps) > 5:
                 rdeps = rdeps[:4] + [_('and %d others.')  % (len(rdeps)-4)]
-            print >> output, '<td class="rdeps">%s</td>' % ', '.join(rdeps)
-            print >> output, '</tr>'
+            print('<td class="rdeps">%s</td>' % ', '.join(rdeps), file=output)
+            print('</tr>', file=output)
 
-        print >> output, '</tbody>'
-        print >> output, '</table>'
+        print('</tbody>', file=output)
+        print('</table>', file=output)
 
-        print >> output, '<div id="footer">'
-        print >> output, 'Generated:', time.strftime('%Y-%m-%d %H:%M:%S %z')
-        print >> output, 'on ', socket.getfqdn()
-        print >> output, '</div>'
+        print('<div id="footer">', file=output)
+        print('Generated:', time.strftime('%Y-%m-%d %H:%M:%S %z'), file=output)
+        print('on ', socket.getfqdn(), file=output)
+        print('</div>', file=output)
 
-        print >> output, '</body>'
-        print >> output, '</html>'
+        print('</body>', file=output)
+        print('</html>', file=output)
 
         if output != sys.stdout:
             file(options.output, 'w').write(output.getvalue())
@@ -160,7 +160,7 @@ class cmd_extdeps(Command):
 
     def compute_rdeps(self, module):
         rdeps = []
-        for mod in self.module_set.modules.values():
+        for mod in list(self.module_set.modules.values()):
             if mod.type == 'meta': continue
             if module.name in mod.dependencies:
                 rdeps.append(mod.name)
diff --git a/jhbuild/commands/goalreport.py b/jhbuild/commands/goalreport.py
index f841dfd..3adc6e8 100644
--- a/jhbuild/commands/goalreport.py
+++ b/jhbuild/commands/goalreport.py
@@ -24,13 +24,13 @@ import sys
 import subprocess
 import time
 import types
-import cPickle
+import pickle
 import logging
 from optparse import make_option
 try:
-    from cStringIO import StringIO
+    from io import StringIO
 except ImportError:
-    from StringIO import StringIO
+    from io import StringIO
 
 try:
     import elementtree.ElementTree as ET
@@ -198,7 +198,7 @@ class SymbolsCheck(Check):
                         deprecated_and_used[s] = True
         except UnicodeDecodeError:
             raise ExcludedModuleException()
-        self.bad_symbols = deprecated_and_used.keys()
+        self.bad_symbols = list(deprecated_and_used.keys())
         self.compute_status()
 
     def compute_status(self):
@@ -315,7 +315,7 @@ class DeprecatedSymbolsCheck(SymbolsCheck):
             except:
                 raise CouldNotPerformCheckException()
             for keyword in tree.findall('//{http://www.devhelp.net/book}keyword'):
-                if not keyword.attrib.has_key('deprecated'):
+                if 'deprecated' not in keyword.attrib:
                     continue
                 name = keyword.attrib.get('name').replace('enum ', '').replace('()', '').strip()
                 symbols.append(name)
@@ -384,7 +384,7 @@ class cmd_goalreport(Command):
 
         module_set = jhbuild.moduleset.load(config)
         if options.list_all_modules:
-            self.module_list = module_set.modules.values()
+            self.module_list = list(module_set.modules.values())
         else:
             self.module_list = module_set.get_module_list(args or config.modules, config.skip)
 
@@ -395,7 +395,7 @@ class cmd_goalreport(Command):
             cachedir = os.path.join(os.environ['HOME'], '.cache','jhbuild')
         if options.cache:
             try:
-                results = cPickle.load(file(os.path.join(cachedir, options.cache)))
+                results = pickle.load(file(os.path.join(cachedir, options.cache)))
             except:
                 pass
 
@@ -453,27 +453,27 @@ class cmd_goalreport(Command):
         if not os.path.exists(cachedir):
             os.makedirs(cachedir)
         if options.cache:
-            cPickle.dump(results, file(os.path.join(cachedir, options.cache), 'w'))
+            pickle.dump(results, file(os.path.join(cachedir, options.cache), 'w'))
 
-        print >> output, HTML_AT_TOP % {'title': self.title}
+        print(HTML_AT_TOP % {'title': self.title}, file=output)
         if self.page_intro:
-            print >> output, self.page_intro
-        print >> output, '<table>'
-        print >> output, '<thead>'
-        print >> output, '<tr><td></td>'
+            print(self.page_intro, file=output)
+        print('<table>', file=output)
+        print('<thead>', file=output)
+        print('<tr><td></td>', file=output)
         for check in self.checks:
-            print >> output, '<th>%s</th>' % check.__name__
-        print >> output, '<td></td></tr>'
+            print('<th>%s</th>' % check.__name__, file=output)
+        print('<td></td></tr>', file=output)
         if [x for x in self.checks if x.header_note]:
-            print >> output, '<tr><td></td>'
+            print('<tr><td></td>', file=output)
             for check in self.checks:
-                print >> output, '<td>%s</td>' % (check.header_note or '')
-            print >> output, '</tr>'
-        print >> output, '</thead>'
-        print >> output, '<tbody>'
+                print('<td>%s</td>' % (check.header_note or ''), file=output)
+            print('</tr>', file=output)
+        print('</thead>', file=output)
+        print('<tbody>', file=output)
 
         suites = []
-        for module_key, module in module_set.modules.items():
+        for module_key, module in list(module_set.modules.items()):
             if not isinstance(module_set.get_module(module_key), MetaModule):
                 continue
             if module_key.endswith('upcoming-deprecations'):
@@ -495,23 +495,23 @@ class cmd_goalreport(Command):
             module_names = [x for x in metamodule.dependencies if x in results]
             if not module_names:
                 continue
-            print >> output, '<tr><td class="heading" colspan="%d">%s</td></tr>' % (
-                    1+len(self.checks)+self.repeat_row_header, suite_label)
+            print('<tr><td class="heading" colspan="%d">%s</td></tr>' % (
+                    1+len(self.checks)+self.repeat_row_header, suite_label), file=output)
             for module_name in module_names:
                 if module_name in not_other_module_names:
                     continue
                 r = results[module_name].get('results')
-                print >> output, self.get_mod_line(module_name, r)
+                print(self.get_mod_line(module_name, r), file=output)
                 processed_modules[module_name] = True
             not_other_module_names.extend(module_names)
 
-        external_deps = [x for x in results.keys() if \
+        external_deps = [x for x in list(results.keys()) if \
                          x in [y.name for y in self.module_list] and \
                          not x in processed_modules and \
                          module_set.get_module(x).moduleset_name.startswith('gnome-external-deps')]
         if external_deps:
-            print >> output, '<tr><td class="heading" colspan="%d">%s</td></tr>' % (
-                    1+len(self.checks)+self.repeat_row_header, 'External Dependencies')
+            print('<tr><td class="heading" colspan="%d">%s</td></tr>' % (
+                    1+len(self.checks)+self.repeat_row_header, 'External Dependencies'), file=output)
             for module_name in sorted(external_deps):
                 if not module_name in results:
                     continue
@@ -520,49 +520,49 @@ class cmd_goalreport(Command):
                     version = module_set.get_module(module_name).branch.version
                 except:
                     version = None
-                print >> output, self.get_mod_line(module_name, r, version_number=version)
+                print(self.get_mod_line(module_name, r, version_number=version), file=output)
 
-        other_module_names = [x for x in results.keys() if \
+        other_module_names = [x for x in list(results.keys()) if \
                               not x in processed_modules and not x in external_deps]
         if other_module_names:
-            print >> output, '<tr><td class="heading" colspan="%d">%s</td></tr>' % (
-                    1+len(self.checks)+self.repeat_row_header, 'Others')
+            print('<tr><td class="heading" colspan="%d">%s</td></tr>' % (
+                    1+len(self.checks)+self.repeat_row_header, 'Others'), file=output)
             for module_name in sorted(other_module_names):
                 if not module_name in results:
                     continue
                 r = results[module_name].get('results')
-                print >> output, self.get_mod_line(module_name, r)
-        print >> output, '</tbody>'
-        print >> output, '<tfoot>'
+                print(self.get_mod_line(module_name, r), file=output)
+        print('</tbody>', file=output)
+        print('<tfoot>', file=output)
 
-        print >> output, '<tr><td></td>'
+        print('<tr><td></td>', file=output)
         for check in self.checks:
-            print >> output, '<th>%s</th>' % check.__name__
-        print >> output, '<td></td></tr>'
+            print('<th>%s</th>' % check.__name__, file=output)
+        print('<td></td></tr>', file=output)
 
-        print >> output, self.get_stat_line(results, not_other_module_names)
-        print >> output, '</tfoot>'
-        print >> output, '</table>'
+        print(self.get_stat_line(results, not_other_module_names), file=output)
+        print('</tfoot>', file=output)
+        print('</table>', file=output)
 
         if (options.bugfile and options.bugfile.startswith('http://')) or \
                 (options.falsepositivesfile and options.falsepositivesfile.startswith('http://')):
-            print >> output, '<div id="data">'
-            print >> output, '<p>The following data sources are used:</p>'
-            print >> output, '<ul>'
+            print('<div id="data">', file=output)
+            print('<p>The following data sources are used:</p>', file=output)
+            print('<ul>', file=output)
             if options.bugfile.startswith('http://'):
-                print >> output, '  <li><a href="%s">Bugs</a></li>' % options.bugfile
+                print('  <li><a href="%s">Bugs</a></li>' % options.bugfile, file=output)
             if options.falsepositivesfile.startswith('http://'):
-                print >> output, '  <li><a href="%s">False positives</a></li>' % options.falsepositivesfile
-            print >> output, '</ul>'
-            print >> output, '</div>'
+                print('  <li><a href="%s">False positives</a></li>' % options.falsepositivesfile, 
file=output)
+            print('</ul>', file=output)
+            print('</div>', file=output)
 
-        print >> output, '<div id="footer">'
-        print >> output, 'Generated:', time.strftime('%Y-%m-%d %H:%M:%S %z')
-        print >> output, 'on ', socket.getfqdn()
-        print >> output, '</div>'
+        print('<div id="footer">', file=output)
+        print('Generated:', time.strftime('%Y-%m-%d %H:%M:%S %z'), file=output)
+        print('on ', socket.getfqdn(), file=output)
+        print('</div>', file=output)
 
-        print >> output, '</body>'
-        print >> output, '</html>'
+        print('</body>', file=output)
+        print('</html>', file=output)
 
         if output != sys.stdout:
             file(options.output, 'w').write(output.getvalue())
@@ -676,7 +676,7 @@ class cmd_goalreport(Command):
                 filename += '?action=raw'
             try:
                 filename = httpcache.load(filename, age=0)
-            except Exception, e:
+            except Exception as e:
                 logging.warning('could not download %s: %s' % (filename, e))
                 return
         for line in file(filename):
@@ -702,7 +702,7 @@ class cmd_goalreport(Command):
         bug_status = httpcache.load(
                 'http://bugzilla.gnome.org/show_bug.cgi?%s&;'
                 'ctype=xml&field=bug_id&field=bug_status&field=emblems&'
-                'field=resolution' % '&'.join(['id=' + x for x in self.bugs.values() if x.isdigit()]),
+                'field=resolution' % '&'.join(['id=' + x for x in list(self.bugs.values()) if x.isdigit()]),
                 age=0)
         tree = ET.parse(bug_status)
         for bug in tree.findall('bug'):
@@ -723,7 +723,7 @@ class cmd_goalreport(Command):
                 filename += '?action=raw'
             try:
                 filename = httpcache.load(filename, age=0)
-            except Exception, e:
+            except Exception as e:
                 logging.warning('could not download %s: %s' % (filename, e))
                 return
         for line in file(filename):
diff --git a/jhbuild/commands/info.py b/jhbuild/commands/info.py
index f52b922..2da98ca 100644
--- a/jhbuild/commands/info.py
+++ b/jhbuild/commands/info.py
@@ -71,7 +71,7 @@ class cmd_info(Command):
                 return 1
         else:
             # no module names given
-            for module in module_set.modules.values():
+            for module in list(module_set.modules.values()):
                 package_entry = packagedb.get(module.name)
                 if options.installed:
                     if package_entry is not None:
@@ -133,7 +133,7 @@ class cmd_info(Command):
         # dependencies
         if module.dependencies:
             uprint(_('Requires:'), ', '.join(module.dependencies))
-        requiredby = [ mod.name for mod in module_set.modules.values()
+        requiredby = [ mod.name for mod in list(module_set.modules.values())
                        if module.name in mod.dependencies ]
         if requiredby:
             uprint(_('Required by:'), ', '.join(requiredby))
@@ -141,11 +141,11 @@ class cmd_info(Command):
             uprint(_('Suggests:'), ', '.join(module.suggests))
         if module.after:
             uprint(_('After:'), ', '.join(module.after))
-        before = [ mod.name for mod in module_set.modules.values()
+        before = [ mod.name for mod in list(module_set.modules.values())
                    if module.name in mod.after ]
         if before:
             uprint(_('Before:'), ', '.join(before))
 
-        print
+        print()
 
 register_command(cmd_info)
diff --git a/jhbuild/commands/make.py b/jhbuild/commands/make.py
index aad0045..2c67242 100644
--- a/jhbuild/commands/make.py
+++ b/jhbuild/commands/make.py
@@ -84,7 +84,7 @@ class cmd_make(Command):
 
         try:
             module = module_set.get_module(modname, ignore_case=True)
-        except KeyError, e:
+        except KeyError as e:
             default_repo = jhbuild.moduleset.get_default_repo()
             if not default_repo:
                 logging.error(_('No module matching current directory %r in the moduleset') % (modname, ))
diff --git a/jhbuild/commands/sanitycheck.py b/jhbuild/commands/sanitycheck.py
index 5700d00..d44757a 100644
--- a/jhbuild/commands/sanitycheck.py
+++ b/jhbuild/commands/sanitycheck.py
@@ -166,7 +166,7 @@ class cmd_sanitycheck(Command):
                 uprint(_("Please copy the lacking macros (%(macros)s) in one of the following paths: 
%(path)s") % \
                        {'macros': ', '.join(not_in_path), 'path': ', '.join(path)})
 
-        except CommandError, exc:
+        except CommandError as exc:
             uprint(str(exc))
 
 register_command(cmd_sanitycheck)
diff --git a/jhbuild/commands/snapshot.py b/jhbuild/commands/snapshot.py
index 050977f..4183d49 100644
--- a/jhbuild/commands/snapshot.py
+++ b/jhbuild/commands/snapshot.py
@@ -21,7 +21,7 @@
 
 
 
-import urllib2
+import urllib.request, urllib.error, urllib.parse
 from optparse import make_option
 
 import jhbuild.moduleset
@@ -55,7 +55,7 @@ class cmd_snapshot(Command):
              + [m.to_sxml() for m in checked_out_mods]
              + [m.to_sxml() for m in meta])
 
-        print '<?xml version="1.0"?>\n'
-        print sxml_to_string(x)
+        print('<?xml version="1.0"?>\n')
+        print(sxml_to_string(x))
 
 register_command(cmd_snapshot)
diff --git a/jhbuild/commands/sysdeps.py b/jhbuild/commands/sysdeps.py
index 779969c..cb5fac4 100644
--- a/jhbuild/commands/sysdeps.py
+++ b/jhbuild/commands/sysdeps.py
@@ -76,7 +76,7 @@ class cmd_sysdeps(cmd_build):
                 if (isinstance(module, SystemModule) or isinstance(module.branch, TarballBranch) and
                                                         module.pkg_config is not None):
                     if module.pkg_config is not None:
-                        print 'pkgconfig:{0}'.format(module.pkg_config[:-3]) # remove .pc
+                        print('pkgconfig:{0}'.format(module.pkg_config[:-3])) # remove .pc
 
                     if module.systemdependencies is not None:
                         for dep_type, value, altdeps in module.systemdependencies:
@@ -93,7 +93,7 @@ class cmd_sysdeps(cmd_build):
         have_too_old = False
 
         if options.dump:
-            for module, (req_version, installed_version, new_enough, systemmodule) in 
module_state.iteritems():
+            for module, (req_version, installed_version, new_enough, systemmodule) in module_state.items():
                 if new_enough:
                     continue
 
@@ -112,7 +112,7 @@ class cmd_sysdeps(cmd_build):
                     assert (module.pkg_config or module.systemdependencies)
 
                     if module.pkg_config is not None:
-                        print 'pkgconfig:{0}'.format(module.pkg_config[:-3]) # remove .pc
+                        print('pkgconfig:{0}'.format(module.pkg_config[:-3])) # remove .pc
 
                     if module.systemdependencies is not None:
                         for dep_type, value, altdeps in module.systemdependencies:
@@ -126,72 +126,72 @@ class cmd_sysdeps(cmd_build):
 
             return
 
-        print _('System installed packages which are new enough:')
-        for module,(req_version, installed_version, new_enough, systemmodule) in module_state.iteritems():
+        print(_('System installed packages which are new enough:'))
+        for module,(req_version, installed_version, new_enough, systemmodule) in module_state.items():
             if (installed_version is not None) and new_enough and (config.partial_build or systemmodule):
                 have_new_enough = True
-                print ('    %s %s' % (module.name,
+                print(('    %s %s' % (module.name,
                                       fmt_details(module.pkg_config,
                                                   req_version,
-                                                  installed_version)))
+                                                  installed_version))))
         if not have_new_enough:
-            print _('  (none)')
+            print(_('  (none)'))
 
-        print _('Required packages:')
-        print _('  System installed packages which are too old:')
-        for module, (req_version, installed_version, new_enough, systemmodule) in module_state.iteritems():
+        print(_('Required packages:'))
+        print(_('  System installed packages which are too old:'))
+        for module, (req_version, installed_version, new_enough, systemmodule) in module_state.items():
             if (installed_version is not None) and (not new_enough) and systemmodule:
                 have_too_old = True
-                print ('    %s %s' % (module.name,
+                print(('    %s %s' % (module.name,
                                       fmt_details(module.pkg_config,
                                                   req_version,
-                                                  installed_version)))
+                                                  installed_version))))
         if not have_too_old:
-            print _('    (none)')
+            print(_('    (none)'))
 
-        print _('  No matching system package installed:')
+        print(_('  No matching system package installed:'))
         uninstalled = []
-        for module, (req_version, installed_version, new_enough, systemmodule) in module_state.iteritems():
+        for module, (req_version, installed_version, new_enough, systemmodule) in module_state.items():
             if installed_version is None and (not new_enough) and systemmodule:
-                print ('    %s %s' % (module.name,
+                print(('    %s %s' % (module.name,
                                       fmt_details(module.pkg_config,
                                                   req_version,
-                                                  installed_version)))
+                                                  installed_version))))
                 if module.pkg_config is not None:
                     uninstalled.append((module.name, 'pkgconfig', module.pkg_config[:-3])) # remove .pc
                 elif module.systemdependencies is not None:
                     for dep_type, value, altdeps in module.systemdependencies:
                         uninstalled.append((module.name, dep_type, value))
         if len(uninstalled) == 0:
-            print _('    (none)')
+            print(_('    (none)'))
 
         have_too_old = False
 
         if config.partial_build:
-            print _('Optional packages: (JHBuild will build the missing packages)')
-            print _('  System installed packages which are too old:')
-            for module, (req_version, installed_version, new_enough, systemmodule) in 
module_state.iteritems():
+            print(_('Optional packages: (JHBuild will build the missing packages)'))
+            print(_('  System installed packages which are too old:'))
+            for module, (req_version, installed_version, new_enough, systemmodule) in module_state.items():
                 if (installed_version is not None) and (not new_enough) and (not systemmodule):
                     have_too_old = True
-                    print ('    %s %s' % (module.name,
+                    print(('    %s %s' % (module.name,
                                           fmt_details(module.pkg_config,
                                                       req_version,
-                                                      installed_version)))
+                                                      installed_version))))
             if not have_too_old:
-                print _('    (none)')
+                print(_('    (none)'))
 
-            print _('  No matching system package installed:')
-            for module,(req_version, installed_version, new_enough, systemmodule) in 
module_state.iteritems():
+            print(_('  No matching system package installed:'))
+            for module,(req_version, installed_version, new_enough, systemmodule) in module_state.items():
                 if installed_version is None and (not new_enough) and (not systemmodule):
-                    print ('    %s %s' % (module.name,
+                    print(('    %s %s' % (module.name,
                                           fmt_details(module.pkg_config,
                                                       req_version,
-                                                      installed_version)))
+                                                      installed_version))))
                     if module.pkg_config is not None:
                         uninstalled.append((module.name, 'pkgconfig', module.pkg_config[:-3])) # remove .pc
 
             if len(uninstalled) == 0:
-                print _('    (none)')
+                print(_('    (none)'))
 
         if options.install:
             installer = SystemInstall.find_best()
diff --git a/jhbuild/commands/twoninetynine.py b/jhbuild/commands/twoninetynine.py
index 4ed1e0e..b65dbd9 100644
--- a/jhbuild/commands/twoninetynine.py
+++ b/jhbuild/commands/twoninetynine.py
@@ -23,7 +23,7 @@ import re
 
 from jhbuild.commands import Command, register_command
 
-from goalreport import cmd_goalreport, ExcludedModuleException, \
+from .goalreport import cmd_goalreport, ExcludedModuleException, \
          Check, ShellCheck, DeprecatedSymbolsCheck, FIND_C
 
 class LibBonobo(ShellCheck):
diff --git a/jhbuild/config.py b/jhbuild/config.py
index cf5d3d4..94be100 100644
--- a/jhbuild/config.py
+++ b/jhbuild/config.py
@@ -27,7 +27,7 @@ import traceback
 import time
 import types
 import logging
-import __builtin__
+import builtins
 
 from jhbuild.environment import setup_env, setup_env_defaults, addpath
 from jhbuild.errors import FatalError
@@ -109,7 +109,7 @@ class Config:
 
         env_prepends.clear()
         try:
-            execfile(_defaults_file, self._config)
+            exec(compile(open(_defaults_file).read(), _defaults_file, 'exec'), self._config)
         except:
             traceback.print_exc()
             raise FatalError(_('could not load config defaults'))
@@ -185,7 +185,7 @@ class Config:
     def include(self, filename):
         '''Read configuration variables from a file.'''
         try:
-            execfile(filename, self._config)
+            exec(compile(open(filename).read(), filename, 'exec'), self._config)
         except:
             traceback.print_exc()
             raise FatalError(_('Could not include config file (%s)') % filename)
@@ -194,8 +194,8 @@ class Config:
         config = self._config
         if filename:
             try:
-                execfile(filename, config)
-            except Exception, e:
+                exec(compile(open(filename).read(), filename, 'exec'), config)
+            except Exception as e:
                 if isinstance(e, FatalError):
                     # raise FatalErrors back, as it means an error in include()
                     # and it will print a traceback, and provide a meaningful
@@ -206,7 +206,7 @@ class Config:
 
         if not config.get('quiet_mode'):
             unknown_keys = []
-            for k in config.keys():
+            for k in list(config.keys()):
                 if k in _known_keys + ['cvsroots', 'svnroots', 'cflags']:
                     continue
                 if k[0] == '_':
@@ -238,7 +238,7 @@ class Config:
             config['repos'].update(config['svnroots'])
 
         # environment variables
-        if config.has_key('cflags') and config['cflags']:
+        if 'cflags' in config and config['cflags']:
             os.environ['CFLAGS'] = config['cflags']
         if config.get('installprog') and os.path.exists(config['installprog']):
             os.environ['INSTALL'] = config['installprog']
@@ -268,7 +268,7 @@ class Config:
         possible_checkout_modes = ('update', 'clobber', 'export', 'copy')
         if self.checkout_mode not in possible_checkout_modes:
             raise FatalError(_('invalid checkout mode'))
-        for module, checkout_mode in self.module_checkout_mode.items():
+        for module, checkout_mode in list(self.module_checkout_mode.items()):
             seen_copy_mode = seen_copy_mode or (checkout_mode == 'copy')
             if checkout_mode not in possible_checkout_modes:
                 raise FatalError(_('invalid checkout mode (module: %s)') % module)
@@ -321,7 +321,7 @@ class Config:
 
     def apply_env_prepends(self):
         ''' handle environment prepends ... '''
-        for envvar in env_prepends.keys():
+        for envvar in list(env_prepends.keys()):
             for path in env_prepends[envvar]:
                 addpath(envvar, path)
 
diff --git a/jhbuild/defaults.jhbuildrc b/jhbuild/defaults.jhbuildrc
index 3f54b68..199891a 100644
--- a/jhbuild/defaults.jhbuildrc
+++ b/jhbuild/defaults.jhbuildrc
@@ -68,7 +68,7 @@ builddir_pattern = '%s'
 try:
     import multiprocessing
     jobs = multiprocessing.cpu_count() + 1
-except ImportError, _e:
+except ImportError as _e:
     try:
         jobs = os.sysconf('SC_NPROCESSORS_ONLN') + 1
     except (OSError, AttributeError, ValueError):
diff --git a/jhbuild/environment.py b/jhbuild/environment.py
index 02ab939..39764b1 100644
--- a/jhbuild/environment.py
+++ b/jhbuild/environment.py
@@ -109,7 +109,7 @@ def setup_env_defaults(system_libdirs):
         os.environ['ACLOCAL_PATH']='/usr/share/aclocal'
 
     # get rid of gdkxft from the env -- it will cause problems.
-    if os.environ.has_key('LD_PRELOAD'):
+    if 'LD_PRELOAD' in os.environ:
         valarr = os.environ['LD_PRELOAD'].split(' ')
         for x in valarr[:]:
             if x.find('libgdkxft.so') >= 0:
@@ -163,7 +163,7 @@ def setup_env(prefix):
         # Running 'man -p' without specifying a manual page name causes it to
         # exit with status 1.
         systemmanpath = get_output('man -p || true', extra_env={'MANPATH': ''})
-        systemmanpath = map(os.path.dirname, systemmanpath.strip().split('\n'))
+        systemmanpath = list(map(os.path.dirname, systemmanpath.strip().split('\n')))
     elif sys.platform.startswith('openbsd'):
         # I cannot find a command that prints the default search path on
         # OpenBSD, so I add paths found in the default /etc/man.conf here.
diff --git a/jhbuild/frontends/autobuild.py b/jhbuild/frontends/autobuild.py
index 6ba1397..37daa42 100644
--- a/jhbuild/frontends/autobuild.py
+++ b/jhbuild/frontends/autobuild.py
@@ -26,14 +26,14 @@ import socket
 
 from jhbuild.utils import cmds
 from jhbuild.errors import CommandError
-import buildscript
+from . import buildscript
 
-import xmlrpclib
+import xmlrpc.client
 import zlib
-from cStringIO import StringIO
+from io import StringIO
 
-from tinderbox import get_distro
-from terminal import TerminalBuildScript, trayicon, t_bold, t_reset
+from .tinderbox import get_distro
+from .terminal import TerminalBuildScript, trayicon, t_bold, t_reset
 import jhbuild.moduleset
 
 def escape(string):
@@ -44,7 +44,7 @@ def fix_encoding(string):
     s = 'VERY BORKEN ENCODING'
     for encoding in [charset, 'utf-8', 'iso-8859-15']:
         try:
-            s = unicode(string, encoding)
+            s = str(string, encoding)
         except:
             continue
         break
@@ -52,28 +52,28 @@ def fix_encoding(string):
 
 def compress_data(data):
     c_data = zlib.compress(data)
-    return xmlrpclib.Binary(c_data)
+    return xmlrpc.client.Binary(c_data)
 
-class ServerProxy(xmlrpclib.ServerProxy):
+class ServerProxy(xmlrpc.client.ServerProxy):
     verbose_timeout = False
 
     def __request(self, methodname, params):
         ITERS = 10
         for i in range(ITERS):
             try:
-                return xmlrpclib.ServerProxy.__request(self, methodname, params)
-            except xmlrpclib.ProtocolError, e:
+                return xmlrpc.client.ServerProxy.__request(self, methodname, params)
+            except xmlrpc.client.ProtocolError as e:
                 if e.errcode != 500:
                     raise
-            except socket.error, e:
+            except socket.error as e:
                 pass
             if i < ITERS-1:
                 if self.verbose_timeout:
-                    print >> sys.stderr, _('Server Error, retrying in %d seconds') % ((i+1)**2)
+                    print(_('Server Error, retrying in %d seconds') % ((i+1)**2), file=sys.stderr)
                 time.sleep((i+1)**2)
             else:
                 if self.verbose_timeout:
-                    print >> sys.stderr, _('Server Error, aborting')
+                    print(_('Server Error, aborting'), file=sys.stderr)
                 raise e
             
 
@@ -93,7 +93,7 @@ class AutobuildBuildScript(buildscript.BuildScript, TerminalBuildScript):
         # cleanup environment
         os.environ['TERM'] = 'dumb'
         os.environ['LANG'] = 'C'
-        for k in os.environ.keys():
+        for k in list(os.environ.keys()):
             if k.startswith('LC_'):
                 os.environ[k] = 'C'
 
@@ -127,7 +127,7 @@ class AutobuildBuildScript(buildscript.BuildScript, TerminalBuildScript):
         kws = {
             'close_fds': True
             }
-        if isinstance(command, (str, unicode)):
+        if isinstance(command, str):
             displayed_command = command
             kws['shell'] = True
         else:
@@ -135,7 +135,7 @@ class AutobuildBuildScript(buildscript.BuildScript, TerminalBuildScript):
 
         self.phasefp.write('<span class="command">%s</span>\n' % escape(displayed_command))
         if self.verbose:
-            print ' $', displayed_command
+            print(' $', displayed_command)
 
         kws['stdin'] = subprocess.PIPE
         kws['stdout'] = subprocess.PIPE
@@ -144,7 +144,7 @@ class AutobuildBuildScript(buildscript.BuildScript, TerminalBuildScript):
             def format_line(line, error_output, fp=self.phasefp):
                 if line[-1] == '\n': line = line[:-1]
                 if self.verbose:
-                    print line
+                    print(line)
                 if line.startswith('C '):
                     fp.write('<span class="conflict">%s</span>\n'
                                         % escape(line))
@@ -156,9 +156,9 @@ class AutobuildBuildScript(buildscript.BuildScript, TerminalBuildScript):
                 if line[-1] == '\n': line = line[:-1]
                 if self.verbose:
                     if error_output:
-                        print >> sys.stderr, line
+                        print(line, file=sys.stderr)
                     else:
-                        print line
+                        print(line)
                 if error_output:
                     fp.write('<span class="error">%s</span>\n'
                                         % escape(line))
@@ -176,7 +176,7 @@ class AutobuildBuildScript(buildscript.BuildScript, TerminalBuildScript):
 
         try:
             p = subprocess.Popen(command, **kws)
-        except OSError, e:
+        except OSError as e:
             self.phasefp.write('<span class="error">' + _('Error: %s') % escape(str(e)) + '</span>\n')
             raise CommandError(str(e))
 
@@ -207,18 +207,18 @@ class AutobuildBuildScript(buildscript.BuildScript, TerminalBuildScript):
 
         try:
             self.build_id = self.server.start_build(info)
-        except xmlrpclib.ProtocolError, e:
+        except xmlrpc.client.ProtocolError as e:
             if e.errcode == 403:
-                print >> sys.stderr, _('ERROR: Wrong credentials, please check username/password')
+                print(_('ERROR: Wrong credentials, please check username/password'), file=sys.stderr)
                 sys.exit(1)
             raise
 
         
         if self.verbose:
             s = _('Starting Build #%s') % self.build_id
-            print s
-            print '=' * len(s)
-            print ''
+            print(s)
+            print('=' * len(s))
+            print('')
 
 
     def end_build(self, failures):
@@ -229,7 +229,7 @@ class AutobuildBuildScript(buildscript.BuildScript, TerminalBuildScript):
 
     def start_module(self, module):
         if self.verbose:
-            print '\n%s' % t_bold + _('**** Starting module %s ****' % module) + t_reset
+            print('\n%s' % t_bold + _('**** Starting module %s ****' % module) + t_reset)
         self.server.start_module(self.build_id, module)
         self.current_module = module
         self.modulefp = StringIO()
@@ -255,17 +255,17 @@ class AutobuildBuildScript(buildscript.BuildScript, TerminalBuildScript):
             if self.modules == {}:
                 self.modules = jhbuild.moduleset.load_tests(self.config)
 
-            if module in self.modules.modules.keys() \
+            if module in list(self.modules.modules.keys()) \
                    and self.modules.modules[module].test_type == 'ldtp':
                 self._upload_logfile(module)
 
         if isinstance(error, Exception):
-            error = unicode(error)
+            error = str(error)
         self.server.end_phase(self.build_id, module, phase, compress_data(log), error)
 
     def handle_error(self, module, phase, nextphase, error, altphases):
         '''handle error during build'''
-        print 'FIXME: handle error! (failed build: %s: %s)' % (module, error)
+        print('FIXME: handle error! (failed build: %s: %s)' % (module, error))
         return 'fail'
 
     def _upload_ldtp_logfile (self, module):
diff --git a/jhbuild/frontends/buildscript.py b/jhbuild/frontends/buildscript.py
index afc4603..f32ad88 100644
--- a/jhbuild/frontends/buildscript.py
+++ b/jhbuild/frontends/buildscript.py
@@ -81,7 +81,7 @@ class BuildScript:
 
     def _prepare_execute(self, command):
         if self.subprocess_nice_args:
-            if isinstance(command, (str, unicode)):
+            if isinstance(command, str):
                 command = ' '.join(self.subprocess_nice_args) + ' ' + command
             else:
                 command = self.subprocess_nice_args + command
@@ -161,7 +161,7 @@ class BuildScript:
                 try:
                     try:
                         error, altphases = module.run_phase(self, phase)
-                    except SkipToPhase, e:
+                    except SkipToPhase as e:
                         try:
                             num_phase = build_phases.index(e.phase)
                         except ValueError:
@@ -261,8 +261,8 @@ class BuildScript:
             logging.info(_('Running post-installation trigger script: %r') % (trig.name, ))
             try:
                 self.execute(trig.command())
-            except CommandError, err:
-                if isinstance(trig.command(), (str, unicode)):
+            except CommandError as err:
+                if isinstance(trig.command(), str):
                     displayed_command = trig.command()
                 else:
                     displayed_command = ' '.join(trig.command())
diff --git a/jhbuild/frontends/gtkui.py b/jhbuild/frontends/gtkui.py
index 62e2878..40b9652 100644
--- a/jhbuild/frontends/gtkui.py
+++ b/jhbuild/frontends/gtkui.py
@@ -37,13 +37,13 @@ try:
 except ImportError:
     vte = None
 
-import buildscript
+from . import buildscript
 import jhbuild.moduleset
 from jhbuild.modtypes import MetaModule
 from jhbuild.errors import CommandError
 from jhbuild.utils import notify
 
-from terminal import t_bold, t_reset
+from .terminal import t_bold, t_reset
 
 
 class ExitRequestedException(Exception):
@@ -446,7 +446,7 @@ class AppWindow(gtk.Window, buildscript.BuildScript):
         if not command:
             raise CommandError(_('No command given'))
 
-        if isinstance(command, (str, unicode)):
+        if isinstance(command, str):
             short_command = command.split()[0]
         else:
             short_command = command[0]
@@ -454,7 +454,7 @@ class AppWindow(gtk.Window, buildscript.BuildScript):
         if vte is None:
             textbuffer = self.terminal.get_buffer()
 
-            if isinstance(command, (str, unicode)):
+            if isinstance(command, str):
                 self.terminal.get_buffer().insert_with_tags_by_name(
                         textbuffer.get_end_iter(),
                         ' $ ' + command + '\n', 'stdin')
@@ -465,7 +465,7 @@ class AppWindow(gtk.Window, buildscript.BuildScript):
 
             kws = {
                 'close_fds': True,
-                'shell': isinstance(command, (str,unicode)),
+                'shell': isinstance(command, str),
                 'stdin': subprocess.PIPE,
                 'stdout': subprocess.PIPE,
                 'stderr': subprocess.PIPE,
@@ -482,7 +482,7 @@ class AppWindow(gtk.Window, buildscript.BuildScript):
 
             try:
                 p = subprocess.Popen(command, **kws)
-            except OSError, e:
+            except OSError as e:
                 raise CommandError(str(e))
             self.child_pid = p.pid
 
@@ -555,7 +555,7 @@ class AppWindow(gtk.Window, buildscript.BuildScript):
             self.child_pid = None
         else:
             # use the vte widget
-            if isinstance(command, (str, unicode)):
+            if isinstance(command, str):
                 self.terminal.feed(' $ ' + command + '\n\r')
                 command = [os.environ.get('SHELL', '/bin/sh'), '-c', command]
             else:
@@ -565,7 +565,7 @@ class AppWindow(gtk.Window, buildscript.BuildScript):
             if extra_env is not None:
                 env = os.environ.copy()
                 env.update(extra_env)
-                kws['envv'] = ['%s=%s' % x for x in env.items()]
+                kws['envv'] = ['%s=%s' % x for x in list(env.items())]
 
             if cwd:
                 kws['directory'] = cwd
diff --git a/jhbuild/frontends/terminal.py b/jhbuild/frontends/terminal.py
index 0b77cba..97061f7 100644
--- a/jhbuild/frontends/terminal.py
+++ b/jhbuild/frontends/terminal.py
@@ -156,7 +156,7 @@ class TerminalBuildScript(buildscript.BuildScript):
             except OSError:
                 pass
 
-        if isinstance(command, (str, unicode)):
+        if isinstance(command, str):
             kws['shell'] = True
             print_args['command'] = command
         else:
@@ -173,10 +173,10 @@ class TerminalBuildScript(buildscript.BuildScript):
         if not self.config.quiet_mode:
             if self.config.print_command_pattern:
                 try:
-                    print self.config.print_command_pattern % print_args
-                except TypeError, e:
+                    print(self.config.print_command_pattern % print_args)
+                except TypeError as e:
                     raise FatalError('\'print_command_pattern\' %s' % e)
-                except KeyError, e:
+                except KeyError as e:
                     raise FatalError(_('%(configuration_variable)s invalid key'
                                        ' %(key)s' % \
                                        {'configuration_variable' :
@@ -206,7 +206,7 @@ class TerminalBuildScript(buildscript.BuildScript):
 
         try:
             p = subprocess.Popen(command, **kws)
-        except OSError, e:
+        except OSError as e:
             raise CommandError(str(e))
 
         output = []
@@ -223,13 +223,13 @@ class TerminalBuildScript(buildscript.BuildScript):
                 if line[-1] == '\n': line = line[:-1]
 
                 if line.startswith('C '):
-                    print '%s%s%s' % (t_colour[12], line, t_reset)
+                    print('%s%s%s' % (t_colour[12], line, t_reset))
                 elif line.startswith('M '):
-                    print '%s%s%s' % (t_colour[10], line, t_reset)
+                    print('%s%s%s' % (t_colour[10], line, t_reset))
                 elif line.startswith('? '):
-                    print '%s%s%s' % (t_colour[8], line, t_reset)
+                    print('%s%s%s' % (t_colour[8], line, t_reset))
                 else:
-                    print line
+                    print(line)
 
             cmds.pprint_output(p, format_line)
             if conflicts:
@@ -255,7 +255,7 @@ class TerminalBuildScript(buildscript.BuildScript):
         try:
             if p.wait() != 0:
                 if self.config.quiet_mode:
-                    print ''.join(output)
+                    print(''.join(output))
                 raise CommandError(_('########## Error running %s')
                                    % print_args['command'], p.returncode)
         except OSError:
@@ -278,8 +278,8 @@ class TerminalBuildScript(buildscript.BuildScript):
         else:
             self.message(_('the following modules were not built'))
             for module in failures:
-                print module,
-            print
+                print(module, end=' ')
+            print()
 
     def handle_error(self, module, phase, nextphase, error, altphases):
         '''handle error during build'''
@@ -309,7 +309,7 @@ class TerminalBuildScript(buildscript.BuildScript):
         if not self.config.interact:
             return 'fail'
         while True:
-            print
+            print()
             uprint('  [1] %s' % _('Rerun phase %s') % phase)
             if nextphase:
                 uprint('  [2] %s' % _('Ignore error and continue to %s') % nextphase)
@@ -326,7 +326,7 @@ class TerminalBuildScript(buildscript.BuildScript):
                     altphase_label = altphase
                 uprint('  [%d] %s' % (i, _('Go to phase "%s"') % altphase_label))
                 i += 1
-            val = raw_input(uencode(_('choice: ')))
+            val = input(uencode(_('choice: ')))
             val = udecode(val)
             val = val.strip()
             if val == '1':
@@ -359,7 +359,7 @@ class TerminalBuildScript(buildscript.BuildScript):
                 except AttributeError:
                     needs_confirmation = False
                 if needs_confirmation:
-                    val = raw_input(uencode(_('Type "yes" to confirm the action: ')))
+                    val = input(uencode(_('Type "yes" to confirm the action: ')))
                     val = udecode(val)
                     val = val.strip()
                     if val.lower() in ('yes', _('yes').lower()):
diff --git a/jhbuild/frontends/tinderbox.py b/jhbuild/frontends/tinderbox.py
index 6e5ae6f..dfb82ec 100644
--- a/jhbuild/frontends/tinderbox.py
+++ b/jhbuild/frontends/tinderbox.py
@@ -29,8 +29,8 @@ from jhbuild.main import _encoding
 from jhbuild.utils import cmds
 from jhbuild.utils import sysid
 from jhbuild.errors import CommandError, FatalError
-import buildscript
-import commands
+from . import buildscript
+import subprocess
 
 index_header = '''<html>
   <head>
@@ -135,8 +135,8 @@ buildlog_footer = '''
 '''
 
 def escape(string):
-    if type(string) is not unicode:
-        string = unicode(string, _encoding, 'replace')
+    if type(string) is not str:
+        string = str(string, _encoding, 'replace')
     string = string.replace('&', '&amp;').replace('<','&lt;').replace(
             '>','&gt;').replace('\n','<br/>').replace(
             '\t','&nbsp;&nbsp;&nbsp;&nbsp;')
@@ -202,7 +202,7 @@ class TinderboxBuildScript(buildscript.BuildScript):
             print_args['cwd'] = os.getcwd()
 
         self.modulefp.write('<pre>')
-        if isinstance(command, (str, unicode)):
+        if isinstance(command, str):
             kws['shell'] = True
             print_args['command'] = command
         else:
@@ -213,9 +213,9 @@ class TinderboxBuildScript(buildscript.BuildScript):
                 commandstr = self.config.print_command_pattern % print_args
                 self.modulefp.write('<span class="command">%s</span>\n'
                                     % escape(commandstr))
-            except TypeError, e:
+            except TypeError as e:
                 raise FatalError('\'print_command_pattern\' %s' % e)
-            except KeyError, e:
+            except KeyError as e:
                 raise FatalError(_('%(configuration_variable)s invalid key'
                                    ' %(key)s' % \
                                    {'configuration_variable' :
@@ -254,7 +254,7 @@ class TinderboxBuildScript(buildscript.BuildScript):
 
         try:
             p = subprocess.Popen(command, **kws)
-        except OSError, e:
+        except OSError as e:
             self.modulefp.write('<span class="error">Error: %s</span>\n'
                                 % escape(str(e)))
             raise CommandError(str(e))
@@ -342,9 +342,9 @@ class TinderboxBuildScript(buildscript.BuildScript):
                 try:
                     help_url = self.config.help_website[1] % {'module' : module}
                     help_html = ' <a href="%s">(help)</a>' % help_url
-                except TypeError, e:
+                except TypeError as e:
                     raise FatalError('"help_website" %s' % e)
-                except KeyError, e:
+                except KeyError as e:
                     raise FatalError(_('%(configuration_variable)s invalid key'
                                        ' %(key)s' % \
                                        {'configuration_variable' :
@@ -397,9 +397,9 @@ class TinderboxBuildScript(buildscript.BuildScript):
                                     ' for more information.</div>'
                                     % {'name' : self.config.help_website[0],
                                        'url'  : help_url})
-            except TypeError, e:
+            except TypeError as e:
                 raise FatalError('"help_website" %s' % e)
-            except KeyError, e:
+            except KeyError as e:
                 raise FatalError(_('%(configuration_variable)s invalid key'
                                    ' %(key)s' % \
                                    {'configuration_variable' :
diff --git a/jhbuild/main.py b/jhbuild/main.py
index da222f5..853a9ee 100644
--- a/jhbuild/main.py
+++ b/jhbuild/main.py
@@ -23,8 +23,8 @@ import traceback
 import logging
 
 import gettext
-import __builtin__
-__builtin__.__dict__['N_'] = lambda x: x
+import builtins
+builtins.__dict__['N_'] = lambda x: x
 
 import jhbuild.config
 import jhbuild.commands
@@ -52,13 +52,13 @@ except (locale.Error, AssertionError):
     _encoding = 'ascii'
 
 def uencode(s):
-    if type(s) is unicode:
+    if type(s) is str:
         return s.encode(_encoding, 'replace')
     else:
         return s
 
 def udecode(s):
-    if type(s) is not unicode:
+    if type(s) is not str:
         return s.decode(_encoding, 'replace')
     else:
         return s
@@ -66,13 +66,13 @@ def udecode(s):
 def uprint(*args):
     '''Print Unicode string encoded for the terminal'''
     for s in args[:-1]:
-        print uencode(s),
+        print(uencode(s), end=' ')
     s = args[-1]
-    print uencode(s)
+    print(uencode(s))
 
-__builtin__.__dict__['uprint'] = uprint
-__builtin__.__dict__['uencode'] = uencode
-__builtin__.__dict__['udecode'] = udecode
+builtins.__dict__['uprint'] = uprint
+builtins.__dict__['uencode'] = uencode
+builtins.__dict__['udecode'] = udecode
 
 class LoggingFormatter(logging.Formatter):
     def __init__(self):
@@ -84,7 +84,7 @@ class LoggingFormatter(logging.Formatter):
 
 def print_help(parser):
     parser.print_help()
-    print
+    print()
     jhbuild.commands.print_help()
     parser.exit()
 
@@ -92,7 +92,7 @@ def main(args):
     localedir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'mo'))
     if not os.path.exists(localedir):
         localedir = None
-    gettext.install('jhbuild', localedir=localedir, unicode=True)
+    gettext.install('jhbuild', localedir=localedir)
 
     if hasattr(os, 'getuid') and os.getuid() == 0:
         sys.stderr.write(_('You should not run jhbuild as root.\n').encode(_encoding, 'replace'))
@@ -135,7 +135,7 @@ def main(args):
 
     try:
         config = jhbuild.config.Config(options.configfile, options.conditions)
-    except FatalError, exc:
+    except FatalError as exc:
         sys.stderr.write('jhbuild: %s\n' % exc.args[0].encode(_encoding, 'replace'))
         sys.exit(1)
 
@@ -153,11 +153,11 @@ def main(args):
 
     try:
         rc = jhbuild.commands.run(command, config, args, help=lambda: print_help(parser))
-    except UsageError, exc:
+    except UsageError as exc:
         sys.stderr.write('jhbuild %s: %s\n' % (command, exc.args[0].encode(_encoding, 'replace')))
         parser.print_usage()
         sys.exit(1)
-    except FatalError, exc:
+    except FatalError as exc:
         sys.stderr.write('jhbuild %s: %s\n' % (command, exc.args[0].encode(_encoding, 'replace')))
         sys.exit(1)
     except KeyboardInterrupt:
@@ -166,7 +166,7 @@ def main(args):
     except EOFError:
         uprint(_('EOF'))
         sys.exit(1)
-    except IOError, e:
+    except IOError as e:
         if e.errno != errno.EPIPE:
             raise
         sys.exit(0)
diff --git a/jhbuild/modtypes/__init__.py b/jhbuild/modtypes/__init__.py
index 41daa3d..c5be891 100644
--- a/jhbuild/modtypes/__init__.py
+++ b/jhbuild/modtypes/__init__.py
@@ -51,12 +51,12 @@ def register_lazy_module_type(name, module):
     _module_types[name] = parse_func
 
 def parse_xml_node(node, config, uri, repositories, default_repo):
-    if not _module_types.has_key(node.nodeName):
+    if node.nodeName not in _module_types:
         try:
             __import__('jhbuild.modtypes.%s' % node.nodeName)
         except ImportError:
             pass
-    if not _module_types.has_key(node.nodeName):
+    if node.nodeName not in _module_types:
         raise FatalError(_('unknown module type %s') % node.nodeName)
 
     parser = _module_types[node.nodeName]
@@ -146,7 +146,7 @@ def get_branch(node, repositories, default_repo, config):
         try:
             repo = repositories[childnode.getAttribute('repo')]
         except KeyError:
-            repo_names = ', '.join([r.name for r in repositories.values()])
+            repo_names = ', '.join([r.name for r in list(repositories.values())])
             raise UndefinedRepositoryError(
                 _('Repository=%(missing)s not found for module id=%(module)s. Possible repositories are 
%(possible)s'
                   % {'missing': childnode.getAttribute('repo'), 'module': name,
@@ -294,9 +294,9 @@ them into the prefix."""
                     try:
                         fileutils.rename(src_path, dest_path)
                         num_copied += 1
-                    except OSError, e:
+                    except OSError as e:
                         errors.append("%s: '%s'" % (str(e), dest_path))
-            except OSError, e:
+            except OSError as e:
                 errors.append(str(e))
         return num_copied
 
@@ -326,7 +326,7 @@ them into the prefix."""
             # $JHBUILD_PREFIX/_jhbuild/root-foo/$JHBUILD_PREFIX
             # Remove them one by one to clean the tree to the state we expect,
             # so we can better spot leftovers or broken things.
-            prefix_dirs = filter(lambda x: x != '', stripped_prefix.split(os.sep))
+            prefix_dirs = [x for x in stripped_prefix.split(os.sep) if x != '']
             while len(prefix_dirs) > 0:
                 dirname = prefix_dirs.pop()
                 subprefix = os.path.join(*([destdir] + prefix_dirs))
@@ -334,7 +334,7 @@ them into the prefix."""
                 assert target.startswith(buildscript.config.prefix)
                 try:
                     os.rmdir(target)
-                except OSError, e:
+                except OSError as e:
                     pass
 
             remaining_files = os.listdir(destdir)
@@ -418,7 +418,7 @@ them into the prefix."""
         method = getattr(self, 'do_' + phase)
         try:
             method(buildscript)
-        except (CommandError, BuildStateError), e:
+        except (CommandError, BuildStateError) as e:
             error_phases = []
             if hasattr(method, 'error_phases'):
                 error_phases = method.error_phases
diff --git a/jhbuild/modtypes/autotools.py b/jhbuild/modtypes/autotools.py
index 78a2ff3..743ec0b 100644
--- a/jhbuild/modtypes/autotools.py
+++ b/jhbuild/modtypes/autotools.py
@@ -91,7 +91,7 @@ class AutogenModule(MakeModule, DownloadableModule):
         try:
             other_stbuf = os.stat(other)
             potential_stbuf = os.stat(potential)
-        except OSError, e:
+        except OSError as e:
             return False
         return potential_stbuf.st_mtime > other_stbuf.st_mtime
 
@@ -218,14 +218,14 @@ class AutogenModule(MakeModule, DownloadableModule):
 
         srcdir = self.get_srcdir(buildscript)
         try:
-            if not (os.stat(os.path.join(srcdir, self.autogen_sh))[stat.ST_MODE] & 0111):
-                os.chmod(os.path.join(srcdir, self.autogen_sh), 0755)
+            if not (os.stat(os.path.join(srcdir, self.autogen_sh))[stat.ST_MODE] & 0o111):
+                os.chmod(os.path.join(srcdir, self.autogen_sh), 0o755)
         except:
             pass
 
         if self.autogen_sh == 'autoreconf':
             buildscript.execute(['autoreconf', '-fi'], cwd=srcdir)
-            os.chmod(os.path.join(srcdir, 'configure'), 0755)
+            os.chmod(os.path.join(srcdir, 'configure'), 0o755)
 
         buildscript.execute(cmd, cwd = builddir, extra_env = self.extra_env)
     do_configure.depends = [PHASE_CHECKOUT]
diff --git a/jhbuild/modtypes/linux.py b/jhbuild/modtypes/linux.py
index d5e79e1..0887179 100644
--- a/jhbuild/modtypes/linux.py
+++ b/jhbuild/modtypes/linux.py
@@ -114,7 +114,8 @@ class LinuxModule(MakeModule):
 
             try:
                 os.makedirs(os.path.join(self.branch.srcdir, 'build-' + kconfig.version))
-            except OSError, (e, msg):
+            except OSError as xxx_todo_changeme:
+                (e, msg) = xxx_todo_changeme.args
                 if e != errno.EEXIST:
                     raise
 
diff --git a/jhbuild/modtypes/tarball.py b/jhbuild/modtypes/tarball.py
index 8097a94..6b8610f 100644
--- a/jhbuild/modtypes/tarball.py
+++ b/jhbuild/modtypes/tarball.py
@@ -87,7 +87,7 @@ def parse_tarball(node, config, uri, repositories, default_repo):
 
     dependencies, after, suggests, systemdependencies = get_dependencies(node)
 
-    from autotools import AutogenModule
+    from .autotools import AutogenModule
     from jhbuild.versioncontrol.tarball import TarballBranch, TarballRepository
 
     # create a fake TarballRepository, and give it the moduleset uri
diff --git a/jhbuild/modtypes/testmodule.py b/jhbuild/modtypes/testmodule.py
index 1281766..18d94ed 100644
--- a/jhbuild/modtypes/testmodule.py
+++ b/jhbuild/modtypes/testmodule.py
@@ -49,9 +49,9 @@ class TestModule(Package, DownloadableModule):
         self.tested_pkgs  = tested_pkgs
 
         ### modify environ for tests to be working
-        if os.environ.has_key('LDTP_DEBUG'):
+        if 'LDTP_DEBUG' in os.environ:
             del os.environ['LDTP_DEBUG'] # get rid of verbose LDTP output
-        if not os.environ.has_key('GNOME_ACCESSIBILITY') or os.environ['GNOME_ACCESSIBILITY'] != 1:
+        if 'GNOME_ACCESSIBILITY' not in os.environ or os.environ['GNOME_ACCESSIBILITY'] != 1:
             os.environ['GNOME_ACCESSIBILITY'] = '1'
 
     def get_srcdir(self, buildscript):
@@ -188,7 +188,7 @@ class TestModule(Package, DownloadableModule):
         for group in groups:
             status += 'In Group #%s (%s)\n' % (group_num, group['groupstatus'])
             for script in group['script']:
-                for test in script['tests'].keys():
+                for test in list(script['tests'].keys()):
                     status += 'Test \'%s\' ' % test
                     if script['tests'][test]['pass'] == '0': # failed
                         status += 'failed\n\tErrors'
@@ -277,7 +277,7 @@ class TestModule(Package, DownloadableModule):
             else:
                 buildscript.execute('ldtprunner run.xml', cwd=src_dir,
                         extra_env={'DISPLAY': ':%s' % self.screennum})
-        except CommandError, e:
+        except CommandError as e:
             os.kill(ldtp_pid, signal.SIGINT)
             if e.returncode == 32512:        # ldtprunner not installed
                 raise BuildStateError('ldtprunner not available')
@@ -317,7 +317,7 @@ class TestModule(Package, DownloadableModule):
             try:
                 buildscript.execute('python %s' % test_case,
                         cwd=src_dir, extra_env=extra_env)
-            except CommandError, e:
+            except CommandError as e:
                 if e.returncode != 0:
                     raise BuildStateError('%s failed' % test_case)
 
diff --git a/jhbuild/moduleset.py b/jhbuild/moduleset.py
index d16c068..a02f3c8 100644
--- a/jhbuild/moduleset.py
+++ b/jhbuild/moduleset.py
@@ -17,11 +17,11 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-from __future__ import generators
+
 
 import os
 import sys
-import urlparse
+import urllib.parse
 import logging
 
 from jhbuild.errors import UsageError, FatalError, DependencyCycleError, \
@@ -86,10 +86,10 @@ class ModuleSet:
 
     def get_module(self, module_name, ignore_case = False):
         module_name = module_name.rstrip(os.sep)
-        if self.modules.has_key(module_name) or not ignore_case:
+        if module_name in self.modules or not ignore_case:
             return self.modules[module_name]
         module_name_lower = module_name.lower()
-        for module in self.modules.keys():
+        for module in list(self.modules.keys()):
             if module.lower() == module_name_lower:
                 logging.info(_('fixed case of module \'%(orig)s\' to '
                                '\'%(new)s\'') % {'orig': module_name,
@@ -171,12 +171,12 @@ class ModuleSet:
                             resolved[index] = (node, False)
 
         if module_names == 'all':
-            module_names = self.modules.keys()
+            module_names = list(self.modules.keys())
         try:
             # remove skip modules from module_name list
             modules = [self.get_module(module, ignore_case = True) \
                        for module in module_names if module not in skip]
-        except KeyError, e:
+        except KeyError as e:
             raise UsageError(_("A module called '%s' could not be found.") % e)
 
         resolved = []
@@ -199,7 +199,7 @@ class ModuleSet:
         test_modules = []
         if seed == []:
             return
-        for mod in self.modules.values():
+        for mod in list(self.modules.values()):
             for test_app in seed:
                 if test_app in mod.tested_pkgs:
                     test_modules.append(mod)
@@ -281,7 +281,7 @@ class ModuleSet:
         from jhbuild.versioncontrol.tarball import TarballBranch
         
         if modules is None:
-            modules = self.modules.keys()
+            modules = list(self.modules.keys())
         inlist = {}
         for module in modules:
             inlist[module] = None
@@ -318,21 +318,21 @@ class ModuleSet:
             
             for dep in self.modules[modname].dependencies:
                 fp.write('  "%s" -> "%s";\n' % (modname, dep))
-                if not inlist.has_key(dep):
+                if dep not in inlist:
                     modules.append(dep)
                 inlist[dep] = None
 
             if suggests:
                 for dep in self.modules[modname].after + self.modules[modname].suggests:
-                    if self.modules.has_key(dep):
+                    if dep in self.modules:
                         fp.write('  "%s" -> "%s" [style=dotted];\n' % (modname, dep))
-                        if not inlist.has_key(dep):
+                        if dep not in inlist:
                             modules.append(dep)
                         inlist[dep] = None
 
         if clusters:
             # create clusters for MetaModules
-            for modname in inlist.keys():
+            for modname in list(inlist.keys()):
                 mod = self.modules.get(modname)
                 if isinstance(mod, MetaModule):
                     fp.write('  subgraph "cluster_%s" {\n' % mod.name)
@@ -369,7 +369,7 @@ def load(config, uri=None):
                 uri = os.path.join(config.modulesets_dir, uri + '.modules')
             elif os.path.isfile(os.path.join(config.modulesets_dir, uri)):
                 uri = os.path.join(config.modulesets_dir, uri)
-        elif not urlparse.urlparse(uri)[0]:
+        elif not urllib.parse.urlparse(uri)[0]:
             uri = 'https://git.gnome.org/browse/jhbuild/plain/modulesets' \
                   '/%s.modules' % uri
         ms.modules.update(_parse_module_set(config, uri).modules)
@@ -378,7 +378,7 @@ def load(config, uri=None):
 def load_tests (config, uri=None):
     ms = load (config, uri)
     ms_tests = ModuleSet(config = config)
-    for app, module in ms.modules.iteritems():
+    for app, module in ms.modules.items():
         if module.__class__ == TestModule:
             ms_tests.modules[app] = module
     return ms_tests
@@ -438,14 +438,14 @@ def _handle_conditions(config, element):
 def _parse_module_set(config, uri):
     try:
         filename = httpcache.load(uri, nonetwork=config.nonetwork, age=0)
-    except Exception, e:
+    except Exception as e:
         raise FatalError(_('could not download %s: %s') % (uri, e))
     filename = os.path.normpath(filename)
     try:
         document = xml.dom.minidom.parse(filename)
-    except IOError, e:
+    except IOError as e:
         raise FatalError(_('failed to parse %s: %s') % (filename, e))
-    except xml.parsers.expat.ExpatError, e:
+    except xml.parsers.expat.ExpatError as e:
         raise FatalError(_('failed to parse %s: %s') % (uri, e))
 
     assert document.documentElement.nodeName == 'moduleset'
@@ -518,12 +518,12 @@ def _parse_module_set(config, uri):
     for node in _child_elements(document.documentElement):
         if node.nodeName == 'include':
             href = node.getAttribute('href')
-            inc_uri = urlparse.urljoin(uri, href)
+            inc_uri = urllib.parse.urljoin(uri, href)
             try:
                 inc_moduleset = _parse_module_set(config, inc_uri)
             except UndefinedRepositoryError:
                 raise
-            except FatalError, e:
+            except FatalError as e:
                 if inc_uri[0] == '/':
                     raise e
                 # look up in local modulesets
diff --git a/jhbuild/monkeypatch.py b/jhbuild/monkeypatch.py
index cee22aa..ede2e96 100644
--- a/jhbuild/monkeypatch.py
+++ b/jhbuild/monkeypatch.py
@@ -18,7 +18,7 @@
 # extras not found in old versions of Python
 
 import sys
-import __builtin__
+import builtins
 
 # Windows lacks all sorts of subprocess features that we need to kludge around
 if sys.platform.startswith('win'):
diff --git a/jhbuild/utils/cmds.py b/jhbuild/utils/cmds.py
index d0bbcac..cb49021 100644
--- a/jhbuild/utils/cmds.py
+++ b/jhbuild/utils/cmds.py
@@ -40,7 +40,7 @@ def get_output(cmd, cwd=None, extra_env=None, get_stderr = True):
         raise CommandError(_('Call to undefined command'))
 
     kws = {}
-    if isinstance(cmd, (str, unicode)):
+    if isinstance(cmd, str):
         kws['shell'] = True
     if cwd is not None:
         kws['cwd'] = cwd
@@ -59,7 +59,7 @@ def get_output(cmd, cwd=None, extra_env=None, get_stderr = True):
                              stdout=subprocess.PIPE,
                              stderr=stderr_output,
                              **kws)
-    except OSError, e:
+    except OSError as e:
         raise CommandError(str(e))
     stdout, stderr = p.communicate()
     if p.returncode != 0:
@@ -111,7 +111,7 @@ class Pipeline(subprocess.Popen):
                 c2cwrite = stdout
 
             self.children.append(
-                subprocess.Popen(cmd, shell=isinstance(cmd, (str, unicode)),
+                subprocess.Popen(cmd, shell=isinstance(cmd, str),
                                  bufsize=bufsize, close_fds=True,
                                  cwd=cwd, env=env,
                                  stdin=stdin,
@@ -158,7 +158,7 @@ def spawn_child(command, use_pipe=False,
         p = Pipeline(command, cwd=cwd, env=env,
                      stdin=stdin, stdout=stdout, stderr=stderr)
     else:
-        p = subprocess.Popen(command, shell=isinstance(command, (str,unicode)),
+        p = subprocess.Popen(command, shell=isinstance(command, str),
                              close_fds=True, cwd=cwd, env=env,
                              stdin=stdin, stdout=stdout, stderr=stderr)
     return p
diff --git a/jhbuild/utils/fileutils.py b/jhbuild/utils/fileutils.py
index e06fb4a..46d1716 100644
--- a/jhbuild/utils/fileutils.py
+++ b/jhbuild/utils/fileutils.py
@@ -69,7 +69,7 @@ Returns a list, where each item is a 2-tuple:
             else:
                 os.unlink(path)
             results.append((path, True, ''))
-        except OSError, e:
+        except OSError as e:
             if (isdir
                 and allow_nonempty_dirs
                 and len(os.listdir(path)) > 0):
@@ -98,7 +98,7 @@ def _windows_rename(src, dst):
     '''atomically rename file src to dst, replacing dst if it exists'''
     try:
         os.rename(src, dst)
-    except OSError, e:
+    except OSError as e:
         if e.errno != errno.EEXIST:
             raise
         # Windows does not allow to unlink open file.
diff --git a/jhbuild/utils/httpcache.py b/jhbuild/utils/httpcache.py
index c541d97..e0f8e42 100644
--- a/jhbuild/utils/httpcache.py
+++ b/jhbuild/utils/httpcache.py
@@ -30,11 +30,11 @@ and draws ideas from feedparser.py.  Strategies include:
 
 import os
 import sys
-import urllib2
-import urlparse
+import urllib.request, urllib.error, urllib.parse
+import urllib.parse
 import time
-import rfc822
-import StringIO
+import email.utils
+import io
 try:
     import gzip
 except ImportError:
@@ -43,7 +43,7 @@ except ImportError:
 try:
     import xml.dom.minidom
 except ImportError:
-    raise SystemExit, _('Python XML packages are required but could not be found')
+    raise SystemExit(_('Python XML packages are required but could not be found'))
 
 def _parse_isotime(string):
     if string[-1] != 'Z':
@@ -55,9 +55,9 @@ def _format_isotime(tm):
     return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(tm))
 
 def _parse_date(date):
-    tm = rfc822.parsedate_tz(date)
+    tm = email.utils.parsedate_tz(date)
     if tm:
-        return rfc822.mktime_tz(tm)
+        return email.utils.mktime_tz(tm)
     return 0
 
 class CacheEntry:
@@ -123,7 +123,7 @@ class Cache:
         document.appendChild(document.createElement('cache'))
         node = document.createTextNode('\n')
         document.documentElement.appendChild(node)
-        for uri in self.entries.keys():
+        for uri in list(self.entries.keys()):
             entry = self.entries[uri]
             node = document.createElement('entry')
             node.setAttribute('uri', entry.uri)
@@ -146,14 +146,14 @@ class Cache:
         '''picks a unique name for a new entry in the cache.
         Very simplistic.'''
         # get the basename from the URI
-        parts = urlparse.urlparse(uri, allow_fragments=False)
+        parts = urllib.parse.urlparse(uri, allow_fragments=False)
         base = parts[2].split('/')[-1]
         if not base: base = 'index.html'
 
         is_unique = False
         while not is_unique:
             is_unique = True
-            for uri in self.entries.keys():
+            for uri in list(self.entries.keys()):
                 if self.entries[uri].local == base:
                     is_unique = False
                     break
@@ -165,7 +165,7 @@ class Cache:
         '''Downloads the file associated with the URI, and returns a local
         file name for contents.'''
         # pass file URIs straight through -- no need to cache them
-        parts = urlparse.urlparse(uri)
+        parts = urllib.parse.urlparse(uri)
         if parts[0] in ('', 'file'):
             return parts[2]
         if sys.platform.startswith('win') and uri[1] == ':':
@@ -184,7 +184,7 @@ class Cache:
         if nonetwork:
             raise RuntimeError(_('file not in cache, but not allowed to check network'))
 
-        request = urllib2.Request(uri)
+        request = urllib.request.Request(uri)
         if gzip:
             request.add_header('Accept-encoding', 'gzip')
         if entry:
@@ -194,13 +194,13 @@ class Cache:
                 request.add_header('If-None-Match', entry.etag)
 
         try:
-            response = urllib2.urlopen(request)
+            response = urllib.request.urlopen(request)
 
             # get data, and gunzip it if it is encoded
             data = response.read()
             if gzip and response.headers.get('Content-Encoding', '') == 'gzip':
                 try:
-                    data = gzip.GzipFile(fileobj=StringIO.StringIO(data)).read()
+                    data = gzip.GzipFile(fileobj=io.StringIO(data)).read()
                 except:
                     data = ''
 
@@ -214,7 +214,7 @@ class Cache:
             fp = open(filename, 'wb')
             fp.write(data)
             fp.close()
-        except urllib2.HTTPError, e:
+        except urllib.error.HTTPError as e:
             if e.code == 304: # not modified; update validated
                 expires = e.hdrs.get('Expires')
                 filename = os.path.join(self.cachedir, entry.local)
diff --git a/jhbuild/utils/packagedb.py b/jhbuild/utils/packagedb.py
index 467e1a2..e25b7da 100644
--- a/jhbuild/utils/packagedb.py
+++ b/jhbuild/utils/packagedb.py
@@ -33,7 +33,7 @@ try:
 except ImportError:
     import elementtree.ElementTree as ET
 
-from StringIO import StringIO
+from io import StringIO
 
 from jhbuild.utils import fileutils
 
diff --git a/jhbuild/utils/sxml.py b/jhbuild/utils/sxml.py
index 98df4cc..85b9113 100644
--- a/jhbuild/utils/sxml.py
+++ b/jhbuild/utils/sxml.py
@@ -41,12 +41,12 @@ __all__ = ['sxml', 'sxml_to_string']
 # from Django, originally. used to make sure xml is utf-8.
 def smart_str(s, encoding='utf-8', errors='strict'):
     # Returns a bytestring version of 's', encoded as specified in 'encoding'.
-    if not isinstance(s, basestring):
+    if not isinstance(s, str):
         try:
             return str(s)
         except UnicodeEncodeError:
-            return unicode(s).encode(encoding, errors)
-    elif isinstance(s, unicode):
+            return str(s).encode(encoding, errors)
+    elif isinstance(s, str):
         return s.encode(encoding, errors)
     elif s and encoding != 'utf-8':
         return s.decode('utf-8', errors).encode(encoding, errors)
@@ -77,7 +77,7 @@ class sxml:
                 return ('<%s%s>%s</%s>'
                         % (attr,
                            ''.join([' %s="%s"' % (_trans(k), quote(v))
-                                    for k, v in kw.items()]),
+                                    for k, v in list(kw.items())]),
                            '\n'.join(args),
                            attr))
             render.__name__ = attr
diff --git a/jhbuild/utils/systeminstall.py b/jhbuild/utils/systeminstall.py
index ffd20d8..9a1f248 100644
--- a/jhbuild/utils/systeminstall.py
+++ b/jhbuild/utils/systeminstall.py
@@ -25,9 +25,9 @@ import subprocess
 import pipes
 import imp
 import time
-from StringIO import StringIO
+from io import StringIO
 
-import cmds
+from . import cmds
 
 def get_installed_pkgconfigs(config):
     """Returns a dictionary mapping pkg-config names to their current versions on the system."""
@@ -46,7 +46,7 @@ def get_installed_pkgconfigs(config):
             stdout = subprocess.check_output(['pkg-config', '--modversion'] + pkgs)
             versions = stdout.splitlines()
             if len(versions) == len(pkgs):
-                return dict(zip(pkgs, versions))
+                return dict(list(zip(pkgs, versions)))
         except OSError:
             pass
 
@@ -96,10 +96,10 @@ def systemdependencies_met(module_name, sysdeps, config):
                 shell_split = shlex.split
             try:
                 while True:
-                    arg = itr.next()
+                    arg = next(itr)
                     if arg.strip() in ['-I', '-isystem']:
                         # extract paths handling quotes and multiple paths
-                        paths += shell_split(itr.next())[0].split(os.pathsep)
+                        paths += shell_split(next(itr))[0].split(os.pathsep)
                     elif arg.startswith('-I'):
                         paths += shell_split(arg[2:])[0].split(os.pathsep)
             except StopIteration:
@@ -197,7 +197,7 @@ class SystemInstall(object):
         elif cmds.has_command('sudo'):
             self._root_command_prefix_args = ['sudo']
         else:
-            raise SystemExit, _('No suitable root privilege command found; you should install "pkexec"')
+            raise SystemExit(_('No suitable root privilege command found; you should install "pkexec"'))
 
     def install(self, uninstalled):
         """Takes a list of pkg-config identifiers and uses a system-specific method to install them."""
@@ -480,5 +480,5 @@ _classes = [AptSystemInstall, PacmanSystemInstall, PKSystemInstall, YumSystemIns
 if __name__ == '__main__':
     logging.basicConfig(level=logging.INFO)
     installer = SystemInstall.find_best()
-    print "Using %r" % (installer, )
+    print("Using %r" % (installer, ))
     installer.install(sys.argv[1:])
diff --git a/jhbuild/utils/trayicon.py b/jhbuild/utils/trayicon.py
index 6c74cab..16c6fba 100644
--- a/jhbuild/utils/trayicon.py
+++ b/jhbuild/utils/trayicon.py
@@ -95,7 +95,7 @@ class TrayIcon:
         try:
             self.proc.stdin.write(cmd)
             self.proc.stdin.flush()
-        except (IOError, OSError), err:
+        except (IOError, OSError) as err:
             self.close()
     def set_icon(self, icon):
         self._send_cmd('icon: %s\n' % icon)
diff --git a/jhbuild/utils/unpack.py b/jhbuild/utils/unpack.py
index fac743a..887eb8d 100644
--- a/jhbuild/utils/unpack.py
+++ b/jhbuild/utils/unpack.py
@@ -50,9 +50,9 @@ def unpack_zip_file(localfile, target_directory):
     def attr_to_file_perm(host, attr):
         if host == 0:
             if attr & 1:
-                perm = 0444
+                perm = 0o444
             else:
-                perm = 0666
+                perm = 0o666
         else:
             perm = attr
             perm &= 0x08FF0000
@@ -64,9 +64,9 @@ def unpack_zip_file(localfile, target_directory):
         if host == 0:
             # attr & 16 should be true (this is directory bit)
             if attr & 1:
-                perm = 0444
+                perm = 0o444
             else:
-                perm = 0666
+                perm = 0o666
         else:
             perm = attr
             perm &= 0xFFFF0000
diff --git a/jhbuild/versioncontrol/__init__.py b/jhbuild/versioncontrol/__init__.py
index b6e80fb..2d9b600 100644
--- a/jhbuild/versioncontrol/__init__.py
+++ b/jhbuild/versioncontrol/__init__.py
@@ -27,7 +27,9 @@ __all__ = [
 __metaclass__ = type
 
 from jhbuild.errors import FatalError, BuildStateError
+import importlib
 import os
+import warnings
 
 class Repository:
     """An abstract class representing a collection of modules."""
@@ -192,8 +194,10 @@ def register_repo_type(name, repo_class):
 def get_repo_type(name):
     if name not in _repo_types:
         try:
-            __import__('jhbuild.versioncontrol.%s' % name)
-        except ImportError:
+            importlib.import_module('jhbuild.versioncontrol.%s' % name)
+        except ImportError as e:
+            warnings.warn("Failed to import versioncontrol.%s: %s" %
+                          (name, e))
             pass
     if name not in _repo_types:
         raise FatalError(_('unknown repository type %s') % name)
diff --git a/jhbuild/versioncontrol/bzr.py b/jhbuild/versioncontrol/bzr.py
index a13916b..272a661 100644
--- a/jhbuild/versioncontrol/bzr.py
+++ b/jhbuild/versioncontrol/bzr.py
@@ -22,7 +22,7 @@ __metaclass__ = type
 
 import os
 import errno
-import urlparse
+import urllib.parse
 import logging
 
 from jhbuild.errors import FatalError, CommandError
@@ -33,20 +33,20 @@ from jhbuild.utils.sxml import sxml
 
 # Make sure that the urlparse module considers bzr://, bzr+ssh://, sftp:// and lp:
 # scheme to be netloc aware and set to allow relative URIs.
-if 'bzr' not in urlparse.uses_netloc:
-    urlparse.uses_netloc.append('bzr')
-if 'bzr' not in urlparse.uses_relative:
-    urlparse.uses_relative.append('bzr')
-if 'bzr+ssh' not in urlparse.uses_netloc:
-    urlparse.uses_netloc.append('bzr+ssh')
-if 'bzr+ssh' not in urlparse.uses_relative:
-    urlparse.uses_relative.append('bzr+ssh')
-if 'sftp' not in urlparse.uses_netloc:
-    urlparse.uses_netloc.append('sftp')
-if 'sftp' not in urlparse.uses_relative:
-    urlparse.uses_relative.append('sftp')
-if 'lp' not in urlparse.uses_relative:
-    urlparse.uses_relative.append('lp')
+if 'bzr' not in urllib.parse.uses_netloc:
+    urllib.parse.uses_netloc.append('bzr')
+if 'bzr' not in urllib.parse.uses_relative:
+    urllib.parse.uses_relative.append('bzr')
+if 'bzr+ssh' not in urllib.parse.uses_netloc:
+    urllib.parse.uses_netloc.append('bzr+ssh')
+if 'bzr+ssh' not in urllib.parse.uses_relative:
+    urllib.parse.uses_relative.append('bzr+ssh')
+if 'sftp' not in urllib.parse.uses_netloc:
+    urllib.parse.uses_netloc.append('sftp')
+if 'sftp' not in urllib.parse.uses_relative:
+    urllib.parse.uses_relative.append('sftp')
+if 'lp' not in urllib.parse.uses_relative:
+    urllib.parse.uses_relative.append('lp')
 
 
 class BzrRepository(Repository):
@@ -79,9 +79,9 @@ class BzrRepository(Repository):
             module = name
 
         if revision or branch:
-            template = urlparse.urljoin(self.href, self.branches_template)
+            template = urllib.parse.urljoin(self.href, self.branches_template)
         else:
-            template = urlparse.urljoin(self.href, self.trunk_template)
+            template = urllib.parse.urljoin(self.href, self.trunk_template)
 
         if not module_href:
             module_href = template % {
@@ -115,7 +115,8 @@ class BzrBranch(Branch):
     def get_revspec(self):
         return self._revspec
 
-    def set_revspec(self, (tag, revspec)):
+    def set_revspec(self, xxx_todo_changeme):
+        (tag, revspec) = xxx_todo_changeme
         if revspec:
             self._revspec = ['-r%s' % revspec]
         elif tag:
diff --git a/jhbuild/versioncontrol/cvs.py b/jhbuild/versioncontrol/cvs.py
index f8bab01..d7a605f 100644
--- a/jhbuild/versioncontrol/cvs.py
+++ b/jhbuild/versioncontrol/cvs.py
@@ -31,7 +31,7 @@ try:
 except ImportError:
     import md5 as hashlib
 
-import git
+from . import git
 
 from jhbuild.errors import BuildStateError, CommandError
 from jhbuild.versioncontrol import Repository, Branch, register_repo_type
diff --git a/jhbuild/versioncontrol/darcs.py b/jhbuild/versioncontrol/darcs.py
index 1e08456..fbf4367 100644
--- a/jhbuild/versioncontrol/darcs.py
+++ b/jhbuild/versioncontrol/darcs.py
@@ -21,7 +21,7 @@ __all__ = []
 __metaclass__ = type
 
 import os
-import urlparse
+import urllib.parse
 
 try:
     import hashlib
@@ -58,7 +58,7 @@ class DarcsRepository(Repository):
         else:
             if module is None:
                 module = name
-            module = urlparse.urljoin(self.href, module)
+            module = urllib.parse.urljoin(self.href, module)
         return DarcsBranch(self, module, checkoutdir)
 
 
@@ -101,9 +101,9 @@ class DarcsBranch(Branch):
             path = os.path.join(self.srcdir, filename)
             try:
                 stat = os.stat(path)
-            except OSError, e:
+            except OSError as e:
                 continue
-            os.chmod(path, stat.st_mode | 0111)
+            os.chmod(path, stat.st_mode | 0o111)
 
     def checkout(self, buildscript):
         if not inpath('darcs', os.environ['PATH'].split(os.pathsep)):
diff --git a/jhbuild/versioncontrol/fossil.py b/jhbuild/versioncontrol/fossil.py
index 172072c..50bc87a 100644
--- a/jhbuild/versioncontrol/fossil.py
+++ b/jhbuild/versioncontrol/fossil.py
@@ -23,7 +23,7 @@ __metaclass__ = type
 
 import os
 import sys
-import urlparse
+import urllib.parse
 from subprocess import Popen, PIPE
 
 from jhbuild.errors import FatalError, CommandError
@@ -52,7 +52,7 @@ class FossilRepository(Repository):
         else:
             if module is None:
                 module = name
-            module = urlparse.urljoin(self.href, module)
+            module = urllib.parse.urljoin(self.href, module)
         return FossilBranch(self, module, checkoutdir)
 
 
@@ -112,7 +112,7 @@ class FossilBranch(Branch):
 
         try:
             infos = Popen(['fossil', 'info'], stdout=PIPE, cwd=self.srcdir)
-        except OSError, e:
+        except OSError as e:
             raise CommandError(str(e))
         infos = infos.stdout.read().strip()
         return re.search(r"checkout: +(\w+)", infos).group(1)
diff --git a/jhbuild/versioncontrol/git.py b/jhbuild/versioncontrol/git.py
index 2f181ee..bf1b25f 100644
--- a/jhbuild/versioncontrol/git.py
+++ b/jhbuild/versioncontrol/git.py
@@ -23,10 +23,10 @@ __metaclass__ = type
 
 import os
 import stat
-import urlparse
+import urllib.parse
 import subprocess
 import re
-import urllib
+import urllib.request, urllib.parse, urllib.error
 import sys
 import logging
 
@@ -39,16 +39,16 @@ from jhbuild.utils.sxml import sxml
 
 # Make sure that the urlparse module considers git:// and git+ssh://
 # schemes to be netloc aware and set to allow relative URIs.
-if 'git' not in urlparse.uses_netloc:
-    urlparse.uses_netloc.append('git')
-if 'git' not in urlparse.uses_relative:
-    urlparse.uses_relative.append('git')
-if 'git+ssh' not in urlparse.uses_netloc:
-    urlparse.uses_netloc.append('git+ssh')
-if 'git+ssh' not in urlparse.uses_relative:
-    urlparse.uses_relative.append('git+ssh')
-if 'ssh' not in urlparse.uses_relative:
-    urlparse.uses_relative.append('ssh')
+if 'git' not in urllib.parse.uses_netloc:
+    urllib.parse.uses_netloc.append('git')
+if 'git' not in urllib.parse.uses_relative:
+    urllib.parse.uses_relative.append('git')
+if 'git+ssh' not in urllib.parse.uses_netloc:
+    urllib.parse.uses_netloc.append('git+ssh')
+if 'git+ssh' not in urllib.parse.uses_relative:
+    urllib.parse.uses_relative.append('git+ssh')
+if 'ssh' not in urllib.parse.uses_relative:
+    urllib.parse.uses_relative.append('ssh')
 
 def get_git_extra_env():
     # we run git without the JHBuild LD_LIBRARY_PATH and PATH, as it can
@@ -112,7 +112,7 @@ class GitRepository(Repository):
                 else:
                     if new_module:
                         module = new_module
-        if not (urlparse.urlparse(module)[0] or module[0] == '/'):
+        if not (urllib.parse.urlparse(module)[0] or module[0] == '/'):
             if self.href.endswith('/'):
                 base_href = self.href
             else:
@@ -540,7 +540,7 @@ class GitSvnBranch(GitBranch):
         # only parse the final match
         if match:
             branch = match.group(1)
-            external = urllib.unquote(match.group(2).replace("%0A", " ").strip("%20 ")).split()
+            external = urllib.parse.unquote(match.group(2).replace("%0A", " ").strip("%20 ")).split()
             revision_expr = re.compile(r"-r(\d*)")
             i = 0
             while i < len(external):
@@ -553,7 +553,7 @@ class GitSvnBranch(GitBranch):
                     externals[external[i]] = (external[i+1], None)
                     i = i+2
         
-        for extdir in externals.iterkeys():
+        for extdir in externals.keys():
             uri = externals[extdir][0]
             revision = externals[extdir][1]
             extdir = cwd+os.sep+extdir
diff --git a/jhbuild/versioncontrol/hg.py b/jhbuild/versioncontrol/hg.py
index 6cc661a..6442b3c 100644
--- a/jhbuild/versioncontrol/hg.py
+++ b/jhbuild/versioncontrol/hg.py
@@ -23,7 +23,7 @@ __metaclass__ = type
 
 import os
 import sys
-import urlparse
+import urllib.parse
 from subprocess import Popen, PIPE
 
 from jhbuild.errors import FatalError, CommandError
@@ -57,7 +57,7 @@ class HgRepository(Repository):
             if module is None:
                 module = name
             if not self.href.startswith('ssh://'):
-                module = urlparse.urljoin(self.href, module)
+                module = urllib.parse.urljoin(self.href, module)
             else:
                 module = self.href + module
         return HgBranch(self, module, checkoutdir)
@@ -111,7 +111,7 @@ class HgBranch(Branch):
         try:
             hg = Popen(['hg', 'ti', '--template', '{node}'], stdout=PIPE,
                        cwd=self.srcdir)
-        except OSError, e:
+        except OSError as e:
             raise CommandError(str(e))
         return hg.stdout.read().strip()
 
diff --git a/jhbuild/versioncontrol/svn.py b/jhbuild/versioncontrol/svn.py
index 0a67316..558f903 100644
--- a/jhbuild/versioncontrol/svn.py
+++ b/jhbuild/versioncontrol/svn.py
@@ -21,7 +21,7 @@ __all__ = []
 __metaclass__ = type
 
 import os
-import urlparse
+import urllib.parse
 import subprocess
 
 from jhbuild.errors import CommandError, BuildStateError
@@ -30,7 +30,7 @@ from jhbuild.versioncontrol import Repository, Branch, register_repo_type
 from jhbuild.commands.sanitycheck import inpath
 from jhbuild.utils.sxml import sxml
 
-import bzr, git
+from . import bzr, git
 
 svn_one_five = None # is this svn 1.5
 
@@ -42,14 +42,14 @@ def _make_uri(repo, path):
 
 # Make sure that the urlparse module considers svn:// and svn+ssh://
 # schemes to be netloc aware and set to allow relative URIs.
-if 'svn' not in urlparse.uses_netloc:
-    urlparse.uses_netloc.append('svn')
-if 'svn' not in urlparse.uses_relative:
-    urlparse.uses_relative.append('svn')
-if 'svn+ssh' not in urlparse.uses_netloc:
-    urlparse.uses_netloc.append('svn+ssh')
-if 'svn+ssh' not in urlparse.uses_relative:
-    urlparse.uses_relative.append('svn+ssh')
+if 'svn' not in urllib.parse.uses_netloc:
+    urllib.parse.uses_netloc.append('svn')
+if 'svn' not in urllib.parse.uses_relative:
+    urllib.parse.uses_relative.append('svn')
+if 'svn+ssh' not in urllib.parse.uses_netloc:
+    urllib.parse.uses_netloc.append('svn+ssh')
+if 'svn+ssh' not in urllib.parse.uses_relative:
+    urllib.parse.uses_relative.append('svn+ssh')
 
 def get_svn_extra_env():
     # we run Subversion in the C locale, because Subversion localises
@@ -71,7 +71,7 @@ def get_info(filename):
     return ret
 
 def get_subdirs(url):
-    print _("Getting SVN subdirs: this operation might be long...")
+    print(_("Getting SVN subdirs: this operation might be long..."))
     output = get_output(
         ['svn', 'ls', '-R', url], extra_env=get_svn_extra_env())
     ret = []
@@ -160,9 +160,9 @@ class SubversionRepository(Repository):
 
         # workaround for svn client not handling '..' in URL (#560246, #678869)
         if os.name != 'nt':
-            splitted_href = list(urlparse.urlsplit(module_href))
+            splitted_href = list(urllib.parse.urlsplit(module_href))
             splitted_href[2] = os.path.abspath(splitted_href[2])
-            module_href = urlparse.urlunsplit(splitted_href)
+            module_href = urllib.parse.urlunsplit(splitted_href)
 
         if self.svn_program == 'bzr' and not revision:
             return bzr.BzrBranch(self, module_href, checkoutdir)
@@ -271,11 +271,11 @@ class SubversionBranch(Branch):
 
         uri = get_uri(outputdir)
 
-        if urlparse.urlparse(uri)[:2] != urlparse.urlparse(self.module)[:2]:
+        if urllib.parse.urlparse(uri)[:2] != urllib.parse.urlparse(self.module)[:2]:
             # server and protocol changed, probably because user changed
             # svnroots[] config variable.
-            new_uri = urlparse.urlunparse(
-                    urlparse.urlparse(self.module)[:2] + urlparse.urlparse(uri)[2:])
+            new_uri = urllib.parse.urlunparse(
+                    urllib.parse.urlparse(self.module)[:2] + urllib.parse.urlparse(uri)[2:])
             cmd = ['svn', 'switch', '--relocate', uri, new_uri, '.']
             buildscript.execute(cmd, 'svn', cwd=outputdir,
                     extra_env=get_svn_extra_env())
@@ -306,7 +306,7 @@ class SubversionBranch(Branch):
         try:
             output = subprocess.Popen(['svn', 'info', '-R'],
                     stdout = subprocess.PIPE, **kws).communicate()[0]
-        except OSError, e:
+        except OSError as e:
             raise CommandError(str(e))
         if '\nConflict' in output:
             raise CommandError(_('Error checking for conflicts'))
diff --git a/jhbuild/versioncontrol/tarball.py b/jhbuild/versioncontrol/tarball.py
index 137e5d8..c14f982 100644
--- a/jhbuild/versioncontrol/tarball.py
+++ b/jhbuild/versioncontrol/tarball.py
@@ -25,8 +25,8 @@ try:
     import hashlib
 except ImportError:
     import md5 as hashlib
-import urlparse
-import urllib2
+import urllib.parse
+import urllib.request, urllib.error, urllib.parse
 import logging
 
 from jhbuild.errors import FatalError, CommandError, BuildStateError
@@ -70,7 +70,7 @@ class TarballRepository(Repository):
         else:
             if module is None:
                 module = name
-            module = urlparse.urljoin(self.href, module)
+            module = urllib.parse.urljoin(self.href, module)
         module = module.replace('${version}', version)
         if checkoutdir is not None:
             checkoutdir = checkoutdir.replace('${version}', version)
@@ -250,23 +250,23 @@ class TarballBranch(Branch):
         # now patch the working tree
         for (patch, patchstrip) in self.patches:
             patchfile = ''
-            if urlparse.urlparse(patch)[0]:
+            if urllib.parse.urlparse(patch)[0]:
                 # patch name has scheme, get patch from network
                 try:
                     patchfile = httpcache.load(patch, nonetwork=buildscript.config.nonetwork)
-                except urllib2.HTTPError, e:
+                except urllib.error.HTTPError as e:
                     raise BuildStateError(_('could not download patch (error: %s)') % e.code)
-                except urllib2.URLError, e:
+                except urllib.error.URLError as e:
                     raise BuildStateError(_('could not download patch'))
             elif self.repository.moduleset_uri:
                 # get it relative to the moduleset uri, either in the same
                 # directory or a patches/ subdirectory
                 for patch_prefix in ('.', 'patches', '../patches'):
-                    uri = urlparse.urljoin(self.repository.moduleset_uri,
+                    uri = urllib.parse.urljoin(self.repository.moduleset_uri,
                             os.path.join(patch_prefix, patch))
                     try:
                         patchfile = httpcache.load(uri, nonetwork=buildscript.config.nonetwork)
-                    except Exception, e:
+                    except Exception as e:
                         continue
                     if not os.path.isfile(patchfile):
                         continue
diff --git a/scripts/changecvsroot.py b/scripts/changecvsroot.py
index 0198c3b..fe10e03 100755
--- a/scripts/changecvsroot.py
+++ b/scripts/changecvsroot.py
@@ -21,7 +21,8 @@
 import os
 
 def changecvsroot(oldroot, newroot, *dirs):
-    def handle((oldroot, newroot), dirname, fnames):
+    def handle(xxx_todo_changeme, dirname, fnames):
+        (oldroot, newroot) = xxx_todo_changeme
         if os.path.basename(dirname) == 'CVS' and 'Root' in fnames:
             r = open(os.path.join(dirname, 'Root'), 'r').read().strip()
             if r == oldroot:
diff --git a/scripts/hg-update.py b/scripts/hg-update.py
index cfe5b70..aeed138 100755
--- a/scripts/hg-update.py
+++ b/scripts/hg-update.py
@@ -51,11 +51,11 @@ def update():
         # going to revert the update.
         if index != -1:
             out = out[:index]
-    print out
+    print(out)
     return hg.returncode == 0
 
 def undo_update(parent):
-    print 'Update failed, updating to parent revision'
+    print('Update failed, updating to parent revision')
     env = dict(os.environ)
     env['HGMERGE'] = 'false'
     hg = call(['hg', 'update', '--noninteractive', '-q', parent], env=env)
@@ -74,8 +74,8 @@ if __name__ == '__main__':
     ret = False
     try:
         ret = pull_and_update()
-    except OSError, e:
-        print '%s: %s' % (sys.argv[0], e)
+    except OSError as e:
+        print('%s: %s' % (sys.argv[0], e))
 
     if ret:
         exit_code = 0
diff --git a/scripts/jhbuild.in b/scripts/jhbuild.in
index fc2489f..0710f8c 100644
--- a/scripts/jhbuild.in
+++ b/scripts/jhbuild.in
@@ -1,9 +1,9 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 
 import sys
 import os
-import __builtin__
+import builtins
 
 USE_CHECKOUT_SRC = False
 
@@ -24,9 +24,9 @@ else:
     except ImportError:
         sys.path.insert(0, srcdir)
 
-__builtin__.__dict__['PKGDATADIR'] = pkgdatadir
-__builtin__.__dict__['DATADIR'] = datadir
-__builtin__.__dict__['SRCDIR'] = srcdir
+builtins.__dict__['PKGDATADIR'] = pkgdatadir
+builtins.__dict__['DATADIR'] = datadir
+builtins.__dict__['SRCDIR'] = srcdir
 
 import jhbuild.main
 jhbuild.main.main(sys.argv[1:])
diff --git a/scripts/mk-tarball-moduleset.py b/scripts/mk-tarball-moduleset.py
index 47553b3..09ee602 100755
--- a/scripts/mk-tarball-moduleset.py
+++ b/scripts/mk-tarball-moduleset.py
@@ -6,8 +6,8 @@ import stat
 import re
 import md5
 import getopt
-import urlparse
-import ConfigParser
+import urllib.parse
+import configparser
 import xml.dom.minidom
 
 usage = 'mk-tarball-moduleset -d DEPS -u URI -s DIR'
@@ -28,15 +28,15 @@ def read_deps(filename):
     line = fp.readline()
     while line:
         pkg, dep_pkgs = line.split(':', 1)
-        assert not deps_dict.has_key(pkg), '%s repeated' % pkg
+        assert pkg not in deps_dict, '%s repeated' % pkg
         dep_pkgs = [ dep.strip() for dep in dep_pkgs.split() ]
         deps.append((pkg, dep_pkgs))
         deps_dict[pkg] = dep_pkgs
         line = fp.readline()
     # verify that all dependencies are listed
-    for pkg in deps_dict.keys():
+    for pkg in list(deps_dict.keys()):
         for dep in deps_dict[pkg]:
-            assert deps_dict.has_key(dep), 'dependency %s not found' % dep
+            assert dep in deps_dict, 'dependency %s not found' % dep
     return deps
 
 class SourceRepo:
@@ -84,7 +84,7 @@ class SourceRepo:
             tarball.setAttribute('version', version)
 
             source_node.setAttribute('href',
-                                     urlparse.urljoin(self.uribase, filename))
+                                     urllib.parse.urljoin(self.uribase, filename))
             info = os.stat(os.path.join(self.sourcedir, filename))
             size = info[stat.ST_SIZE]
             source_node.setAttribute('size', str(info[stat.ST_SIZE]))
@@ -104,7 +104,7 @@ def main(args):
         opts, args = getopt.getopt(args, 'd:u:s:x:h',
                                    ['dependencies=', 'uri=', 'source=',
                                     'exceptions=', 'help'])
-    except getopt.error, exc:
+    except getopt.error as exc:
         sys.stderr.write('mk-tarball-moduleset: %s\n' % str(exc))
         sys.stderr.write(usage + '\n')
         sys.exit(1)
@@ -112,11 +112,11 @@ def main(args):
     dependencies = None
     uri = None
     source = None
-    exceptions = ConfigParser.ConfigParser()
+    exceptions = configparser.ConfigParser()
     for opt, arg in opts:
         if opt in ('-h', '--help'):
-            print usage
-            print help
+            print(usage)
+            print(help)
             sys.exit(0)
         elif opt in ('-d', '--dependencies'):
             dependencies = arg
diff --git a/tests/tests.py b/tests/tests.py
index 1745db1..83e28c6 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -28,13 +28,13 @@ import sys
 import tempfile
 import unittest
 
-import __builtin__
-__builtin__.__dict__['_'] = lambda x: x
-__builtin__.__dict__['N_'] = lambda x: x
+import builtins
+builtins.__dict__['_'] = lambda x: x
+builtins.__dict__['N_'] = lambda x: x
 
-__builtin__.__dict__['PKGDATADIR'] = None
-__builtin__.__dict__['DATADIR'] = None
-__builtin__.__dict__['SRCDIR'] = os.path.join(os.path.dirname(__file__), '..')
+builtins.__dict__['PKGDATADIR'] = None
+builtins.__dict__['DATADIR'] = None
+builtins.__dict__['SRCDIR'] = os.path.join(os.path.dirname(__file__), '..')
 
 sys.path.insert(0, SRCDIR)
 
@@ -54,7 +54,7 @@ import jhbuild.utils.cmds
 import jhbuild.versioncontrol.tarball
 
 def uencode(s):
-    if type(s) is unicode:
+    if type(s) is str:
         return s.encode(_encoding, 'replace')
     else:
         return s
@@ -62,11 +62,11 @@ def uencode(s):
 def uprint(*args):
     '''Print Unicode string encoded for the terminal'''
     for s in args[:-1]:
-        print uencode(s),
+        print(uencode(s), end=' ')
     s = args[-1]
-    print uencode(s)
-__builtin__.__dict__['uprint'] = uprint
-__builtin__.__dict__['uencode'] = uencode
+    print(uencode(s))
+builtins.__dict__['uprint'] = uprint
+builtins.__dict__['uencode'] = uencode
 
 
 import mock
@@ -589,9 +589,9 @@ class SimpleBranch(object):
 
 def restore_environ(env):
     # os.environ.clear() doesn't appear to change underlying environment.
-    for key in os.environ.keys():
+    for key in list(os.environ.keys()):
         del os.environ[key]
-    for key, value in env.iteritems():
+    for key, value in env.items():
         os.environ[key] = value
 
 


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