[pitivi] Port Pitivi to Python 3



commit 2696f41b92acfc0f1b093ce425408134b464ff46
Author: Lubosz Sarnecki <lubosz gmail com>
Date:   Tue Apr 9 18:33:31 2013 +0200

    Port Pitivi to Python 3

 Makefile.am                               |    2 +
 autogen.sh                                |    4 +-
 bin/pitivi-git-environment.sh             |    2 +-
 bin/pitivi.in                             |   18 +-
 configure.ac                              |   24 ++-
 m4/python.m4                              |   25 +++
 pitivi/application.py                     |    2 +-
 pitivi/autoaligner.py                     |   18 +-
 pitivi/check.py                           |   16 +-
 pitivi/clipproperties.py                  |   10 +-
 pitivi/configure.py.in                    |    2 +-
 pitivi/coptimizations/Makefile.am         |    6 +-
 pitivi/coptimizations/renderer.c          |   24 +++-
 pitivi/dialogs/depsmanager.py             |    2 +-
 pitivi/dialogs/filelisterrordialog.py     |    2 +-
 pitivi/dialogs/prefs.py                   |    6 +-
 pitivi/effects.py                         |    6 +-
 pitivi/mainwindow.py                      |    4 +-
 pitivi/mediafilespreviewer.py             |   10 +-
 pitivi/medialibrary.py                    |   14 +-
 pitivi/preset.py                          |    9 +-
 pitivi/project.py                         |    6 +-
 pitivi/render.py                          |    6 +-
 pitivi/settings.py                        |   10 +-
 pitivi/timeline/__init__.py               |    2 +-
 pitivi/timeline/elements.py               |    6 +-
 pitivi/timeline/previewers.py             |    4 +-
 pitivi/timeline/ruler.py                  |    4 +-
 pitivi/timeline/timeline.py               |   10 +-
 pitivi/titleeditor.py                     |   58 ++++----
 pitivi/transitions.py                     |    2 +-
 pitivi/undo/timeline.py                   |    8 +-
 pitivi/utils/loggable.py                  |   66 +++++----
 pitivi/utils/misc.py                      |   20 ++--
 pitivi/utils/pipeline.py                  |   12 +-
 pitivi/utils/signal.py                    |   17 +-
 pitivi/utils/system.py                    |    2 +-
 pitivi/utils/timeline.py                  |   12 +-
 pitivi/utils/ui.py                        |   18 ++-
 pitivi/utils/widgets.py                   |   20 ++--
 pitivi/viewer.py                          |   10 +-
 pre-commit.hook                           |   12 +-
 tests/__init__.py                         |    2 +-
 tests/common.py                           |    6 +-
 tests/dogtail_scripts/helper_functions.py |    2 +-
 tests/dogtail_scripts/test_base.py        |    2 +-
 tests/runtests.py                         |    2 +-
 tests/test_common.py                      |    8 +-
 tests/test_log.py                         |   52 +++---
 tests/test_misc.py                        |   16 +-
 tests/test_preset.py                      |    8 +-
 tests/test_project.py                     |   42 +++---
 tests/test_signallable.py                 |   84 +++++------
 tests/test_undo.py                        |  236 ++++++++++++++--------------
 tests/test_utils.py                       |   36 +++---
 55 files changed, 532 insertions(+), 475 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index f536cb3..a2ee16c 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,6 +2,8 @@ AUTOMAKE_OPTIONS = dist-bzip2
 
 SUBDIRS        = bin pitivi common po tests data
 
+ACLOCAL_AMFLAGS = -I m4
+
 if BUILD_HELP
 SUBDIRS += help
 endif
diff --git a/autogen.sh b/autogen.sh
index d5246c0..8a82162 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-export PYTHON=python2
+export PYTHON=python3
 
 DIE=0
 package=pitivi
@@ -79,7 +79,7 @@ fi
 
 # This is needed to create ltmain.sh for our C bits.
 tool_run "$libtoolize" "--copy --force"
-tool_run "$aclocal" "-I common/m4 $ACLOCAL_FLAGS"
+tool_run "$aclocal" "-I common/m4 -I m4 $ACLOCAL_FLAGS"
 tool_run "$autoconf"
 tool_run "$automake" "-a -c"
 
diff --git a/bin/pitivi-git-environment.sh b/bin/pitivi-git-environment.sh
index fbc5fc3..a429713 100755
--- a/bin/pitivi-git-environment.sh
+++ b/bin/pitivi-git-environment.sh
@@ -35,7 +35,7 @@ GOBJECT_INTROSPECTION_RELEASE_TAG="GOBJECT_INTROSPECTION_$(echo $GOBJECT_INTROSP
 # Everything below this line shouldn't be edited!
 #
 
-export PYTHON=python2
+export PYTHON=python3
 
 if ! pkg-config glib-2.0 --atleast-version=$GLIB_RELEASE_TAG; then
   echo "Using a local build of glib"
diff --git a/bin/pitivi.in b/bin/pitivi.in
index a8eb12a..be68e43 100644
--- a/bin/pitivi.in
+++ b/bin/pitivi.in
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 # Pitivi video editor
 #
 #       pitivi
@@ -27,7 +27,7 @@ import locale
 import gettext
 
 localedir = ""
-if os.environ.has_key("APPDIR"):
+if "APPDIR" in os.environ:
     basedir = os.environ["APPDIR"]
     CONFIGURED_PYTHONPATH = ""
     CONFIGURED_GI_TYPELIB_PATH = ""
@@ -79,7 +79,7 @@ def _add_pitivi_path():
     # prepend any directories found at configure time if they're not
     # already in the path. (if they are already in the path, the user
     # chose to have it that way, so we leave their order)
-    for path in string.split(CONFIGURED_PYTHONPATH, ':'):
+    for path in CONFIGURED_PYTHONPATH.split(':'):
         if path not in sys.path:
             sys.path.insert(0, path)
 
@@ -89,12 +89,12 @@ def _add_pitivi_path():
         locale.bindtextdomain('pitivi', localedir)
         locale.textdomain('pitivi')
     except:
-        print "Couldn't set locale."
+        print("Couldn't set locale.")
     try:
         gettext.bindtextdomain('pitivi', localedir)
         gettext.textdomain('pitivi')
     except:
-        print "Couldn't set the gettext domain. Translations will not work."
+        print("Couldn't set the gettext domain. Translations will not work.")
 
     if CONFIGURED_LD_LIBRARY_PATH or CONFIGURED_GST_PLUGIN_PATH:
         _prepend_env_path("LD_LIBRARY_PATH", [CONFIGURED_LD_LIBRARY_PATH])
@@ -112,8 +112,8 @@ def _initialize_modules():
     from pitivi.check import initialize_modules
     try:
         initialize_modules()
-    except Exception, e:
-        print "Failed to initialize modules: ", e
+    except Exception as e:
+        print("Failed to initialize modules: ", e)
 
 
 def _check_requirements():
@@ -127,7 +127,7 @@ def _run_pitivi():
 
     # Make it easy for developers to debug the application startup.
     if os.environ.get('PITIVI_DEBUG_NO_UI') == '1':
-        print 'Starting Pitivi with no GUI.'
+        print('Starting Pitivi with no GUI.')
         ptv.GuiPitivi._showGui = lambda *args, **kargs : None
 
     # Start the real Pitivi, with given arguments.
@@ -146,4 +146,4 @@ if __name__ == "__main__":
         _check_requirements()
         _run_pitivi()
     except KeyboardInterrupt:
-        print "\tPitivi stopped by user with KeyboardInterrupt!"
+        print("\tPitivi stopped by user with KeyboardInterrupt!")
diff --git a/configure.ac b/configure.ac
index e39d949..23eb1f6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,7 +24,8 @@ AC_SUBST_FILE(AUTHORS)
 AUTHORS=$srcdir/AUTHORS
 
 AM_INIT_AUTOMAKE([foreign])
-AC_SUBST(ACLOCAL_AMFLAGS, "-I common/m4")
+AC_SUBST(ACLOCAL_AMFLAGS, "-I m4 -I common/m4")
+AC_CONFIG_MACRO_DIR([m4])
 
 AS_AC_EXPAND(LIBDIR, $libdir)
 AC_MSG_NOTICE(Storing library files in $LIBDIR)
@@ -38,13 +39,18 @@ AC_MSG_NOTICE(Storing configuration files in $SYSCONFDIR)
 AS_AC_EXPAND(LOCALSTATEDIR, $localstatedir)
 AC_MSG_NOTICE(Using localstatedir $LOCALSTATEDIR)
 
-dnl python checks (you can change the required python version bellow)
-AM_PATH_PYTHON(2.7.0)
-PY_PREFIX=`$PYTHON -c 'import sys ; print sys.prefix'`
-PYTHON_LIBS="-lpython$PYTHON_VERSION"
-PYTHON_CFLAGS="-I$PY_PREFIX/include/python$PYTHON_VERSION"
-AC_SUBST([PYTHON_LIBS])
-AC_SUBST([PYTHON_CFLAGS])
+# python checks
+
+# you can change the required python version bellow
+AM_PATH_PYTHON([3])
+
+AM_CHECK_PYTHON_HEADERS(, AC_MSG_ERROR([Python headers not found]))
+
+# - 'SO' for PyPy, CPython 2.7-3.2
+# - 'EXT_SUFFIX' for CPython3.3+ (http://bugs.python.org/issue16754)
+# - fallback to '.so'
+PYTHON_SO=`$PYTHON -c "import distutils.sysconfig, sys; get = distutils.sysconfig.get_config_var; 
sys.stdout.write(get('EXT_SUFFIX') or get('SO') or '.so');"`
+AC_SUBST(PYTHON_SO)
 
 dnl ALL_LINGUAS="fr"
 GETTEXT_PACKAGE="pitivi"
@@ -70,7 +76,7 @@ AC_SUBST(CONFIGURED_GI_TYPELIB_PATH)
 AC_CONFIG_FILES([bin/pitivi], [chmod +x bin/pitivi])
 
 PKG_CHECK_MODULES([cairo], [cairo])
-PKG_CHECK_MODULES([pycairo], [pycairo])
+PKG_CHECK_MODULES([py3cairo], [py3cairo])
 
 AC_ARG_ENABLE(help,
   AS_HELP_STRING([--disable-help],[disable help]),
diff --git a/m4/python.m4 b/m4/python.m4
new file mode 100644
index 0000000..0c56e66
--- /dev/null
+++ b/m4/python.m4
@@ -0,0 +1,25 @@
+dnl a macro to check for ability to create python extensions
+dnl  AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE])
+dnl function also defines PYTHON_INCLUDES
+AC_DEFUN([AM_CHECK_PYTHON_HEADERS],
+[AC_REQUIRE([AM_PATH_PYTHON])
+    AC_MSG_CHECKING(for python headers)
+    # deduce PYTHON_INCLUDES
+    py_prefix=`$PYTHON -c "import sys; print(sys.prefix)"`
+    py_exec_prefix=`$PYTHON -c "import sys; print(sys.exec_prefix)"`
+    if $PYTHON-config --help 1>/dev/null 2>/dev/null; then
+      PYTHON_INCLUDES=`$PYTHON-config --includes 2>/dev/null`
+    else
+      PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}"
+      if test "$py_prefix" != "$py_exec_prefix"; then
+        PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}"
+      fi
+    fi
+    AC_SUBST(PYTHON_INCLUDES)
+    # check if the headers exist
+    CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES"
+    AC_PREPROC_IFELSE(
+      [AC_LANG_PROGRAM([#include <Python.h>])],
+      [AC_MSG_RESULT(found)],
+      [AC_MSG_FAILURE(not found)])
+])
diff --git a/pitivi/application.py b/pitivi/application.py
index 5b1fcad..1c87e38 100644
--- a/pitivi/application.py
+++ b/pitivi/application.py
@@ -215,7 +215,7 @@ class Pitivi(Loggable, Signallable):
             self._version_information["current"] = current_version
             self._version_information["status"] = status
             self.emit("version-info-received", self._version_information)
-        except Exception, e:
+        except Exception as e:
             self.warning("Version info could not be read: %s", e)
 
     def isLatest(self):
diff --git a/pitivi/autoaligner.py b/pitivi/autoaligner.py
index ec608d2..f986237 100644
--- a/pitivi/autoaligner.py
+++ b/pitivi/autoaligner.py
@@ -154,7 +154,7 @@ def _findslope(a):
     x_neg = numpy.arange(2 * X - 1, X, -1)
     best_end = 0
     max_sum = 0
-    for end in xrange(Y):
+    for end in range(Y):
         y = (x_pos * end) // X
         s = numpy.sum(a[y, x_pos])
         if s > max_sum:
@@ -201,7 +201,7 @@ def affinealign(reference, targets, max_drift=0.02):
     # Construct FFT'd reference blocks
     freference_blocks = numpy.zeros((L2 / 2 + 1, num_blocks),
                                     dtype=numpy.complex)
-    for i in xrange(num_blocks):
+    for i in range(num_blocks):
         s = i * bspace
         tmp = numpy.zeros((L2,))
         tmp[s:s + bsize] = reference[s:s + bsize]
@@ -216,7 +216,7 @@ def affinealign(reference, targets, max_drift=0.02):
         #fxcorr is the FFT'd cross-correlation with the reference blocks
         fxcorr_blocks = numpy.zeros((L2 / 2 + 1, num_blocks),
                                     dtype=numpy.complex)
-        for i in xrange(num_blocks):
+        for i in range(num_blocks):
             fxcorr_blocks[:, i] = ft * freference_blocks[:, i]
             fxcorr_blocks[:, i] /= numpy.sqrt(numpy.sum(fxcorr_blocks[:, i] ** 2))
         del ft
@@ -252,7 +252,7 @@ def affinealign(reference, targets, max_drift=0.02):
         # Remove the local-correlation peak.
         halfautocorr[-1:2, -1:2] = 0  # NEEDS TUNING
         # Normalize each column (appears to be necessary)
-        for i in xrange(2 * num_blocks):
+        for i in range(2 * num_blocks):
             halfautocorr[:, i] /= numpy.sqrt(numpy.sum(halfautocorr[:, i] ** 2))
         #from matplotlib.pyplot import imshow,show
         #imshow(halfautocorr,interpolation='nearest',aspect='auto');show()
@@ -263,7 +263,7 @@ def affinealign(reference, targets, max_drift=0.02):
         xcorr_blocks = numpy.fft.irfft(fxcorr_blocks, None, 0)
         del fxcorr_blocks
         #TODO: see if phase ramps are worthwhile here
-        for i in xrange(num_blocks):
+        for i in range(num_blocks):
             blockcenter = i * bspace + bsize / 2
             shift = int(blockcenter * drift)
             if shift > 0:
@@ -566,7 +566,7 @@ class AutoAligner(Loggable):
         """
         progress_aggregator = ProgressAggregator()
         pairs = []  # (Clip, {audio}TrackElement) pairs
-        for clip in self._clips.keys():
+        for clip in list(self._clips.keys()):
             audiotrack = getAudioTrack(clip)
             if audiotrack is not None:
                 pairs.append((clip, audiotrack))
@@ -614,7 +614,7 @@ class AutoAligner(Loggable):
         """
         def priority(clip):
             return clip.priority
-        return min(self._clips.iterkeys(), key=priority)
+        return min(iter(self._clips.keys()), key=priority)
 
     def _performShifts(self):
         self.debug("performing shifts")
@@ -682,10 +682,10 @@ if __name__ == '__main__':
     envelopes = [numpy.fromfile(n) for n in names]
     reference = envelopes[-1]
     offsets, drifts = affinealign(reference, envelopes, 0.02)
-    print offsets, drifts
+    print(offsets, drifts)
     from matplotlib.pyplot import *
     clf()
-    for i in xrange(len(envelopes)):
+    for i in range(len(envelopes)):
         t = offsets[i] + (1 + drifts[i]) * numpy.arange(len(envelopes[i]))
         plot(t, envelopes[i] / numpy.sqrt(numpy.sum(envelopes[i] ** 2)))
     show()
diff --git a/pitivi/check.py b/pitivi/check.py
index fe25f1b..88dc42e 100644
--- a/pitivi/check.py
+++ b/pitivi/check.py
@@ -88,7 +88,7 @@ class Dependency(object):
         """
         raise NotImplementedError
 
-    def __nonzero__(self):
+    def __bool__(self):
         return self.satisfied
 
     def __repr__(self):
@@ -219,24 +219,24 @@ def check_requirements():
         dependency.check()
         if not dependency.satisfied:
             if hard_dependencies_satisfied:
-                print _("ERROR - The following hard dependencies are unmet:")
-                print "=================================================="
-            print dependency
+                print((_("ERROR - The following hard dependencies are unmet:")))
+                print("==================================================")
+            print(dependency)
             hard_dependencies_satisfied = False
 
     for dependency in SOFT_DEPENDENCIES:
         dependency.check()
         if not dependency.satisfied:
             missing_soft_deps[dependency.modulename] = dependency
-            print _("Missing soft dependency:")
-            print dependency
+            print((_("Missing soft dependency:")))
+            print(dependency)
 
     if not hard_dependencies_satisfied:
         return False
 
     if not _check_audiosinks():
-        print _("Could not create audio output sink. "
-                "Make sure you have a valid one (pulsesink, alsasink or osssink).")
+        print((_("Could not create audio output sink. "
+                "Make sure you have a valid one (pulsesink, alsasink or osssink).")))
         return False
 
     return True
diff --git a/pitivi/clipproperties.py b/pitivi/clipproperties.py
index f02209d..8d90c8f 100644
--- a/pitivi/clipproperties.py
+++ b/pitivi/clipproperties.py
@@ -47,7 +47,7 @@ from pitivi.effects import AUDIO_EFFECT, VIDEO_EFFECT, HIDDEN_EFFECTS, \
  COL_TYPE,
  COL_NAME_TEXT,
  COL_DESC_TEXT,
- COL_TRACK_EFFECT) = range(5)
+ COL_TRACK_EFFECT) = list(range(5))
 
 
 class ClipPropertiesError(Exception):
@@ -532,22 +532,22 @@ class TransformationProperties(Gtk.Expander):
 
     def _defaultValuesCb(self, widget):
         self.disconnectSpinButtonsFromFlush()
-        for name, spinbtn in self.spin_buttons.items():
+        for name, spinbtn in list(self.spin_buttons.items()):
             spinbtn.set_value(self.default_values[name])
         self.connectSpinButtonsToFlush()
         # FIXME Why are we looking at the gnl object directly?
         self.effect.gnl_object.props.active = False
 
     def disconnectSpinButtonsFromFlush(self):
-        for spinbtn in self.spin_buttons.values():
+        for spinbtn in list(self.spin_buttons.values()):
             spinbtn.disconnect_by_func(self._flushPipeLineCb)
 
     def connectSpinButtonsToFlush(self):
-        for spinbtn in self.spin_buttons.values():
+        for spinbtn in list(self.spin_buttons.values()):
             spinbtn.connect("output", self._flushPipeLineCb)
 
     def _updateSpinButtons(self):
-        for name, spinbtn in self.spin_buttons.items():
+        for name, spinbtn in list(self.spin_buttons.items()):
             spinbtn.set_value(self.effect.get_property(name))
 
     def _getAndConnectToEffect(self, widget_name, property_name):
diff --git a/pitivi/configure.py.in b/pitivi/configure.py.in
index ebf8a19..93675ac 100644
--- a/pitivi/configure.py.in
+++ b/pitivi/configure.py.in
@@ -38,7 +38,7 @@ def in_devel():
     rd = _get_root_dir()
     return os.path.exists(os.path.join(rd, '.git'))
 
-if os.environ.has_key("APPDIR"):
+if "APPDIR" in os.environ:
     basedir = os.environ["APPDIR"]
     LIBDIR = os.path.join(basedir, 'usr', 'lib')
     PKGDATADIR = os.path.join(basedir, 'usr', 'share', 'pitivi')
diff --git a/pitivi/coptimizations/Makefile.am b/pitivi/coptimizations/Makefile.am
index 2de5912..e11a801 100644
--- a/pitivi/coptimizations/Makefile.am
+++ b/pitivi/coptimizations/Makefile.am
@@ -2,7 +2,7 @@ pyexec_LTLIBRARIES = renderer.la
 
 renderer_la_SOURCES = renderer.c
 pyexecdir = $(libdir)/pitivi/python/pitivi/timeline/
-AM_CFLAGS = $(cairo_CFLAGS) $(pycairo_CFLAGS)
-LIBS = $(cairo_LIBS) $(pycairo_LIBS)
+AM_CFLAGS = $(cairo_CFLAGS) $(py3cairo_CFLAGS)
+LIBS = $(cairo_LIBS) $(py3cairo_LIBS)
 renderer_la_CFLAGS = $(PYTHON_CFLAGS) $(AM_CFLAGS)
-renderer_la_LDFLAGS = -module -avoid-version -export-symbols-regex initrenderer $(LIBS)
+renderer_la_LDFLAGS = -module -avoid-version $(LIBS)
diff --git a/pitivi/coptimizations/renderer.c b/pitivi/coptimizations/renderer.c
index 67977aa..db9c65b 100644
--- a/pitivi/coptimizations/renderer.c
+++ b/pitivi/coptimizations/renderer.c
@@ -1,7 +1,7 @@
 #include <Python.h>
 #include <stdio.h>
 #include <cairo.h>
-#include <pycairo.h>
+#include <py3cairo.h>
 
 static Pycairo_CAPI_t *Pycairo_CAPI;
 
@@ -88,8 +88,22 @@ static PyMethodDef renderer_methods[] = {
   {NULL, NULL}
 };
 
-void initrenderer()
-{
-  Pycairo_IMPORT;
-  (void) Py_InitModule("renderer", renderer_methods);
+static PyModuleDef module = {
+    PyModuleDef_HEAD_INIT,
+    "renderer",
+    "Pitivi renderer module.",
+    -1,
+    renderer_methods, NULL, NULL, NULL, NULL
+};
+
+PyMODINIT_FUNC PyInit_renderer(void) {
+  if (import_cairo() < 0) {
+    g_print("Cairo import failed.");
+  }
+
+  PyObject* m;
+  m = PyModule_Create(&module);
+  if (m == NULL)
+      return NULL;
+  return m;
 }
diff --git a/pitivi/dialogs/depsmanager.py b/pitivi/dialogs/depsmanager.py
index 4698209..c5e6995 100644
--- a/pitivi/dialogs/depsmanager.py
+++ b/pitivi/dialogs/depsmanager.py
@@ -91,7 +91,7 @@ class DepsManager(object):
         missing dependencies
         """
         label_contents = ""
-        for depname, dep in missing_soft_deps.iteritems():
+        for depname, dep in missing_soft_deps.items():
             label_contents += "• %s (%s)\n" % (dep.modulename, dep.additional_message)
         self.builder.get_object("pkg_list").set_text(label_contents)
 
diff --git a/pitivi/dialogs/filelisterrordialog.py b/pitivi/dialogs/filelisterrordialog.py
index 0f101df..26f2585 100644
--- a/pitivi/dialogs/filelisterrordialog.py
+++ b/pitivi/dialogs/filelisterrordialog.py
@@ -29,7 +29,7 @@ from gi.repository import Pango
 
 from gettext import gettext as _
 
-from urllib import unquote
+from urllib.parse import unquote
 from pitivi.configure import get_ui_dir
 from pitivi.utils.signal import Signallable
 from pitivi.utils.loggable import Loggable
diff --git a/pitivi/dialogs/prefs.py b/pitivi/dialogs/prefs.py
index 44d74a1..3435a22 100644
--- a/pitivi/dialogs/prefs.py
+++ b/pitivi/dialogs/prefs.py
@@ -332,7 +332,7 @@ class PreferencesDialog(object):
         """
         Reset all settings to the defaults
         """
-        for section in self.prefs.itervalues():
+        for section in self.prefs.values():
             for attrname in section:
                 self._resetOptionCb(self.resets[attrname], attrname)
 
@@ -341,7 +341,7 @@ class PreferencesDialog(object):
         Resets all settings to the values from before the user opened the
         preferences dialog.
         """
-        for attrname, value in self.original_values.iteritems():
+        for attrname, value in self.original_values.items():
             self.widgets[attrname].setWidgetValue(value)
             setattr(self.settings, attrname, value)
         self._clearHistory()
@@ -391,7 +391,7 @@ class PreferencesDialog(object):
     def _canReset(self):
         # Disable missing docstring
         #pylint: disable=C0111
-        for section in self.prefs.itervalues():
+        for section in self.prefs.values():
             for attrname in section:
                 if not self.settings.isDefault(attrname):
                     return True
diff --git a/pitivi/effects.py b/pitivi/effects.py
index 5a7d222..89336fd 100644
--- a/pitivi/effects.py
+++ b/pitivi/effects.py
@@ -59,7 +59,7 @@ from pitivi.utils.widgets import GstElementSettingsWidget, FractionWidget
 
 
 #------------- Helper to handle effect in the backend ---------------------------#
-(VIDEO_EFFECT, AUDIO_EFFECT) = range(1, 3)
+(VIDEO_EFFECT, AUDIO_EFFECT) = list(range(1, 3))
 
 BLACKLISTED_EFFECTS = ["colorconvert", "coglogoinsert", "festival",
                        "alphacolor", "cogcolorspace", "videodetect",
@@ -364,7 +364,7 @@ GlobalSettings.addConfigSection('effect-library')
  COL_EFFECT_CATEGORIES,
  COL_FACTORY,
  COL_ELEMENT_NAME,
- COL_ICON) = range(7)
+ COL_ICON) = list(range(7))
 
 
 class EffectListWidget(Gtk.VBox, Loggable):
@@ -663,7 +663,7 @@ class EffectsPropertiesManager:
         return effect_set_ui
 
     def _connectAllWidgetCallbacks(self, effect_settings_widget, unused_effect):
-        for prop, widget in effect_settings_widget.properties.iteritems():
+        for prop, widget in effect_settings_widget.properties.items():
             widget.connectValueChanged(self._onValueChangedCb, widget, prop)
 
     def _onSetDefaultCb(self, unused_widget, dynamic):
diff --git a/pitivi/mainwindow.py b/pitivi/mainwindow.py
index 315f407..f0fd190 100644
--- a/pitivi/mainwindow.py
+++ b/pitivi/mainwindow.py
@@ -23,7 +23,7 @@
 import os
 
 from time import time
-from urllib import unquote
+from urllib.parse import unquote
 from gettext import gettext as _
 from hashlib import md5
 
@@ -146,7 +146,7 @@ def create_stock_icons():
     }
     factory = Gtk.IconFactory()
     pmdir = get_pixmap_dir()
-    for stockid, path in pixmaps.iteritems():
+    for stockid, path in pixmaps.items():
         pixbuf = GdkPixbuf.Pixbuf.new_from_file(os.path.join(pmdir, path))
         iconset = Gtk.IconSet.new_from_pixbuf(pixbuf)
         factory.add(stockid, iconset)
diff --git a/pitivi/mediafilespreviewer.py b/pitivi/mediafilespreviewer.py
index 5988d52..d7105c6 100644
--- a/pitivi/mediafilespreviewer.py
+++ b/pitivi/mediafilespreviewer.py
@@ -192,7 +192,7 @@ class PreviewWidget(Gtk.Grid, Loggable):
             self.fixme("Use a GESAsset here, and discover async with it")
             try:
                 info = self.discoverer.discover_uri(uri)
-            except Exception, e:
+            except Exception as e:
                 self.preview_cache_errors[uri] = e
                 if self.current_selected_uri == uri:
                     self.show_error(uri)
@@ -328,7 +328,7 @@ class PreviewWidget(Gtk.Grid, Loggable):
                 self.player.setState(Gst.State.PAUSED)
         elif event.type == Gdk.EventType.BUTTON_RELEASE:
             self.countinuous_seek = False
-            value = long(widget.get_value())
+            value = int(widget.get_value())
             self.player.simple_seek(value)
             if self.is_playing:
                 self.player.setState(Gst.State.PLAYING)
@@ -337,7 +337,7 @@ class PreviewWidget(Gtk.Grid, Loggable):
 
     def _on_motion_notify_cb(self, widget, event):
         if self.countinuous_seek:
-            value = long(widget.get_value())
+            value = int(widget.get_value())
             self.player.simple_seek(value)
 
     def _pipelineEosCb(self, unused_pipeline):
@@ -353,7 +353,7 @@ class PreviewWidget(Gtk.Grid, Loggable):
     def _update_position(self, *unused_args):
         if self.is_playing and not self.slider_being_used:
             curr_pos = self.player.getPosition()
-            self.pos_adj.set_value(long(curr_pos))
+            self.pos_adj.set_value(int(curr_pos))
         return self.is_playing
 
     def _on_preview_video_realize_cb(self, unused_drawing_area, unused_widget):
@@ -423,7 +423,7 @@ class PreviewWidget(Gtk.Grid, Loggable):
     def _tag_found_cb(self, abus, mess):
         tag_list = mess.parse_tag()
         tag_list.foreach(self._appendTag, None)
-        keys = self.tags.keys()
+        keys = list(self.tags.keys())
         keys.sort()
         text = self.description + "\n\n"
         for key in keys:
diff --git a/pitivi/medialibrary.py b/pitivi/medialibrary.py
index 8a67e02..4884f7a 100644
--- a/pitivi/medialibrary.py
+++ b/pitivi/medialibrary.py
@@ -36,9 +36,9 @@ import os
 import time
 import threading
 
-from urllib import unquote
+from urllib.parse import unquote
 from gettext import ngettext, gettext as _
-from urlparse import urlparse
+from urllib.parse import urlparse
 from hashlib import md5
 from gi.repository.GstPbutils import DiscovererVideoInfo
 
@@ -87,7 +87,7 @@ STORE_MODEL_STRUCTURE = (
  COL_ASSET,
  COL_URI,
  COL_LENGTH,
- COL_SEARCH_TEXT) = range(len(STORE_MODEL_STRUCTURE))
+ COL_SEARCH_TEXT) = list(range(len(STORE_MODEL_STRUCTURE)))
 
 ui = '''
 <ui>
@@ -325,7 +325,7 @@ class MediaLibraryWidget(Gtk.VBox, Loggable):
 
     def getAssetForUri(self, uri):
         # Sanitization
-        uri = filter(lambda c: c != '\n' and c != '\r', uri)
+        uri = [c for c in uri if c != '\n' and c != '\r']
         for path in self.modelFilter:
             asset = path[COL_ASSET]
             info = asset.get_info()
@@ -474,7 +474,7 @@ class MediaLibraryWidget(Gtk.VBox, Loggable):
         filt_supported = Gtk.FileFilter()
         filt_known = Gtk.FileFilter()
         filt_supported.set_name(_("Supported file formats"))
-        for category, mime_types in SUPPORTED_FILE_FORMATS.iteritems():
+        for category, mime_types in SUPPORTED_FILE_FORMATS.items():
             for mime in mime_types:
                 filt_supported.add_mime_type(category + "/" + mime)
                 filt_known.add_mime_type(category + "/" + mime)
@@ -578,7 +578,7 @@ class MediaLibraryWidget(Gtk.VBox, Loggable):
             # $HOME/.cache/thumbnails will be used."
             # Older version of the spec also mentioned $HOME/.thumbnails
             quoted_uri = quote_uri(info.get_uri())
-            thumbnail_hash = md5(quoted_uri).hexdigest()
+            thumbnail_hash = md5(quoted_uri.encode()).hexdigest()
             try:
                 thumb_dir = os.environ['XDG_CACHE_HOME']
                 thumb_64, thumb_128 = self._getThumbnailInDir(thumb_dir, thumbnail_hash)
@@ -1028,7 +1028,7 @@ class MediaLibraryWidget(Gtk.VBox, Loggable):
 
         uris = selection.get_data().split("\r\n")
         # Filter out the empty uris.
-        uris = filter(lambda x: x, uris)
+        uris = [x for x in uris if x]
         for raw_uri in uris:
             # Strip out NULL chars first.
             raw_uri = raw_uri.strip('\x00')
diff --git a/pitivi/preset.py b/pitivi/preset.py
index f2b6ce5..e87f68e 100644
--- a/pitivi/preset.py
+++ b/pitivi/preset.py
@@ -137,9 +137,6 @@ class PresetManager(object):
         @param values: The values of the new preset.
         @type values: dict
         """
-        if type(name) == unicode:
-            # We need utf-8 string objects, not unicode objects!
-            name = name.encode("utf-8")
         if self.hasPreset(name):
             raise DuplicatePresetNameException(name)
         self.presets[name] = values
@@ -212,7 +209,7 @@ class PresetManager(object):
             return
         values = self.presets[preset]
         self.cur_preset = preset
-        for field, (setter, getter) in self.widget_map.iteritems():
+        for field, (setter, getter) in self.widget_map.items():
             if values[field] != 0:
                 setter(values[field])
             else:
@@ -228,7 +225,7 @@ class PresetManager(object):
     def _updatePreset(self):
         """Copy the values from the widgets to the preset."""
         values = self.presets[self.cur_preset]
-        for field, (setter, getter) in self.widget_map.iteritems():
+        for field, (setter, getter) in self.widget_map.items():
             values[field] = getter()
 
     def _isCurrentPresetChanged(self):
@@ -238,7 +235,7 @@ class PresetManager(object):
             return False
         values = self.presets[self.cur_preset]
         return any((values[field] != getter()
-                    for field, (setter, getter) in self.widget_map.iteritems()))
+                    for field, (setter, getter) in self.widget_map.items()))
 
     def removePreset(self, name):
         try:
diff --git a/pitivi/project.py b/pitivi/project.py
index 022f084..7ebfe8c 100644
--- a/pitivi/project.py
+++ b/pitivi/project.py
@@ -281,7 +281,7 @@ class ProjectManager(Signallable, Loggable):
             # set to always ask the user on our behalf about overwriting, so
             # if saveProject is actually called, that means overwriting is OK.
             saved = self.current_project.save(self.current_project.timeline, uri, formatter_type, 
overwrite=True)
-        except Exception, e:
+        except Exception as e:
             saved = False
             self.emit("save-project-failed", uri, e)
 
@@ -342,7 +342,7 @@ class ProjectManager(Signallable, Loggable):
         # This catches errors with tarring; the GUI already shows errors while
         # saving projects (ex: permissions), so probably no GUI needed here.
         # Keep the exception generic enough to catch programming errors:
-        except Exception, e:
+        except Exception as e:
             everything_ok = False
             self.error(e)
             tar_file = path_from_uri(uri)
@@ -881,7 +881,7 @@ class Project(Loggable, GES.Project):
         self.pipeline = Pipeline()
         try:
             self.pipeline.set_timeline(self.timeline)
-        except PipelineError, e:
+        except PipelineError as e:
             self.warning("Failed to set the timeline to the pipeline: %s", e)
             return False
 
diff --git a/pitivi/render.py b/pitivi/render.py
index fa74772..dd19f69 100644
--- a/pitivi/render.py
+++ b/pitivi/render.py
@@ -851,7 +851,7 @@ class RenderDialog(Loggable):
         self.window.show()  # Show the rendering dialog again
 
     def _disconnectFromGst(self):
-        for obj, id in self._gstSigId.iteritems():
+        for obj, id in self._gstSigId.items():
             obj.disconnect(id)
         self._gstSigId = {}
         try:
@@ -1034,7 +1034,7 @@ class RenderDialog(Loggable):
         elif factory == get_combo_value(self.audio_encoder_combo):
             settings = self.project.acodecsettings
 
-        for propname, value in settings.iteritems():
+        for propname, value in settings.items():
             element.set_property(propname, value)
             self.debug("Setting %s to %s", propname, value)
 
@@ -1046,7 +1046,7 @@ class RenderDialog(Loggable):
 
     def updateResolution(self):
         width, height = self.project.getVideoWidthAndHeight(True)
-        self.resolution_label.set_text(u"%d×%d" % (width, height))
+        self.resolution_label.set_text("%d×%d" % (width, height))
 
     def _projectSettingsButtonClickedCb(self, unused_button):
         from pitivi.project import ProjectSettingsDialog
diff --git a/pitivi/settings.py b/pitivi/settings.py
index f7205b2..283c1e9 100644
--- a/pitivi/settings.py
+++ b/pitivi/settings.py
@@ -20,7 +20,7 @@
 # Boston, MA 02110-1301, USA.
 
 import os
-from ConfigParser import SafeConfigParser, ParsingError
+from configparser import SafeConfigParser, ParsingError
 
 from gi.repository import GLib
 from pitivi.utils.signal import Signallable
@@ -160,7 +160,7 @@ class GlobalSettings(Signallable):
             if not self._config.has_section(section):
                 continue
             if key and self._config.has_option(section, key):
-                if typ == int or typ == long:
+                if typ == int or typ == int:
                     try:
                         value = self._config.getint(section, key)
                     except ValueError:
@@ -221,7 +221,7 @@ class GlobalSettings(Signallable):
                     self._config.remove_option(section, key)
         try:
             file = open(conf_file_path, 'w')
-        except IOError, OSError:
+        except IOError as OSError:
             return
         self._config.write(file)
         file.close()
@@ -241,8 +241,8 @@ class GlobalSettings(Signallable):
         @return: an iterator which yields a tuple of (attrname, type, key,
         environment, value for each option)
         """
-        for section, options in self.options.iteritems():
-            for attrname, (typ, key, environment) in options.iteritems():
+        for section, options in list(self.options.items()):
+            for attrname, (typ, key, environment) in list(options.items()):
                 yield section, attrname, typ, key, environment, getattr(self, attrname)
 
     def isDefault(self, attrname):
diff --git a/pitivi/timeline/__init__.py b/pitivi/timeline/__init__.py
index 9a1dda6..19c30f9 100644
--- a/pitivi/timeline/__init__.py
+++ b/pitivi/timeline/__init__.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 #
 #       pitivi/timeline/__init__.py
 #
diff --git a/pitivi/timeline/elements.py b/pitivi/timeline/elements.py
index da2470a..955cba8 100644
--- a/pitivi/timeline/elements.py
+++ b/pitivi/timeline/elements.py
@@ -35,7 +35,7 @@ import weakref
 
 from gi.repository import Clutter, Gtk, GtkClutter, Cogl, GES, Gdk, Gst, GstController
 from pitivi.utils.timeline import Zoomable, EditingContext, SELECT, UNSELECT, SELECT_ADD, Selected
-from previewers import AudioPreviewer, VideoPreviewer
+from .previewers import AudioPreviewer, VideoPreviewer
 
 import pitivi.configure as configure
 from pitivi.utils.ui import EXPANDED_SIZE, SPACING, KEYFRAME_SIZE, CONTROL_WIDTH, create_cogl_color
@@ -422,7 +422,7 @@ class TimelineElement(Clutter.Actor, Zoomable):
             source = GstController.InterpolationControlSource()
             source.props.mode = GstController.InterpolationMode.LINEAR
             if not (element.set_control_source(source, propname.name, "direct")):
-                print "There was something like a problem captain"
+                print("There was something like a problem captain")
                 return
             binding = element.get_control_binding(propname.name)
 
@@ -1044,7 +1044,7 @@ class URISourceElement(TimelineElement):
             self.timeline._container.gui.switchContextTab(self.bElement)
 
         children = self.bElement.get_toplevel_parent().get_children(True)
-        selection = filter(lambda elem: isinstance(elem, GES.Source), children)
+        selection = [elem for elem in children if isinstance(elem, GES.Source)]
 
         self.timeline.selection.setSelection(selection, mode)
 
diff --git a/pitivi/timeline/previewers.py b/pitivi/timeline/previewers.py
index d3a86a5..b0241f7 100644
--- a/pitivi/timeline/previewers.py
+++ b/pitivi/timeline/previewers.py
@@ -162,7 +162,7 @@ class VideoPreviewer(Clutter.ScrollActor, PreviewGenerator, Zoomable, Loggable):
         self._running = False
         # We should have one thumbnail per thumb_period.
         # TODO: get this from the user settings
-        self.thumb_period = long(0.5 * Gst.SECOND)
+        self.thumb_period = int(0.5 * Gst.SECOND)
         self.thumb_height = EXPANDED_SIZE - 2 * THUMB_MARGIN_PX
         self.thumb_width = None  # will be set by self._setupPipeline()
 
@@ -275,7 +275,7 @@ class VideoPreviewer(Clutter.ScrollActor, PreviewGenerator, Zoomable, Loggable):
         else:
             self.duration = duration
 
-        self.queue = range(0, duration, self.thumb_period)
+        self.queue = list(range(0, duration, self.thumb_period))
 
         self._checkCPU()
 
diff --git a/pitivi/timeline/ruler.py b/pitivi/timeline/ruler.py
index 6e42113..5db31e3 100644
--- a/pitivi/timeline/ruler.py
+++ b/pitivi/timeline/ruler.py
@@ -302,7 +302,7 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
 
     def drawTimes(self, context, offset, spacing, scale):
         # figure out what the optimal offset is
-        interval = long(Gst.SECOND * scale)
+        interval = int(Gst.SECOND * scale)
         current_time = self.pixelToNs(self.pixbuf_offset)
         paintpos = TIMES_LEFT_MARGIN_PIXELS
         if offset > 0:
@@ -325,7 +325,7 @@ class ScaleRuler(Gtk.DrawingArea, Zoomable, Loggable):
         width = context.get_target().get_width()
         while paintpos < width:
             context.move_to(int(paintpos), 1 - y_bearing)
-            current = split(time_to_string(long(current_time)))
+            current = split(time_to_string(int(current_time)))
             self._drawTime(context, current, previous, millis)
             previous = current
             paintpos += spacing
diff --git a/pitivi/timeline/timeline.py b/pitivi/timeline/timeline.py
index 41fd4f4..c60adf8 100644
--- a/pitivi/timeline/timeline.py
+++ b/pitivi/timeline/timeline.py
@@ -35,11 +35,11 @@ from pitivi.utils.timeline import Zoomable, Selection, SELECT, TimelineError
 from pitivi.utils.ui import alter_style_class, EXPANDED_SIZE, SPACING, PLAYHEAD_COLOR, PLAYHEAD_WIDTH, 
CONTROL_WIDTH
 from pitivi.utils.widgets import ZoomBox
 
-from ruler import ScaleRuler
+from .ruler import ScaleRuler
 from gettext import gettext as _
 from pitivi.utils.pipeline import PipelineError
-from elements import URISourceElement, TransitionElement, Ghostclip
-from controls import ControlContainer
+from .elements import URISourceElement, TransitionElement, Ghostclip
+from .controls import ControlContainer
 
 GlobalSettings.addConfigOption('edgeSnapDeadband',
     section="user-interface",
@@ -1120,7 +1120,7 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
         canvas_width = self.embed.get_allocation().width - CONTROL_WIDTH
         try:
             new_pos = Zoomable.nsToPixel(self._project.pipeline.getPosition())
-        except PipelineError, e:
+        except PipelineError as e:
             self.info("Pipeline error: %s", e)
             return
         except AttributeError:  # Standalone, no pipeline.
@@ -1204,7 +1204,7 @@ class TimelineContainer(Gtk.Grid, Zoomable, Loggable):
         try:
             progress_meter = auto_aligner.start()
             progress_meter.addWatcher(progress_dialog.updatePosition)
-        except Exception, e:
+        except Exception as e:
             self.error("Could not start the autoaligner: %s" % e)
             progress_dialog.window.destroy()
 
diff --git a/pitivi/titleeditor.py b/pitivi/titleeditor.py
index 9059a38..bffc874 100644
--- a/pitivi/titleeditor.py
+++ b/pitivi/titleeditor.py
@@ -31,7 +31,7 @@ from gi.repository import GLib
 from gettext import gettext as _
 from xml.sax import saxutils
 
-from utils.timeline import SELECT
+from .utils.timeline import SELECT
 from pitivi.configure import get_ui_dir, get_pixmap_dir
 from pitivi.utils.loggable import Loggable
 from pitivi.utils.signal import Signallable
@@ -46,10 +46,10 @@ class AttrIterator():
         self.attribute_stack = []
         self.start_index = 0
         self.end_index = 0
-        if not self.next():
+        if not next(self):
             self.end_index = 2 ** 32 - 1
 
-    def next(self):
+    def __next__(self):
         if len(self.attributes) == 0 and len(self.attribute_stack) == 0:
             return False
         self.start_index = self.end_index
@@ -217,15 +217,15 @@ class PangoBuffer(Gtk.TextBuffer):
 
     def set_text(self, txt):
         Gtk.TextBuffer.set_text(self, "")
-        suc, self.parsed, self.txt, self.separator = Pango.parse_markup(txt, -1, u'\x00')
+        suc, self.parsed, self.txt, self.separator = Pango.parse_markup(txt, -1, '\x00')
         if not suc:
             oldtxt = txt
             txt = saxutils.escape(txt)
             self.warn("Marked text is not correct. Escape %s to %s", oldtxt, txt)
-            suc, self.parsed, self.txt, self.separator = Pango.parse_markup(txt, -1, u'\x00')
+            suc, self.parsed, self.txt, self.separator = Pango.parse_markup(txt, -1, '\x00')
         self.attrIter = self.parsed.get_iterator()
         self.add_iter_to_buffer()
-        while self.attrIter.next():
+        while next(self.attrIter):
             self.add_iter_to_buffer()
 
     def add_iter_to_buffer(self):
@@ -351,7 +351,7 @@ class PangoBuffer(Gtk.TextBuffer):
 
     def split_overlap(self, tagdict):
         intervals = []
-        for k, v in tagdict.items():
+        for k, v in list(tagdict.items()):
             #Split by exiting intervals
             tmpint = v
             for i in intervals:
@@ -370,11 +370,11 @@ class PangoBuffer(Gtk.TextBuffer):
             start = self.get_start_iter()
         if not end:
             end = self.get_end_iter()
-        txt = unicode(Gtk.TextBuffer.get_text(self, start, end, True))
+        txt = str(Gtk.TextBuffer.get_text(self, start, end, True))
         #Important step, split that no tags overlap
         tagdict = self.split_overlap(tagdict)
         cuts = {}
-        for k, v in tagdict.items():
+        for k, v in list(tagdict.items()):
             stag, etag = self.tag_to_markup(k)
             for st, e in v:
                 if st in cuts:
@@ -389,11 +389,11 @@ class PangoBuffer(Gtk.TextBuffer):
                     cuts[e + 1] = [etag]
         last_pos = 0
         outbuff = ""
-        cut_indices = cuts.keys()
+        cut_indices = list(cuts.keys())
         cut_indices.sort()
         soffset = start.get_offset()
         eoffset = end.get_offset()
-        cut_indices = filter(lambda i: eoffset >= i >= soffset, cut_indices)
+        cut_indices = [i for i in cut_indices if eoffset >= i >= soffset]
         for c in cut_indices:
             if not last_pos == c:
                 outbuff += saxutils.escape(txt[last_pos:c])
@@ -405,7 +405,7 @@ class PangoBuffer(Gtk.TextBuffer):
 
     def tag_to_markup(self, tag):
         stag = "<span"
-        for k, v in self.tagdict[tag].items():
+        for k, v in list(self.tagdict[tag].items()):
             #family in gtk, face in pango mark language
             if k == "family":
                 k = "face"
@@ -477,7 +477,7 @@ class PangoBuffer(Gtk.TextBuffer):
     def remove_all_tags(self):
         selection = self.get_selection()
         if selection:
-            for t in self.tags.values():
+            for t in list(self.tags.values()):
                 self.remove_tag(t, *selection)
 
 
@@ -511,7 +511,7 @@ class InteractivePangoBuffer(PangoBuffer):
     def setup_widget_from_pango(self, widg, markupstring):
         """setup widget from a pango markup string"""
         #font = Pango.FontDescription(fontstring)
-        suc, a, t, s = Pango.parse_markup(markupstring, -1, u'\x00')
+        suc, a, t, s = Pango.parse_markup(markupstring, -1, '\x00')
         ai = a.get_iterator()
         font, lang, attrs = ai.get_font()
 
@@ -539,7 +539,7 @@ class InteractivePangoBuffer(PangoBuffer):
             return
         self._in_mark_set = True
         if mark.get_name() == 'insert':
-            for tags, widg in self.tag_widgets.items():
+            for tags, widg in list(self.tag_widgets.items()):
                 active = True
                 for t in tags:
                     if not iter.has_tag(t):
@@ -563,7 +563,7 @@ class InteractivePangoBuffer(PangoBuffer):
         if old_itr != insert_itr:
             # Use the state of our widgets to determine what
             # properties to apply...
-            for tags, w in self.tag_widgets.items():
+            for tags, w in list(self.tag_widgets.items()):
                 if w.get_active():
                     for t in tags:
                         self.apply_tag(t, old_itr, insert_itr)
@@ -620,17 +620,17 @@ class TitleEditor(Loggable):
         for setting in settings:
             self.settings[setting] = builder.get_object(setting)
 
-        for n, en in {_("Custom"): "position",
-                      _("Top"): "top",
-                      _("Center"): "center",
-                      _("Bottom"): "bottom",
-                      _("Baseline"): "baseline"}.items():
+        for n, en in list({_("Custom"): "position",
+                _("Top"): "top",
+                _("Center"): "center",
+                _("Bottom"): "bottom",
+                _("Baseline"): "baseline"}.items()):
             self.settings["valignment"].append(en, n)
 
-        for n, en in {_("Custom"): "position",
-                      _("Left"): "left",
-                      _("Center"): "center",
-                      _("Right"): "right"}.items():
+        for n, en in list({_("Custom"): "position",
+                _("Left"): "left",
+                _("Center"): "center",
+                _("Right"): "right"}.items()):
             self.settings["halignment"].append(en, n)
         self._deactivate()
 
@@ -646,7 +646,7 @@ class TitleEditor(Loggable):
         self.source.set_background(color_int)
 
     def _frontTextColorButtonCb(self, widget):
-        suc, a, t, s = Pango.parse_markup("<span color='" + widget.get_color().to_string() + 
"'>color</span>", -1, u'\x00')
+        suc, a, t, s = Pango.parse_markup("<span color='" + widget.get_color().to_string() + 
"'>color</span>", -1, '\x00')
         ai = a.get_iterator()
         font, lang, attrs = ai.get_font()
         tags = self.pangobuffer.get_tags_from_attrs(None, None, attrs)
@@ -657,7 +657,7 @@ class TitleEditor(Loggable):
         font_face = " ".join(font_desc[:-1])
         font_size = str(int(font_desc[-1]) * 1024)
         text = "<span face='" + font_face + "'><span size='" + font_size + "'>text</span></span>"
-        suc, a, t, s = Pango.parse_markup(text, -1, u'\x00')
+        suc, a, t, s = Pango.parse_markup(text, -1, '\x00')
         ai = a.get_iterator()
         font, lang, attrs = ai.get_font()
         tags = self.pangobuffer.get_tags_from_attrs(font, None, attrs)
@@ -748,7 +748,7 @@ class TitleEditor(Loggable):
         """
         if self.source is None:
             return
-        for name, obj in self.settings.items():
+        for name, obj in list(self.settings.items()):
             if obj == updated_obj:
                 if name == "valignment":
                     self.source.set_valignment(getattr(GES.TextVAlign, obj.get_active_id().upper()))
@@ -800,7 +800,7 @@ class TitleEditor(Loggable):
         """
         source = GES.TitleClip()
         source.set_text("")
-        source.set_duration(long(Gst.SECOND * 5))
+        source.set_duration(int(Gst.SECOND * 5))
         self.set_source(source, True)
         # TODO: insert on the current layer at the playhead position.
         # If no space is available, create a new layer to insert to on top.
diff --git a/pitivi/transitions.py b/pitivi/transitions.py
index 798c064..1d7cecc 100644
--- a/pitivi/transitions.py
+++ b/pitivi/transitions.py
@@ -37,7 +37,7 @@ from pitivi.utils.ui import SPACING, PADDING
 (COL_TRANSITION_ASSET,
  COL_NAME_TEXT,
  COL_DESC_TEXT,
- COL_ICON) = range(4)
+ COL_ICON) = list(range(4))
 
 
 class TransitionsListWidget(Signallable, Gtk.VBox, Loggable):
diff --git a/pitivi/undo/timeline.py b/pitivi/undo/timeline.py
index f675f5c..4d39360 100644
--- a/pitivi/undo/timeline.py
+++ b/pitivi/undo/timeline.py
@@ -46,7 +46,7 @@ class ClipPropertyChangeTracker(PropertyChangeTracker):
         if self._disabled and not disabled:
             self._disabled = disabled
             properties = self._takeCurrentSnapshot(self.obj)
-            for property_name, property_value in properties.iteritems():
+            for property_name, property_value in properties.items():
                 old_value = self.properties[property_name]
                 if old_value != property_value:
                     self._propertyChangedCb(self.obj, property_value, property_name)
@@ -125,7 +125,7 @@ class ClipAdded(UndoableAction):
                 for track_element in clip.get_children(False))
 
     def do(self):
-        for track_element, track in self.tracks.iteritems():
+        for track_element, track in self.tracks.items():
             track.addTrackElement(track_element)
 
         self.timeline.addClip(self.clip)
@@ -148,7 +148,7 @@ class ClipRemoved(UndoableAction):
         self._done()
 
     def undo(self):
-        for track_element, track in self.tracks.iteritems():
+        for track_element, track in self.tracks.items():
             track.addTrackElement(track_element)
 
         self.timeline.addClip(self.clip)
@@ -299,7 +299,7 @@ class TimelineLogObserver(object):
             self.effect_properties_tracker.addEffectElement(track_element.getElement())
 
     def _disconnectFromTrackElement(self, track_element):
-        for prop, interpolator in track_element.getInterpolators().itervalues():
+        for prop, interpolator in track_element.getInterpolators().values():
             self._disconnectFromInterpolator(interpolator)
 
     def _connectToInterpolator(self, interpolator):
diff --git a/pitivi/utils/loggable.py b/pitivi/utils/loggable.py
index 1a231c8..72c6680 100644
--- a/pitivi/utils/loggable.py
+++ b/pitivi/utils/loggable.py
@@ -27,7 +27,8 @@ import fnmatch
 import time
 import types
 import traceback
-import thread
+import _thread
+import collections
 
 
 # environment variables controlling levels for each category
@@ -57,7 +58,7 @@ _old_hup_handler = None
  FIXME,
  INFO,
  DEBUG,
- LOG) = range(1, 7)
+ LOG) = list(range(1, 7))
 
 COLORS = {ERROR: 'RED',
           WARN: 'YELLOW',
@@ -179,35 +180,35 @@ class TerminalController:
         # Look up string capabilities.
         for capability in self._STRING_CAPABILITIES:
             (attrib, cap_name) = capability.split('=')
-            setattr(self, attrib, self._tigetstr(cap_name) or '')
+            setattr(self, attrib, self._tigetstr(cap_name) or b'')
 
         # Colors
         set_fg = self._tigetstr('setf')
         if set_fg:
-            for i, color in zip(range(len(self._COLORS)), self._COLORS):
-                setattr(self, color, curses.tparm(set_fg, i) or '')
+            for i, color in zip(list(range(len(self._COLORS))), self._COLORS):
+                setattr(self, color, curses.tparm(set_fg, i) or b'')
         set_fg_ansi = self._tigetstr('setaf')
         if set_fg_ansi:
-            for i, color in zip(range(len(self._ANSICOLORS)),
+            for i, color in zip(list(range(len(self._ANSICOLORS))),
                                 self._ANSICOLORS):
-                setattr(self, color, curses.tparm(set_fg_ansi, i) or '')
+                setattr(self, color, curses.tparm(set_fg_ansi, i) or b'')
         set_bg = self._tigetstr('setb')
         if set_bg:
-            for i, color in zip(range(len(self._COLORS)), self._COLORS):
-                setattr(self, 'BG_' + color, curses.tparm(set_bg, i) or '')
+            for i, color in zip(list(range(len(self._COLORS))), self._COLORS):
+                setattr(self, 'BG_' + color, curses.tparm(set_bg, i) or b'')
         set_bg_ansi = self._tigetstr('setab')
         if set_bg_ansi:
-            for i, color in zip(range(len(self._ANSICOLORS)),
+            for i, color in zip(list(range(len(self._ANSICOLORS))),
                                 self._ANSICOLORS):
-                setattr(self, 'BG_' + color, curses.tparm(set_bg_ansi, i) or '')
+                setattr(self, 'BG_' + color, curses.tparm(set_bg_ansi, i) or b'')
 
     def _tigetstr(self, cap_name):
         # String capabilities can include "delays" of the form "$<2>".
         # For any modern terminal, we should be able to just ignore
         # these, so strip them out.
         import curses
-        cap = curses.tigetstr(cap_name) or ''
-        return re.sub(r'\$<\d+>[/*]?', '', cap)
+        cap = curses.tigetstr(cap_name) or b''
+        return re.sub(r'\$<\d+>[/*]?', '', cap.decode()).encode()
 
     def render(self, template):
         """
@@ -435,11 +436,11 @@ def getFileLine(where=-1):
     name = None
 
     if isinstance(where, types.FunctionType):
-        co = where.func_code
+        co = where.__code__
         lineno = co.co_firstlineno
         name = co.co_name
     elif isinstance(where, types.MethodType):
-        co = where.im_func.func_code
+        co = where.__func__.__code__
         lineno = co.co_firstlineno
         name = co.co_name
     else:
@@ -484,7 +485,7 @@ def getFormatArgs(startFormat, startArgs, endFormat, endArgs, args, kwargs):
     for a in args:
         debugArgs.append(ellipsize(a))
 
-    for items in kwargs.items():
+    for items in list(kwargs.items()):
         debugArgs.extend(items)
     debugArgs.extend(endArgs)
     format = startFormat \
@@ -536,7 +537,7 @@ def doLog(level, object, category, format, args, where=-1, filePath=None, line=N
         for handler in handlers:
             try:
                 handler(level, object, category, filePath, line, message)
-            except TypeError, e:
+            except TypeError as e:
                 raise SystemError("handler %r raised a TypeError: %s" % (
                     handler, getExceptionMessage(e)))
 
@@ -601,7 +602,7 @@ def safeprintf(file, format, *args):
             file.write(format % args)
         else:
             file.write(format)
-    except IOError, e:
+    except IOError as e:
         if e.errno == errno.EPIPE:
             # if our output is closed, exit; e.g. when logging over an
             # ssh connection and the ssh connection is closed
@@ -638,21 +639,32 @@ def stderrHandler(level, object, category, file, line, message):
         # level   pid     object   cat      time
         # 5 + 1 + 7 + 1 + 32 + 1 + 17 + 1 + 15 == 80
         safeprintf(sys.stderr, '%s [%5d] [0x%12x] %-32s %-17s %-15s %-4s %s %s\n',
-                   getFormattedLevelName(level), os.getpid(), thread.get_ident(),
+                   getFormattedLevelName(level), os.getpid(), _thread.get_ident(),
                    o[:32], category, time.strftime("%b %d %H:%M:%S"), "",
                    message, where)
     sys.stderr.flush()
 
 
-def _preformatLevels(enableColorOutput):
+def logLevelName(level):
     format = '%-5s'
+    return format % (_LEVEL_NAMES[level - 1], )
+
+
+def _preformatLevels(enableColorOutput):
 
     if enableColorOutput:
         t = TerminalController()
-        formatter = lambda level: ''.join((t.BOLD, getattr(t, COLORS[level]),
-                            format % (_LEVEL_NAMES[level - 1], ), t.NORMAL))
+
+        if type(t.BOLD) == bytes:
+            formatter = lambda level: ''.join(
+                (t.BOLD.decode(), getattr(t, COLORS[level]).decode(),
+                logLevelName(level), t.NORMAL.decode()))
+        else:
+            formatter = lambda level: ''.join(
+                (t.BOLD, getattr(t, COLORS[level]),
+                logLevelName(level), t.NORMAL))
     else:
-        formatter = lambda level: format % (_LEVEL_NAMES[level - 1], )
+        formatter = lambda level: logLevelName(level)
 
     for level in ERROR, WARN, FIXME, INFO, DEBUG, LOG:
         _FORMATTED_LEVELS.append(formatter(level))
@@ -747,7 +759,7 @@ def addLogHandler(func):
     @raises TypeError: if func is not a callable
     """
 
-    if not callable(func):
+    if not isinstance(func, collections.Callable):
         raise TypeError("func must be callable")
 
     if func not in _log_handlers:
@@ -766,7 +778,7 @@ def addLimitedLogHandler(func):
 
     @raises TypeError: TypeError if func is not a callable
     """
-    if not callable(func):
+    if not isinstance(func, collections.Callable):
         raise TypeError("func must be callable")
 
     if func not in _log_handlers_limited:
@@ -862,7 +874,7 @@ def reopenOutputFiles():
         return
 
     def reopen(name, fileno, *args):
-        oldmask = os.umask(0026)
+        oldmask = os.umask(0o026)
         try:
             f = open(name, 'a+', *args)
         finally:
@@ -902,7 +914,7 @@ def outputToFiles(stdout=None, stderr=None):
             _old_hup_handler(signum, frame)
 
     debug('log', 'installing SIGHUP handler')
-    import signal
+    from . import signal
     handler = signal.signal(signal.SIGHUP, sighup)
     if handler == signal.SIG_DFL or handler == signal.SIG_IGN:
         _old_hup_handler = None
diff --git a/pitivi/utils/misc.py b/pitivi/utils/misc.py
index 1abf7eb..ffa8780 100644
--- a/pitivi/utils/misc.py
+++ b/pitivi/utils/misc.py
@@ -27,8 +27,8 @@ from gi.repository import GLib
 from gi.repository import GObject
 from gi.repository import Gst
 from gi.repository import Gtk
-from urllib import unquote
-from urlparse import urlsplit, urlparse
+from urllib.parse import unquote
+from urllib.parse import urlsplit, urlparse
 import bisect
 import hashlib
 import os
@@ -51,10 +51,10 @@ UNKNOWN_DURATION = 2 ** 63 - 1
 
 native_endianness = struct.pack('=I', 0x34333231)
 
-big_to_cairo_alpha_mask = struct.unpack('=i', '\xFF\x00\x00\x00')[0]
-big_to_cairo_red_mask = struct.unpack('=i', '\x00\xFF\x00\x00')[0]
-big_to_cairo_green_mask = struct.unpack('=i', '\x00\x00\xFF\x00')[0]
-big_to_cairo_blue_mask = struct.unpack('=i', '\x00\x00\x00\xFF')[0]
+big_to_cairo_alpha_mask = struct.unpack(b'=i', b'\xFF\x00\x00\x00')[0]
+big_to_cairo_red_mask = struct.unpack(b'=i', b'\x00\xFF\x00\x00')[0]
+big_to_cairo_green_mask = struct.unpack(b'=i', b'\x00\x00\xFF\x00')[0]
+big_to_cairo_blue_mask = struct.unpack(b'=i', b'\x00\x00\x00\xFF')[0]
 
 
 def between(a, b, c):
@@ -260,8 +260,8 @@ def element_make_many(*args):
 
 
 def pipeline(graph):
-    E = graph.iteritems()
-    V = graph.iterkeys()
+    E = iter(graph.items())
+    V = iter(graph.keys())
     p = Gst.Pipeline()
     p.add(*V)
     for u, v in E:
@@ -385,7 +385,7 @@ def argmax(func, seq):
 
 def same(seq):
     i = iter(seq)
-    first = i.next()
+    first = next(i)
     for item in i:
         if first != item:
             return None
@@ -409,7 +409,7 @@ def show_user_manual(page=None):
         try:
             Gtk.show_uri(None, uri, time_now)
             return
-        except Exception, e:
+        except Exception as e:
             log.debug("utils", "Failed loading URI %s: %s", uri, e)
             continue
     log.warning("utils", "Failed loading URIs")
diff --git a/pitivi/utils/pipeline.py b/pitivi/utils/pipeline.py
index f947eac..e6c6cdb 100644
--- a/pitivi/utils/pipeline.py
+++ b/pitivi/utils/pipeline.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 #
 #       pitivi/utils/pipeline.py
 #
@@ -88,7 +88,7 @@ class Seeker(Signallable, Loggable):
 
     def seekRelative(self, time, on_idle=False):
         if self.pending_seek_id is None:
-            self._time = long(time)
+            self._time = int(time)
             if on_idle:
                 self.pending_seek_id = self._scheduleSeek(self.timeout, self._seekTimeoutCb, relative=True)
             else:
@@ -167,7 +167,7 @@ class SimplePipeline(Signallable, Loggable):
         self._listeningInterval = 300  # default 300ms
         self._listeningSigId = 0
         self._duration = Gst.CLOCK_TIME_NONE
-        self.lastPosition = long(0 * Gst.SECOND)
+        self.lastPosition = int(0 * Gst.SECOND)
         self.pendingRecovery = False
         self._attempted_recoveries = 0
         self._waiting_for_async_done = True
@@ -290,7 +290,7 @@ class SimplePipeline(Signallable, Loggable):
         """
         try:
             res, cur = self._pipeline.query_position(format)
-        except Exception, e:
+        except Exception as e:
             self.handleException(e)
             raise PipelineError("Couldn't get position")
 
@@ -498,7 +498,7 @@ class SimplePipeline(Signallable, Loggable):
     def _getDuration(self, format=Gst.Format.TIME):
         try:
             res, dur = self._pipeline.query_duration(format)
-        except Exception, e:
+        except Exception as e:
             self.handleException(e)
             raise PipelineError("Couldn't get duration: %s" % e)
 
@@ -595,7 +595,7 @@ class Pipeline(GES.Pipeline, SimplePipeline):
 
         cur_frame = int(round(position * framerate.num / float(Gst.SECOND * framerate.denom), 2))
         new_frame = cur_frame + frames_offset
-        new_pos = long(new_frame * Gst.SECOND * framerate.denom / framerate.num)
+        new_pos = int(new_frame * Gst.SECOND * framerate.denom / framerate.num)
         Loggable.info(self, "From frame %d to %d at %f fps, seek to %s s",
                     cur_frame,
                     new_frame,
diff --git a/pitivi/utils/signal.py b/pitivi/utils/signal.py
index d469aec..b19063b 100644
--- a/pitivi/utils/signal.py
+++ b/pitivi/utils/signal.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 #
 #       pitivi/utils/signal.py
 #
@@ -27,6 +27,7 @@
 """
 
 from random import randint
+import collections
 
 
 class SignalGroup:
@@ -78,7 +79,7 @@ class SignalGroup:
         """Disconnect all signals in the group.
 
         """
-        for old_object, handler_id in self.signal_handler_ids.itervalues():
+        for old_object, handler_id in self.signal_handler_ids.values():
             old_object.disconnect(handler_id)
         self.signal_handler_ids = {}
 
@@ -87,7 +88,7 @@ class SignalGroup:
         Disconnects all signal in the group connect on the given object
         """
         assert obj is not None
-        objids = [sid for sid in self.signal_handler_ids.keys() if self.signal_handler_ids[sid][0] == obj]
+        objids = [sid for sid in list(self.signal_handler_ids.keys()) if self.signal_handler_ids[sid][0] == 
obj]
         for sid in objids:
             old_object, handler_id = self.signal_handler_ids.pop(id)
             old_object.disconnect(handler_id)
@@ -118,16 +119,16 @@ class Signallable(object):
             # self.handlers is a dictionnary of callback ids per
             # signals.
             self.handlers = {}
-            for signame in self.siglist.keys():
+            for signame in list(self.siglist.keys()):
                 self.handlers[signame] = []
 
         def connect(self, signame, cb, args, kwargs):
             """ connect """
             # get a unique id
-            if not signame in self.handlers.keys():
+            if not signame in list(self.handlers.keys()):
                 raise Exception("Signal %s is not one of %s" % (signame,
-                ",\n\t".join(self.handlers.keys())))
-            if not callable(cb):
+                ",\n\t".join(list(self.handlers.keys()))))
+            if not isinstance(cb, collections.Callable):
                 raise Exception("Provided callable '%r' is not callable" % cb)
 
             uuid = randint(0, 2 ** 64)
@@ -147,7 +148,7 @@ class Signallable(object):
             except KeyError:
                 raise Exception("unknown signal id")
 
-            for lists in self.handlers.itervalues():
+            for lists in self.handlers.values():
                 try:
                     lists.remove(sigid)
                 except ValueError:
diff --git a/pitivi/utils/system.py b/pitivi/utils/system.py
index 6e80eb9..4cd5651 100644
--- a/pitivi/utils/system.py
+++ b/pitivi/utils/system.py
@@ -181,7 +181,7 @@ class FreedesktopOrgSystem(System):
             notification = Notify.Notification.new(title, message, icon=icon)
             try:
                 notification.show()
-            except RuntimeError, e:
+            except RuntimeError as e:
                 # This can happen if the system is not properly configured.
                 # See for example https://bugzilla.gnome.org/show_bug.cgi?id=719627.
                 self.error("desktopMessage: Failed displaying notification: %s", e.message)
diff --git a/pitivi/utils/timeline.py b/pitivi/utils/timeline.py
index 316f497..2f1bd33 100644
--- a/pitivi/utils/timeline.py
+++ b/pitivi/utils/timeline.py
@@ -55,10 +55,10 @@ class ClipEdited(UndoableAction):
         self.edge = edge
 
     def do(self):
-        self.focus.edit([], self.new_priority, self.mode, self.edge, long(self.new_position))
+        self.focus.edit([], self.new_priority, self.mode, self.edge, int(self.new_position))
 
     def undo(self):
-        self.focus.edit([], self.old_priority, self.mode, self.edge, long(self.old_position))
+        self.focus.edit([], self.old_priority, self.mode, self.edge, int(self.old_position))
 
 
 class Selected(Signallable):
@@ -77,7 +77,7 @@ class Selected(Signallable):
     def __init__(self):
         self._selected = False
 
-    def __nonzero__(self):
+    def __bool__(self):
         """
         checking a Selected object is the same as checking its _selected
         property
@@ -277,7 +277,7 @@ class EditingContext(Signallable):
         self.new_position = position
         self.new_priority = priority
 
-        res = self.focus.edit([], priority, self.mode, self.edge, long(position))
+        res = self.focus.edit([], priority, self.mode, self.edge, int(position))
         if res and self.mode == GES.EditMode.EDIT_TRIM:
             if self.edge == GES.Edge.EDGE_START:
                 self.emit("clip-trim", self.focus, self.focus.props.in_point)
@@ -381,14 +381,14 @@ class Zoomable(object):
         """
         Returns the pixel equivalent in nanoseconds according to the zoomratio
         """
-        return long(pixel * Gst.SECOND / cls.zoomratio)
+        return int(pixel * Gst.SECOND / cls.zoomratio)
 
     @classmethod
     def pixelToNsAt(cls, pixel, ratio):
         """
         Returns the pixel equivalent in nanoseconds according to the zoomratio
         """
-        return long(pixel * Gst.SECOND / ratio)
+        return int(pixel * Gst.SECOND / ratio)
 
     @classmethod
     def nsToPixel(cls, duration):
diff --git a/pitivi/utils/ui.py b/pitivi/utils/ui.py
index d806bbb..ff69bf6 100644
--- a/pitivi/utils/ui.py
+++ b/pitivi/utils/ui.py
@@ -30,7 +30,9 @@ classes that help with UI drawing around the application
 import cairo
 import decimal
 import os
-import urllib
+import urllib.request
+import urllib.parse
+import urllib.error
 
 from gettext import ngettext, gettext as _
 
@@ -213,7 +215,7 @@ def set_cairo_color(context, color):
         cairo_color = (float(color.red), float(color.green), float(color.blue))
     elif type(color) is tuple:
         # Cairo's set_source_rgb function expects values from 0.0 to 1.0
-        cairo_color = map(lambda x: max(0, min(1, x / 255.0)), color)
+        cairo_color = [max(0, min(1, x / 255.0)) for x in color]
     else:
         raise Exception("Unexpected color parameter: %s, %s" % (type(color), color))
     context.set_source_rgb(*cairo_color)
@@ -259,9 +261,9 @@ def info_name(info):
     @type info: L{GES.Asset} or L{DiscovererInfo}
     """
     if isinstance(info, GES.Asset):
-        filename = urllib.unquote(os.path.basename(info.get_id()))
+        filename = urllib.parse.unquote(os.path.basename(info.get_id()))
     elif isinstance(info, DiscovererInfo):
-        filename = urllib.unquote(os.path.basename(info.get_uri()))
+        filename = urllib.parse.unquote(os.path.basename(info.get_uri()))
     else:
         raise Exception("Unsupported argument type: %s" % type(info))
     return GLib.markup_escape_text(filename)
@@ -326,10 +328,10 @@ def beautify_length(length):
     Converts the given time in nanoseconds to a human readable string
     """
     sec = length / Gst.SECOND
-    mins = sec / 60
-    sec = sec % 60
-    hours = mins / 60
-    mins = mins % 60
+    mins = int(sec / 60)
+    sec = int(sec % 60)
+    hours = int(mins / 60)
+    mins = int(mins % 60)
 
     parts = []
     if hours:
diff --git a/pitivi/utils/widgets.py b/pitivi/utils/widgets.py
index 5910656..4fdea9b 100644
--- a/pitivi/utils/widgets.py
+++ b/pitivi/utils/widgets.py
@@ -247,8 +247,8 @@ class NumericWidget(Gtk.HBox, DynamicWidget):
         if self._type is None:
             self._type = type_
 
-        if type_ == int or type_ == long:
-            minimum, maximum = (-sys.maxint, sys.maxint)
+        if type_ == int or type_ == int:
+            minimum, maximum = (-sys.maxsize, sys.maxsize)
             step = 1.0
             page = 10.0
         elif type_ == float:
@@ -526,7 +526,7 @@ class ColorWidget(Gtk.ColorButton, DynamicWidget):
 
         if type_ is str:
             color = Gdk.Color(value)
-        elif (type_ is int) or (type_ is long):
+        elif (type_ is int) or (type_ is int):
             red, green, blue, alpha = unpack_color(value)
             color = Gdk.Color(red, green, blue)
         elif type_ is Gdk.Color:
@@ -542,7 +542,7 @@ class ColorWidget(Gtk.ColorButton, DynamicWidget):
         alpha = self.get_alpha()
         if self.value_type is int:
             return pack_color_32(color.red, color.green, color.blue, alpha)
-        if self.value_type is long:
+        if self.value_type is int:
             return pack_color_64(color.red, color.green, color.blue, alpha)
         elif self.value_type is Gdk.Color:
             return color
@@ -589,7 +589,7 @@ class GstElementSettingsWidget(Gtk.VBox, Loggable):
             # Use the dynamic widget (that has been provided as an argument)
             # to find which of the togglebuttons is the related one.
             self.log("Resetting one keyframe button")
-            for togglebutton in self.keyframeToggleButtons.keys():
+            for togglebutton in list(self.keyframeToggleButtons.keys()):
                 if self.keyframeToggleButtons[togglebutton] is widget:
                     # The dynamic widget matches the one
                     # related to the current to the current togglebutton
@@ -598,7 +598,7 @@ class GstElementSettingsWidget(Gtk.VBox, Loggable):
                     break  # Stop searching
         else:
             self.log("Resetting all keyframe buttons")
-            for togglebutton in self.keyframeToggleButtons.keys():
+            for togglebutton in list(self.keyframeToggleButtons.keys()):
                 togglebutton.set_label("◇")
                 self._setKeyframeToggleButtonState(togglebutton, False)
 
@@ -752,7 +752,7 @@ class GstElementSettingsWidget(Gtk.VBox, Loggable):
         widget = self.keyframeToggleButtons[button]
         widget.set_sensitive(False)
         # Now change the state of the *other* togglebuttons.
-        for togglebutton in self.keyframeToggleButtons.keys():
+        for togglebutton in list(self.keyframeToggleButtons.keys()):
             if togglebutton != button:
                 # Don't use set_active directly on the buttons; doing so will
                 # fire off signals that will toggle the others/confuse the UI
@@ -793,7 +793,7 @@ class GstElementSettingsWidget(Gtk.VBox, Loggable):
         returns the dictionnary of propertyname/propertyvalue
         """
         d = {}
-        for prop, widget in self.properties.iteritems():
+        for prop, widget in self.properties.items():
             if not prop.flags & GObject.PARAM_WRITABLE:
                 continue
             if isinstance(widget, DefaultWidget):
@@ -819,7 +819,7 @@ class GstElementSettingsWidget(Gtk.VBox, Loggable):
             widget = ToggleWidget(default=prop.default_value)
         elif type_name == "GEnum":
             choices = []
-            for key, val in prop.enum_class.__enum_values__.iteritems():
+            for key, val in prop.enum_class.__enum_values__.items():
                 choices.append([val.value_name, int(val)])
             widget = ChoiceWidget(choices, default=prop.default_value)
         elif type_name == "GstFraction":
@@ -894,7 +894,7 @@ class GstElementSettingsDialog(Loggable):
         self.resetAll()
 
     def resetAll(self):
-        for prop, widget in self.elementsettings.properties.iteritems():
+        for prop, widget in self.elementsettings.properties.items():
             widget.setWidgetToDefault()
 
 
diff --git a/pitivi/viewer.py b/pitivi/viewer.py
index 22d08be..c994dc2 100644
--- a/pitivi/viewer.py
+++ b/pitivi/viewer.py
@@ -540,7 +540,7 @@ class Point():
  LEFT,
  RIGHT,
  TOP,
- BOTTOM) = range(10)
+ BOTTOM) = list(range(10))
 
 
 class TransformationBox():
@@ -651,7 +651,7 @@ class TransformationBox():
         else:
             point_width = self.settings.pointSize
 
-        for point in self.points.values():
+        for point in list(self.points.values()):
             point.set_width(point_width)
 
     def draw(self, cr):
@@ -661,14 +661,14 @@ class TransformationBox():
         cr.rectangle(self.left, self.top, self.right - self.left, self.bottom - self.top)
         cr.stroke()
 
-        for point in self.points.values():
+        for point in list(self.points.values()):
             point.draw(cr)
 
     def select_point(self, event):
         # translate when zoomed out
         event.x -= self.area.x
         event.y -= self.area.y
-        for type, point in self.points.items():
+        for type, point in list(self.points.items()):
             if point.is_clicked(event):
                 self.clicked_point = type
                 return
@@ -722,7 +722,7 @@ class TransformationBox():
         return True
 
     def release_point(self):
-        for point in self.points.values():
+        for point in list(self.points.values()):
             point.clicked = False
         self.clicked_point = NO_POINT
 
diff --git a/pre-commit.hook b/pre-commit.hook
index d95ffe5..cfe008c 100755
--- a/pre-commit.hook
+++ b/pre-commit.hook
@@ -1,5 +1,4 @@
-#!/usr/bin/env python2
-from __future__ import with_statement
+#!/usr/bin/env python3
 import os
 import shutil
 import subprocess
@@ -11,6 +10,8 @@ def system(*args, **kwargs):
     kwargs.setdefault('stdout', subprocess.PIPE)
     proc = subprocess.Popen(args, **kwargs)
     out, err = proc.communicate()
+    if type(out) == bytes:
+      out = out.decode()
     return out
 
 
@@ -21,7 +22,7 @@ def copy_files_to_tmp_dir(files):
         filepath = os.path.dirname(filename)
         if not os.path.exists(filepath):
             os.makedirs(filepath)
-        with file(filename, 'w') as f:
+        with open(filename, 'w') as f:
             system('git', 'show', ':' + name, stdout=f)
 
     return tempdir
@@ -36,7 +37,7 @@ def main():
     try:
         pep8_errors = system('pep8', '--repeat', '--ignore', 'E501,E128', '.',
             cwd=tempdir)
-        if pep8_errors != "":
+        if pep8_errors:
             output_message = "Your code is not fully pep8 compliant and contains"\
                 " the following coding style issues:\n\n" + pep8_errors +\
                 "\n\nThanks for correcting them before commiting"
@@ -47,12 +48,13 @@ def main():
            "standard.\nYou can install it:\n"\
            "  * on ubuntu, debian: $sudo apt-get install pep8 \n"\
            "  * on fedora: #yum install python-pep8 \n"\
+           "  * on arch: #pacman -S pep8-python3 \n"\
            "  * or add the official pep8 from http://www.python.org/dev/peps/pep-0008/"\
            " in your $PATH"
 
     shutil.rmtree(tempdir)
     if output_message:
-        print output_message,
+        print(output_message, end=' ')
         sys.exit(1)
 
 
diff --git a/tests/__init__.py b/tests/__init__.py
index 7500891..55c3337 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,4 +1,4 @@
 #!/usr/bin/env python2
 
-import runtests
+from . import runtests
 runtests.setup()
diff --git a/tests/common.py b/tests/common.py
index ae5e5ef..6eced92 100644
--- a/tests/common.py
+++ b/tests/common.py
@@ -45,11 +45,11 @@ class TestCase(unittest.TestCase):
         self.gccollect()
 
         for elt in leaked:
-            print elt
+            print(elt)
             for i in gc.get_referrers(elt):
-                print "   ", i
+                print("   ", i)
 
-        self.failIf(leaked, leaked)
+        self.assertFalse(leaked, leaked)
         del self._tracked
 
     def setUp(self):
diff --git a/tests/dogtail_scripts/helper_functions.py b/tests/dogtail_scripts/helper_functions.py
index 7b410db..14b9425 100644
--- a/tests/dogtail_scripts/helper_functions.py
+++ b/tests/dogtail_scripts/helper_functions.py
@@ -90,7 +90,7 @@ class HelpFunc(BaseDogTail):
                 # and that means we can't assume that it's a text cell. Many
                 # listviews/treeviews/etc have cells for icons (text is None)
                 if child.text is not None:
-                    print "Searching for", text, "in", child.text
+                    print("Searching for", text, "in", child.text)
                     if exactMatchOnly:
                         if text == child.text:
                             return child
diff --git a/tests/dogtail_scripts/test_base.py b/tests/dogtail_scripts/test_base.py
index 3eed6ba..4143d20 100644
--- a/tests/dogtail_scripts/test_base.py
+++ b/tests/dogtail_scripts/test_base.py
@@ -66,7 +66,7 @@ class BaseDogTail(unittest.TestCase):
             # When we were simply searching the toplevel for the menu bar,
             # startup time was 0.0043 seconds. Anything significantly longer
             # means there are optimizations to be done, avoid recursive searches
-            print "\nWARNING: setUp in test_base took", start_time, "seconds, that's too slow.\n"
+            print("\nWARNING: setUp in test_base took", start_time, "seconds, that's too slow.\n")
         try:
             self.unlink
         except AttributeError:
diff --git a/tests/runtests.py b/tests/runtests.py
index 167e0af..a83dd56 100644
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -60,7 +60,7 @@ def setup():
 
     try:
         import mock
-    except ImportError, e:
+    except ImportError as e:
         raise Exception("Python mock library missing! www.voidspace.org.uk/python/mock", e)
 
 
diff --git a/tests/test_common.py b/tests/test_common.py
index 9070a68..d3b9396 100644
--- a/tests/test_common.py
+++ b/tests/test_common.py
@@ -26,21 +26,21 @@ import pitivi.utils.ui as ui_common
 class TestColors(common.TestCase):
 
     def test_pack_color_32(self):
-        self.assertEquals(
+        self.assertEqual(
             0x01020408,
             ui_common.pack_color_32(0x01FF, 0x02FF, 0x04FF, 0x08FF))
 
     def test_pack_color_64(self):
-        self.assertEquals(
+        self.assertEqual(
             0x01FF02FF04FF08FF,
             ui_common.pack_color_64(0x01FF, 0x02FF, 0x04FF, 0x08FF))
 
     def test_unpack_color_32(self):
-        self.assertEquals(
+        self.assertEqual(
             (0x0100, 0x0200, 0x0400, 0x0800),
             ui_common.unpack_color_32(0x01020408))
 
     def test_unpack_color_64(self):
-        self.assertEquals(
+        self.assertEqual(
             (0x01FF, 0x02FF, 0x04FF, 0x08FF),
             ui_common.unpack_color_64(0x01FF02FF04FF08FF))
diff --git a/tests/test_log.py b/tests/test_log.py
index 7cdb35f..da9aa79 100644
--- a/tests/test_log.py
+++ b/tests/test_log.py
@@ -186,21 +186,21 @@ class TestGetExceptionMessage(unittest.TestCase):
         try:
             self.func2()
             self.fail("Should not get to this point")
-        except TypeError, e:
+        except TypeError as e:
             self.verifyException(e)
 
     def testLevel3(self):
         try:
             self.func3()
             self.fail("Should not get to this point")
-        except TypeError, e:
+        except TypeError as e:
             self.verifyException(e)
 
     def verifyException(self, e):
         message = log.getExceptionMessage(e)
-        self.failUnless("func1()" in message, message)
-        self.failUnless("test_log.py" in message, message)
-        self.failUnless("TypeError" in message, message)
+        self.assertTrue("func1()" in message, message)
+        self.assertTrue("test_log.py" in message, message)
+        self.assertTrue("TypeError" in message, message)
 
 
 class TestLogSettings(unittest.TestCase):
@@ -208,10 +208,10 @@ class TestLogSettings(unittest.TestCase):
     def testSet(self):
         old = log.getLogSettings()
         log.setDebug('*:5')
-        self.assertNotEquals(old, log.getLogSettings())
+        self.assertNotEqual(old, log.getLogSettings())
 
         log.setLogSettings(old)
-        self.assertEquals(old, log.getLogSettings())
+        self.assertEqual(old, log.getLogSettings())
 
 
 class TestWriteMark(TestWithHandler):
@@ -222,7 +222,7 @@ class TestWriteMark(TestWithHandler):
         log.addLogHandler(self.handler)
         marker = 'test'
         loggable.writeMarker(marker, log.DEBUG)
-        self.assertEquals(self.message, marker)
+        self.assertEqual(self.message, marker)
 
     def testWriteMarkInWarn(self):
         loggable = log.Loggable()
@@ -230,7 +230,7 @@ class TestWriteMark(TestWithHandler):
         log.addLogHandler(self.handler)
         marker = 'test'
         loggable.writeMarker(marker, log.WARN)
-        self.assertEquals(self.message, marker)
+        self.assertEqual(self.message, marker)
 
     def testWriteMarkInInfo(self):
         loggable = log.Loggable()
@@ -238,7 +238,7 @@ class TestWriteMark(TestWithHandler):
         log.addLogHandler(self.handler)
         marker = 'test'
         loggable.writeMarker(marker, log.INFO)
-        self.assertEquals(self.message, marker)
+        self.assertEqual(self.message, marker)
 
     def testWriteMarkInLog(self):
         loggable = log.Loggable()
@@ -246,7 +246,7 @@ class TestWriteMark(TestWithHandler):
         log.addLogHandler(self.handler)
         marker = 'test'
         loggable.writeMarker(marker, log.LOG)
-        self.assertEquals(self.message, marker)
+        self.assertEqual(self.message, marker)
 
     def testWriteMarkInError(self):
         loggable = log.Loggable()
@@ -254,27 +254,27 @@ class TestWriteMark(TestWithHandler):
         log.addLogHandler(self.handler)
         marker = 'test'
         loggable.writeMarker(marker, log.ERROR)
-        self.assertEquals(self.message, marker)
+        self.assertEqual(self.message, marker)
 
 
 class TestLogNames(unittest.TestCase):
 
     def testGetLevelNames(self):
-        self.assertEquals(['ERROR', 'WARN', 'FIXME', 'INFO', 'DEBUG', 'LOG'],
-                          log.getLevelNames())
+        self.assertEqual(['ERROR', 'WARN', 'FIXME', 'INFO', 'DEBUG', 'LOG'],
+            log.getLevelNames())
 
     def testGetLevelCode(self):
-        self.assertEquals(1, log.getLevelInt('ERROR'))
-        self.assertEquals(2, log.getLevelInt('WARN'))
-        self.assertEquals(3, log.getLevelInt('FIXME'))
-        self.assertEquals(4, log.getLevelInt('INFO'))
-        self.assertEquals(5, log.getLevelInt('DEBUG'))
-        self.assertEquals(6, log.getLevelInt('LOG'))
+        self.assertEqual(1, log.getLevelInt('ERROR'))
+        self.assertEqual(2, log.getLevelInt('WARN'))
+        self.assertEqual(3, log.getLevelInt('FIXME'))
+        self.assertEqual(4, log.getLevelInt('INFO'))
+        self.assertEqual(5, log.getLevelInt('DEBUG'))
+        self.assertEqual(6, log.getLevelInt('LOG'))
 
     def testGetLevelName(self):
-        self.assertEquals('ERROR', log.getLevelName(1))
-        self.assertEquals('WARN', log.getLevelName(2))
-        self.assertEquals('FIXME', log.getLevelName(3))
-        self.assertEquals('INFO', log.getLevelName(4))
-        self.assertEquals('DEBUG', log.getLevelName(5))
-        self.assertEquals('LOG', log.getLevelName(6))
+        self.assertEqual('ERROR', log.getLevelName(1))
+        self.assertEqual('WARN', log.getLevelName(2))
+        self.assertEqual('FIXME', log.getLevelName(3))
+        self.assertEqual('INFO', log.getLevelName(4))
+        self.assertEqual('DEBUG', log.getLevelName(5))
+        self.assertEqual('LOG', log.getLevelName(6))
diff --git a/tests/test_misc.py b/tests/test_misc.py
index ffa847c..e35132e 100644
--- a/tests/test_misc.py
+++ b/tests/test_misc.py
@@ -25,19 +25,19 @@ from pitivi.utils.misc import binary_search
 class BinarySearchTest(unittest.TestCase):
 
     def testEmptyList(self):
-        self.assertEquals(binary_search([], 10), -1)
+        self.assertEqual(binary_search([], 10), -1)
 
     def testExisting(self):
         A = [10, 20, 30]
         for index, element in enumerate(A):
-            self.assertEquals(binary_search([10, 20, 30], element), index)
+            self.assertEqual(binary_search([10, 20, 30], element), index)
 
     def testMissingLeft(self):
-        self.assertEquals(binary_search([10, 20, 30], 1), 0)
-        self.assertEquals(binary_search([10, 20, 30], 16), 1)
-        self.assertEquals(binary_search([10, 20, 30], 29), 2)
+        self.assertEqual(binary_search([10, 20, 30], 1), 0)
+        self.assertEqual(binary_search([10, 20, 30], 16), 1)
+        self.assertEqual(binary_search([10, 20, 30], 29), 2)
 
     def testMissingRight(self):
-        self.assertEquals(binary_search([10, 20, 30], 11), 0)
-        self.assertEquals(binary_search([10, 20, 30], 24), 1)
-        self.assertEquals(binary_search([10, 20, 30], 40), 2)
+        self.assertEqual(binary_search([10, 20, 30], 11), 0)
+        self.assertEqual(binary_search([10, 20, 30], 24), 1)
+        self.assertEqual(binary_search([10, 20, 30], 40), 2)
diff --git a/tests/test_preset.py b/tests/test_preset.py
index 29f9eb7..481c82c 100644
--- a/tests/test_preset.py
+++ b/tests/test_preset.py
@@ -102,9 +102,9 @@ class TestPresetBasics(TestCase):
         self.assertRaises(DuplicatePresetNameException, self.manager.addPreset, 'x', {})
 
     def testAddPresetWithNonAsciiName(self):
-        unicode_name = u"ソリッド・スネーク"
+        unicode_name = "ソリッド・スネーク"
         self.manager.addPreset(unicode_name, {})
-        self.assertTrue(unicode_name.encode("utf-8") in self.manager.getPresetNames())
+        self.assertTrue(unicode_name in self.manager.getPresetNames())
 
     def testRenamePreset(self):
         self.manager.addPreset('preseT onE', {'name1': '1A'})
@@ -165,7 +165,7 @@ class TestAudioPresetsIO(TestCase):
 
         other_manager = self.createOtherManager()
         other_manager.loadAll()
-        self.assertEquals(1 + countDefaultPresets(other_manager), len(other_manager.presets))
+        self.assertEqual(1 + countDefaultPresets(other_manager), len(other_manager.presets))
         snaaaake = other_manager.presets[non_ascii_preset_name]
         self.assertEqual(snake, snaaaake)
 
@@ -181,6 +181,6 @@ class TestAudioPresetsIO(TestCase):
 
         other_manager = self.createOtherManager()
         other_manager.loadAll()
-        self.assertEquals(1 + countDefaultPresets(other_manager), len(other_manager.presets))
+        self.assertEqual(1 + countDefaultPresets(other_manager), len(other_manager.presets))
         other_values = other_manager.presets[preset_name]
         self.assertEqual(values, other_values)
diff --git a/tests/test_project.py b/tests/test_project.py
index 33d0875..6802941 100644
--- a/tests/test_project.py
+++ b/tests/test_project.py
@@ -111,7 +111,7 @@ class TestProjectManager(TestCase):
         self.manager.loadProject(uri)
 
         self.assertEqual(0, len(self.signals))
-        self.failUnless(state["tried-close"], self.signals)
+        self.assertTrue(state["tried-close"], self.signals)
 
     def testLoadProject(self):
         self.manager.newBlankProject()
@@ -130,7 +130,7 @@ class TestProjectManager(TestCase):
             mainloop.quit()
 
         def missingUriCb(self, project, error, clip_asset, mainloop, result):
-            print project, error, clip_asset, mainloop, result
+            print(project, error, clip_asset, mainloop, result)
             result[0] = True
             mainloop.quit()
 
@@ -166,8 +166,8 @@ class TestProjectManager(TestCase):
             os.remove(xges_path)
 
     def testCloseRunningProjectNoProject(self):
-        self.failUnless(self.manager.closeRunningProject())
-        self.failIf(self.signals)
+        self.assertTrue(self.manager.closeRunningProject())
+        self.assertFalse(self.signals)
 
     def testCloseRunningProjectRefuseFromSignal(self):
         def closing(manager, project):
@@ -177,29 +177,29 @@ class TestProjectManager(TestCase):
         self.manager.current_project.uri = "file:///ciao"
         self.manager.connect("closing-project", closing)
 
-        self.failIf(self.manager.closeRunningProject())
+        self.assertFalse(self.manager.closeRunningProject())
         self.assertEqual(1, len(self.signals))
         name, args = self.signals[0]
         self.assertEqual("closing-project", name)
         project = args[0]
-        self.failUnless(project is self.manager.current_project)
+        self.assertTrue(project is self.manager.current_project)
 
     def testCloseRunningProject(self):
         current = self.manager.current_project = MockProject()
-        self.failUnless(self.manager.closeRunningProject())
+        self.assertTrue(self.manager.closeRunningProject())
         self.assertEqual(2, len(self.signals))
 
         name, args = self.signals[0]
         self.assertEqual("closing-project", name)
         project = args[0]
-        self.failUnless(project is current)
+        self.assertTrue(project is current)
 
         name, args = self.signals[1]
         self.assertEqual("project-closed", name)
         project = args[0]
-        self.failUnless(project is current)
+        self.assertTrue(project is current)
 
-        self.failUnless(self.manager.current_project is None)
+        self.assertTrue(self.manager.current_project is None)
 
     def testNewBlankProjectCantCloseCurrent(self):
         def closing(manager, project):
@@ -208,19 +208,19 @@ class TestProjectManager(TestCase):
         self.manager.current_project = MockProject()
         self.manager.current_project.uri = "file:///ciao"
         self.manager.connect("closing-project", closing)
-        self.failIf(self.manager.newBlankProject())
+        self.assertFalse(self.manager.newBlankProject())
         self.assertEqual(1, len(self.signals))
         signal, args = self.signals[0]
         self.assertEqual("closing-project", signal)
 
     def testNewBlankProject(self):
-        self.failUnless(self.manager.newBlankProject())
+        self.assertTrue(self.manager.newBlankProject())
         self.assertEqual(3, len(self.signals))
 
         name, args = self.signals[0]
         self.assertEqual("new-project-loading", name)
         uri = args[0]
-        self.failUnless(uri is None)
+        self.assertTrue(uri is None)
 
         name, args = self.signals[1]
         self.assertEqual("new-project-created", name)
@@ -230,10 +230,10 @@ class TestProjectManager(TestCase):
         name, args = self.signals[2]
         self.assertEqual("new-project-loaded", name)
         project = args[0]
-        self.failUnless(project is self.manager.current_project)
+        self.assertTrue(project is self.manager.current_project)
 
     def testSaveProject(self):
-        self.failUnless(self.manager.newBlankProject())
+        self.assertTrue(self.manager.newBlankProject())
 
         unused, path = tempfile.mkstemp(suffix=".xges")
         unused, path2 = tempfile.mkstemp(suffix=".xges")
@@ -242,15 +242,15 @@ class TestProjectManager(TestCase):
             uri2 = "file://" + os.path.abspath(path2)
 
             # Save the project.
-            self.failUnless(self.manager.saveProject(uri=uri, backup=False))
-            self.failUnless(uri_is_reachable(uri))
+            self.assertTrue(self.manager.saveProject(uri=uri, backup=False))
+            self.assertTrue(uri_is_reachable(uri))
 
             # Wait a bit.
             time.sleep(0.1)
 
             # Save the project at a new location.
-            self.failUnless(self.manager.saveProject(uri2, backup=False))
-            self.failUnless(uri_is_reachable(uri2))
+            self.assertTrue(self.manager.saveProject(uri2, backup=False))
+            self.assertTrue(uri_is_reachable(uri2))
 
             # Make sure the old path and the new path have different mtimes.
             mtime = os.path.getmtime(path)
@@ -261,7 +261,7 @@ class TestProjectManager(TestCase):
             time.sleep(0.1)
 
             # Save project again under the new path (by omitting uri arg)
-            self.failUnless(self.manager.saveProject(backup=False))
+            self.assertTrue(self.manager.saveProject(backup=False))
 
             # regression test for bug 594396
             # make sure we didn't save to the old URI
@@ -288,7 +288,7 @@ class TestProjectManager(TestCase):
 
         # Save the backup
         self.assertTrue(self.manager.saveProject(self.manager.current_project, backup=True))
-        self.failUnless(uri_is_reachable(backup_uri))
+        self.assertTrue(uri_is_reachable(backup_uri))
 
         self.manager.closeRunningProject()
         self.assertFalse(uri_is_reachable(backup_uri), "Backup file not deleted when project closed")
diff --git a/tests/test_signallable.py b/tests/test_signallable.py
index f664ba1..f59b28d 100644
--- a/tests/test_signallable.py
+++ b/tests/test_signallable.py
@@ -59,10 +59,8 @@ class TestSignalisation(unittest.TestCase):
         self.object = myobject()
         self.subobject = mysubobject()
         # internal checks to make sure these objects are clean
-        self.assertEquals(hasattr(self.object, "_signal_group"),
-                          False)
-        self.assertEquals(hasattr(self.subobject, "_signal_group"),
-                          False)
+        self.assertEqual(hasattr(self.object, "_signal_group"), False)
+        self.assertEqual(hasattr(self.subobject, "_signal_group"), False)
 
         # To detect if signals were triggered
         self.s_oneargs_triggered = 0
@@ -104,18 +102,16 @@ class TestSignalisation(unittest.TestCase):
         self.signal_subnoargs_kwargs = kwargs
 
     def test01_get_signals(self):
-        self.assertEquals(self.object.get_signals(),
-                          myobject.__signals__)
+        self.assertEqual(self.object.get_signals(), myobject.__signals__)
         expected = dict(myobject.__signals__)
         expected.update(mysubobject.__signals__)
-        self.assertEquals(self.subobject.get_signals(),
-                          expected)
+        self.assertEqual(self.subobject.get_signals(), expected)
 
     def test02_connect(self):
         def my_cb1(self, firstarg=None):
             pass
         # This should return a uuid
-        self.assert_(self.object.connect("signal-oneargs",
+        self.assertTrue(self.object.connect("signal-oneargs",
                                          my_cb1))
 
         # you can't connect to unexisting signals !
@@ -134,7 +130,7 @@ class TestSignalisation(unittest.TestCase):
         def my_cb1(self, firstarg=None):
             pass
         sigid = self.object.connect("signal-oneargs", my_cb1)
-        self.assert_(sigid)
+        self.assertTrue(sigid)
         self.object.disconnect(sigid)
 
         # disconnecting something already disconnected should
@@ -218,12 +214,12 @@ class TestSignalisation(unittest.TestCase):
         # connect: no arguments
         noargsid = self.object.connect("signal-noargs",
                                        self._cb_noargs)
-        self.assert_(noargsid)
+        self.assertTrue(noargsid)
         self.object.emit_signal_no_args()
-        self.assertEquals(self.s_noargs_triggered, 1)
-        self.assertEquals(self.signal_noargs_args, ())
-        self.assertEquals(self.signal_noargs_signaller, self.object)
-        self.assertEquals(self.signal_noargs_kwargs, {})
+        self.assertEqual(self.s_noargs_triggered, 1)
+        self.assertEqual(self.signal_noargs_args, ())
+        self.assertEqual(self.signal_noargs_signaller, self.object)
+        self.assertEqual(self.signal_noargs_kwargs, {})
 
         # disconnect
         self.object.disconnect(noargsid)
@@ -231,7 +227,7 @@ class TestSignalisation(unittest.TestCase):
         # let's make sure we're not called anymore
         self.s_noargs_triggered = 0
         self.object.emit_signal_no_args()
-        self.assertEquals(self.s_noargs_triggered, 0)
+        self.assertEqual(self.s_noargs_triggered, 0)
 
     def test04_emit02(self):
         # signal: no arguments
@@ -240,37 +236,37 @@ class TestSignalisation(unittest.TestCase):
                                        self._cb_noargs,
                                        1, 2, 3,
                                        myvalue=42)
-        self.assert_(noargsid)
+        self.assertTrue(noargsid)
         self.object.emit_signal_no_args()
-        self.assertEquals(self.s_noargs_triggered, 1)
-        self.assertEquals(self.signal_noargs_args, (1, 2, 3))
-        self.assertEquals(self.signal_noargs_signaller, self.object)
-        self.assertEquals(self.signal_noargs_kwargs, {"myvalue": 42})
+        self.assertEqual(self.s_noargs_triggered, 1)
+        self.assertEqual(self.signal_noargs_args, (1, 2, 3))
+        self.assertEqual(self.signal_noargs_signaller, self.object)
+        self.assertEqual(self.signal_noargs_kwargs, {"myvalue": 42})
 
     def test04_emit03(self):
         # signal: named argument
         # connect: no arguments
         oneargsigid = self.object.connect("signal-oneargs", self._cb_oneargs)
-        self.assert_(oneargsigid)
+        self.assertTrue(oneargsigid)
         self.object.emit_signal_one_args(firstarg="yep")
-        self.assertEquals(self.s_oneargs_triggered, 1)
-        self.assertEquals(self.signal_oneargs_signaller, self.object)
-        self.assertEquals(self.signal_oneargs_firstarg, "yep")
-        self.assertEquals(self.signal_oneargs_args, ())
-        self.assertEquals(self.signal_oneargs_kwargs, {})
+        self.assertEqual(self.s_oneargs_triggered, 1)
+        self.assertEqual(self.signal_oneargs_signaller, self.object)
+        self.assertEqual(self.signal_oneargs_firstarg, "yep")
+        self.assertEqual(self.signal_oneargs_args, ())
+        self.assertEqual(self.signal_oneargs_kwargs, {})
 
     def test04_emit04(self):
         # signal: named argument
         # connect: extra arguments
         oneargsigid = self.object.connect("signal-oneargs", self._cb_oneargs,
                                           1, 2, 3, myvalue=42)
-        self.assert_(oneargsigid)
+        self.assertTrue(oneargsigid)
         self.object.emit_signal_one_args(firstarg="yep")
-        self.assertEquals(self.s_oneargs_triggered, 1)
-        self.assertEquals(self.signal_oneargs_firstarg, "yep")
-        self.assertEquals(self.signal_oneargs_signaller, self.object)
-        self.assertEquals(self.signal_oneargs_args, (1, 2, 3))
-        self.assertEquals(self.signal_oneargs_kwargs, {"myvalue": 42})
+        self.assertEqual(self.s_oneargs_triggered, 1)
+        self.assertEqual(self.signal_oneargs_firstarg, "yep")
+        self.assertEqual(self.signal_oneargs_signaller, self.object)
+        self.assertEqual(self.signal_oneargs_args, (1, 2, 3))
+        self.assertEqual(self.signal_oneargs_kwargs, {"myvalue": 42})
 
     def test05_subclass_emit01(self):
         # making sure a subclass can emit the parent classes
@@ -279,12 +275,12 @@ class TestSignalisation(unittest.TestCase):
                                           self._cb_noargs,
                                           1, 2, 3,
                                           myvalue=42)
-        self.assert_(noargsid)
+        self.assertTrue(noargsid)
         self.subobject.emit_signal_no_args()
-        self.assertEquals(self.s_noargs_triggered, 1)
-        self.assertEquals(self.signal_noargs_signaller, self.subobject)
-        self.assertEquals(self.signal_noargs_args, (1, 2, 3))
-        self.assertEquals(self.signal_noargs_kwargs, {"myvalue": 42})
+        self.assertEqual(self.s_noargs_triggered, 1)
+        self.assertEqual(self.signal_noargs_signaller, self.subobject)
+        self.assertEqual(self.signal_noargs_args, (1, 2, 3))
+        self.assertEqual(self.signal_noargs_kwargs, {"myvalue": 42})
 
     def test06_multiple_emissions(self):
         # connect two handlers to one signal
@@ -292,24 +288,24 @@ class TestSignalisation(unittest.TestCase):
                                         self._cb_noargs,
                                         1, 2, 3,
                                         myvalue=42)
-        self.assert_(noargsid1)
+        self.assertTrue(noargsid1)
         noargsid2 = self.object.connect("signal-noargs",
                                         self._cb_noargs,
                                         1, 2, 3,
                                         myvalue=42)
-        self.assert_(noargsid2)
+        self.assertTrue(noargsid2)
 
         # emit the signal...
         self.object.emit_signal_no_args()
         # ...which should have called all the handlers
-        self.assertEquals(self.s_noargs_triggered, 2)
-        self.assertEquals(self.signal_noargs_args, (1, 2, 3))
-        self.assertEquals(self.signal_noargs_kwargs, {"myvalue": 42})
+        self.assertEqual(self.s_noargs_triggered, 2)
+        self.assertEqual(self.signal_noargs_args, (1, 2, 3))
+        self.assertEqual(self.signal_noargs_kwargs, {"myvalue": 42})
 
         self.object.disconnect(noargsid1)
         self.object.disconnect(noargsid2)
 
         self.object.emit_signal_no_args()
-        self.assertEquals(self.s_noargs_triggered, 2)
+        self.assertEqual(self.s_noargs_triggered, 2)
 
     #FIXME : test return values on emission !
diff --git a/tests/test_undo.py b/tests/test_undo.py
index 0b5c772..cec82db 100644
--- a/tests/test_undo.py
+++ b/tests/test_undo.py
@@ -52,10 +52,10 @@ class TestUndoableAction(TestCase):
         action.connect("undone", doneCb, False)
 
         action.undo()
-        self.failIf(state["done"])
+        self.assertFalse(state["done"])
 
         action.do()
-        self.failUnless(state["done"])
+        self.assertTrue(state["done"])
 
 
 class TestUndoableActionStack(TestCase):
@@ -73,10 +73,10 @@ class TestUndoableActionStack(TestCase):
         stack.connect("undone", doneCb, False)
 
         stack.undo()
-        self.failIf(state["done"])
+        self.assertFalse(state["done"])
 
         stack.do()
-        self.failUnless(state["done"])
+        self.assertTrue(state["done"])
 
     def testUndoDo(self):
         """
@@ -107,12 +107,12 @@ class TestUndoableActionStack(TestCase):
         stack.push(action2)
 
         stack.undo()
-        self.failUnlessEqual(state["actions"], 0)
-        self.failIf(state["done"])
+        self.assertEqual(state["actions"], 0)
+        self.assertFalse(state["done"])
 
         stack.do()
-        self.failUnlessEqual(state["actions"], 2)
-        self.failUnless(state["done"])
+        self.assertEqual(state["actions"], 2)
+        self.assertTrue(state["done"])
 
     def testUndoError(self):
         """
@@ -143,9 +143,9 @@ class TestUndoableActionStack(TestCase):
         stack.push(action1)
         stack.push(action2)
 
-        self.failUnlessRaises(UndoError, stack.undo)
-        self.failUnlessEqual(state["actions"], 1)
-        self.failUnless(state["done"])
+        self.assertRaises(UndoError, stack.undo)
+        self.assertEqual(state["actions"], 1)
+        self.assertTrue(state["done"])
 
 
 class TestUndoableActionLog(TestCase):
@@ -171,156 +171,156 @@ class TestUndoableActionLog(TestCase):
         self.log.disconnect_by_func(self._undoActionLogSignalCb)
 
     def testRollbackWrongState(self):
-        self.failUnlessRaises(UndoWrongStateError, self.log.rollback)
+        self.assertRaises(UndoWrongStateError, self.log.rollback)
 
     def testCommitWrongState(self):
-        self.failUnlessRaises(UndoWrongStateError, self.log.commit)
+        self.assertRaises(UndoWrongStateError, self.log.commit)
 
     def testPushWrongState(self):
         # no error in this case
         self.log.push(None)
 
     def testUndoWrongState(self):
-        self.failUnlessRaises(UndoWrongStateError, self.log.undo)
+        self.assertRaises(UndoWrongStateError, self.log.undo)
 
     def testRedoWrongState(self):
-        self.failUnlessRaises(UndoWrongStateError, self.log.redo)
+        self.assertRaises(UndoWrongStateError, self.log.redo)
 
     def testCheckpoint(self):
         self.log.begin("meh")
         self.log.push(DummyUndoableAction())
-        self.failUnlessRaises(UndoWrongStateError, self.log.checkpoint)
+        self.assertRaises(UndoWrongStateError, self.log.checkpoint)
         self.log.rollback()
         self.log.checkpoint()
-        self.failIfEqual(self.log._checkpoint, None)
+        self.assertNotEqual(self.log._checkpoint, None)
 
     def testDirty(self):
-        self.failIf(self.log.dirty())
+        self.assertFalse(self.log.dirty())
         self.log.begin("meh")
         self.log.push(DummyUndoableAction())
         self.log.commit()
-        self.failUnless(self.log.dirty())
+        self.assertTrue(self.log.dirty())
         self.log.checkpoint()
-        self.failIf(self.log.dirty())
+        self.assertFalse(self.log.dirty())
         self.log.undo()
-        self.failUnless(self.log.dirty())
+        self.assertTrue(self.log.dirty())
         self.log.redo()
-        self.failIf(self.log.dirty())
+        self.assertFalse(self.log.dirty())
 
     def testCommit(self):
         """
         Commit a stack.
         """
-        self.failUnlessEqual(len(self.log.undo_stacks), 0)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(len(self.log.undo_stacks), 0)
+        self.assertEqual(len(self.log.redo_stacks), 0)
         self.log.begin("meh")
-        self.failUnlessEqual(len(self.signals), 1)
+        self.assertEqual(len(self.signals), 1)
         name, (stack, nested) = self.signals[0]
-        self.failUnlessEqual(name, "begin")
-        self.failIf(nested)
+        self.assertEqual(name, "begin")
+        self.assertFalse(nested)
 
-        self.failUnlessEqual(self.log.undo_stacks, [])
+        self.assertEqual(self.log.undo_stacks, [])
         self.log.commit()
-        self.failUnlessEqual(len(self.signals), 2)
+        self.assertEqual(len(self.signals), 2)
         name, (stack, nested) = self.signals[1]
-        self.failUnlessEqual(name, "commit")
-        self.failIf(nested)
-        self.failUnlessEqual(len(self.log.undo_stacks), 1)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(name, "commit")
+        self.assertFalse(nested)
+        self.assertEqual(len(self.log.undo_stacks), 1)
+        self.assertEqual(len(self.log.redo_stacks), 0)
 
     def testNestedCommit(self):
         """
         Do two nested commits.
         """
-        self.failUnlessEqual(len(self.log.undo_stacks), 0)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(len(self.log.undo_stacks), 0)
+        self.assertEqual(len(self.log.redo_stacks), 0)
         self.log.begin("meh")
-        self.failUnlessEqual(len(self.signals), 1)
+        self.assertEqual(len(self.signals), 1)
         name, (stack, nested) = self.signals[0]
-        self.failUnlessEqual(name, "begin")
-        self.failIf(nested)
+        self.assertEqual(name, "begin")
+        self.assertFalse(nested)
 
-        self.failUnlessEqual(len(self.log.undo_stacks), 0)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(len(self.log.undo_stacks), 0)
+        self.assertEqual(len(self.log.redo_stacks), 0)
         self.log.begin("nested")
-        self.failUnlessEqual(len(self.signals), 2)
+        self.assertEqual(len(self.signals), 2)
         name, (stack, nested) = self.signals[1]
-        self.failUnlessEqual(name, "begin")
-        self.failUnless(nested)
+        self.assertEqual(name, "begin")
+        self.assertTrue(nested)
 
-        self.failUnlessEqual(self.log.undo_stacks, [])
+        self.assertEqual(self.log.undo_stacks, [])
         self.log.commit()
-        self.failUnlessEqual(len(self.signals), 3)
+        self.assertEqual(len(self.signals), 3)
         name, (stack, nested) = self.signals[2]
-        self.failUnlessEqual(name, "commit")
-        self.failUnless(nested)
-        self.failUnlessEqual(len(self.log.undo_stacks), 0)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(name, "commit")
+        self.assertTrue(nested)
+        self.assertEqual(len(self.log.undo_stacks), 0)
+        self.assertEqual(len(self.log.redo_stacks), 0)
 
-        self.failUnlessEqual(self.log.undo_stacks, [])
+        self.assertEqual(self.log.undo_stacks, [])
         self.log.commit()
-        self.failUnlessEqual(len(self.signals), 4)
+        self.assertEqual(len(self.signals), 4)
         name, (stack, nested) = self.signals[3]
-        self.failUnlessEqual(name, "commit")
-        self.failIf(nested)
-        self.failUnlessEqual(len(self.log.undo_stacks), 1)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(name, "commit")
+        self.assertFalse(nested)
+        self.assertEqual(len(self.log.undo_stacks), 1)
+        self.assertEqual(len(self.log.redo_stacks), 0)
 
     def testRollback(self):
         """
         Test a rollback.
         """
-        self.failUnlessEqual(len(self.log.undo_stacks), 0)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(len(self.log.undo_stacks), 0)
+        self.assertEqual(len(self.log.redo_stacks), 0)
         self.log.begin("meh")
-        self.failUnlessEqual(len(self.signals), 1)
+        self.assertEqual(len(self.signals), 1)
         name, (stack, nested) = self.signals[0]
-        self.failUnlessEqual(name, "begin")
-        self.failIf(nested)
+        self.assertEqual(name, "begin")
+        self.assertFalse(nested)
 
         self.log.rollback()
-        self.failUnlessEqual(len(self.signals), 2)
+        self.assertEqual(len(self.signals), 2)
         name, (stack, nested) = self.signals[1]
-        self.failUnlessEqual(name, "rollback")
-        self.failIf(nested)
-        self.failUnlessEqual(len(self.log.undo_stacks), 0)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(name, "rollback")
+        self.assertFalse(nested)
+        self.assertEqual(len(self.log.undo_stacks), 0)
+        self.assertEqual(len(self.log.redo_stacks), 0)
 
     def testNestedRollback(self):
         """
         Test two nested rollbacks.
         """
-        self.failUnlessEqual(len(self.log.undo_stacks), 0)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(len(self.log.undo_stacks), 0)
+        self.assertEqual(len(self.log.redo_stacks), 0)
         self.log.begin("meh")
-        self.failUnlessEqual(len(self.signals), 1)
+        self.assertEqual(len(self.signals), 1)
         name, (stack, nested) = self.signals[0]
-        self.failUnlessEqual(name, "begin")
-        self.failIf(nested)
+        self.assertEqual(name, "begin")
+        self.assertFalse(nested)
 
-        self.failUnlessEqual(len(self.log.undo_stacks), 0)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(len(self.log.undo_stacks), 0)
+        self.assertEqual(len(self.log.redo_stacks), 0)
         self.log.begin("nested")
-        self.failUnlessEqual(len(self.signals), 2)
+        self.assertEqual(len(self.signals), 2)
         name, (stack, nested) = self.signals[1]
-        self.failUnlessEqual(name, "begin")
-        self.failUnless(nested)
+        self.assertEqual(name, "begin")
+        self.assertTrue(nested)
 
         self.log.rollback()
-        self.failUnlessEqual(len(self.signals), 3)
+        self.assertEqual(len(self.signals), 3)
         name, (stack, nested) = self.signals[2]
-        self.failUnlessEqual(name, "rollback")
-        self.failUnless(nested)
-        self.failUnlessEqual(len(self.log.undo_stacks), 0)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(name, "rollback")
+        self.assertTrue(nested)
+        self.assertEqual(len(self.log.undo_stacks), 0)
+        self.assertEqual(len(self.log.redo_stacks), 0)
 
         self.log.rollback()
-        self.failUnlessEqual(len(self.signals), 4)
+        self.assertEqual(len(self.signals), 4)
         name, (stack, nested) = self.signals[3]
-        self.failUnlessEqual(name, "rollback")
-        self.failIf(nested)
-        self.failUnlessEqual(len(self.log.undo_stacks), 0)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(name, "rollback")
+        self.assertFalse(nested)
+        self.assertEqual(len(self.log.undo_stacks), 0)
+        self.assertEqual(len(self.log.redo_stacks), 0)
 
     def testUndoRedo(self):
         """
@@ -328,61 +328,61 @@ class TestUndoableActionLog(TestCase):
         """
         # begin
         self.log.begin("meh")
-        self.failUnlessEqual(len(self.signals), 1)
+        self.assertEqual(len(self.signals), 1)
         name, (stack, nested) = self.signals[0]
-        self.failUnlessEqual(name, "begin")
-        self.failIf(nested)
+        self.assertEqual(name, "begin")
+        self.assertFalse(nested)
 
         # push two actions
         action1 = DummyUndoableAction()
         self.log.push(action1)
-        self.failUnlessEqual(len(self.signals), 2)
+        self.assertEqual(len(self.signals), 2)
         name, (stack, signalAction) = self.signals[1]
-        self.failUnlessEqual(name, "push")
-        self.failUnless(action1 is signalAction)
+        self.assertEqual(name, "push")
+        self.assertTrue(action1 is signalAction)
 
         action2 = DummyUndoableAction()
         self.log.push(action2)
-        self.failUnlessEqual(len(self.signals), 3)
+        self.assertEqual(len(self.signals), 3)
         name, (stack, signalAction) = self.signals[2]
-        self.failUnlessEqual(name, "push")
-        self.failUnless(action2 is signalAction)
+        self.assertEqual(name, "push")
+        self.assertTrue(action2 is signalAction)
 
         # commit
-        self.failUnlessEqual(len(self.log.undo_stacks), 0)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(len(self.log.undo_stacks), 0)
+        self.assertEqual(len(self.log.redo_stacks), 0)
         self.log.commit()
-        self.failUnlessEqual(len(self.signals), 4)
+        self.assertEqual(len(self.signals), 4)
         name, (stack, nested) = self.signals[3]
-        self.failUnlessEqual(name, "commit")
-        self.failIf(nested)
-        self.failUnlessEqual(len(self.log.undo_stacks), 1)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(name, "commit")
+        self.assertFalse(nested)
+        self.assertEqual(len(self.log.undo_stacks), 1)
+        self.assertEqual(len(self.log.redo_stacks), 0)
 
-        self.failUnless(action1.done_)
-        self.failUnless(action2.done_)
+        self.assertTrue(action1.done_)
+        self.assertTrue(action2.done_)
 
         # undo what we just committed
         self.log.undo()
-        self.failUnlessEqual(len(self.signals), 5)
+        self.assertEqual(len(self.signals), 5)
         name, stack = self.signals[4]
-        self.failUnlessEqual(name, "undo")
-        self.failUnlessEqual(len(self.log.undo_stacks), 0)
-        self.failUnlessEqual(len(self.log.redo_stacks), 1)
+        self.assertEqual(name, "undo")
+        self.assertEqual(len(self.log.undo_stacks), 0)
+        self.assertEqual(len(self.log.redo_stacks), 1)
 
-        self.failIf(action1.done_)
-        self.failIf(action2.done_)
+        self.assertFalse(action1.done_)
+        self.assertFalse(action2.done_)
 
         # redo
         self.log.redo()
-        self.failUnlessEqual(len(self.signals), 6)
+        self.assertEqual(len(self.signals), 6)
         name, stack = self.signals[5]
-        self.failUnlessEqual(name, "redo")
-        self.failUnlessEqual(len(self.log.undo_stacks), 1)
-        self.failUnlessEqual(len(self.log.redo_stacks), 0)
+        self.assertEqual(name, "redo")
+        self.assertEqual(len(self.log.undo_stacks), 1)
+        self.assertEqual(len(self.log.redo_stacks), 0)
 
-        self.failUnless(action1.done_)
-        self.failUnless(action2.done_)
+        self.assertTrue(action1.done_)
+        self.assertTrue(action2.done_)
 
     def testOrder(self):
         """
@@ -415,12 +415,12 @@ class TestUndoableActionLog(TestCase):
         self.log.commit()
 
         self.log.undo()
-        self.failUnlessEqual(call_sequence, ["undo3", "undo2", "undo1"])
+        self.assertEqual(call_sequence, ["undo3", "undo2", "undo1"])
 
         call_sequence[:] = []
         self.log.redo()
-        self.failUnlessEqual(call_sequence, ["do1", "do2", "do3"])
+        self.assertEqual(call_sequence, ["do1", "do2", "do3"])
 
         call_sequence[:] = []
         self.log.undo()
-        self.failUnlessEqual(call_sequence, ["undo3", "undo2", "undo1"])
+        self.assertEqual(call_sequence, ["undo3", "undo2", "undo1"])
diff --git a/tests/test_utils.py b/tests/test_utils.py
index e448972..877bfaf 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -34,23 +34,23 @@ hour = minute * 60
 
 class TestBeautifyLength(TestCase):
     def testBeautifySeconds(self):
-        self.failUnlessEqual(beautify_length(second), "1 second")
-        self.failUnlessEqual(beautify_length(second * 2), "2 seconds")
+        self.assertEqual(beautify_length(second), "1 second")
+        self.assertEqual(beautify_length(second * 2), "2 seconds")
 
     def testBeautifyMinutes(self):
-        self.failUnlessEqual(beautify_length(minute), "1 minute")
-        self.failUnlessEqual(beautify_length(minute * 2), "2 minutes")
+        self.assertEqual(beautify_length(minute), "1 minute")
+        self.assertEqual(beautify_length(minute * 2), "2 minutes")
 
     def testBeautifyHours(self):
-        self.failUnlessEqual(beautify_length(hour), "1 hour")
-        self.failUnlessEqual(beautify_length(hour * 2), "2 hours")
+        self.assertEqual(beautify_length(hour), "1 hour")
+        self.assertEqual(beautify_length(hour * 2), "2 hours")
 
     def testBeautifyMinutesAndSeconds(self):
-        self.failUnlessEqual(beautify_length(minute + second),
+        self.assertEqual(beautify_length(minute + second),
                 "1 minute, 1 second")
 
     def testBeautifyHoursAndMinutes(self):
-        self.failUnlessEqual(beautify_length(hour + minute + second),
+        self.assertEqual(beautify_length(hour + minute + second),
                 "1 hour, 1 minute")
 
 
@@ -58,40 +58,40 @@ class TestDependencyChecks(TestCase):
     def testDependencies(self):
         gi_dep = GstDependency("Gst", "1.0.0")
         gi_dep.check()
-        self.failUnless(gi_dep.satisfied)
+        self.assertTrue(gi_dep.satisfied)
 
         gi_dep = GstDependency("Gst", "9.9.9")
         gi_dep.check()
-        self.failIf(gi_dep.satisfied)
+        self.assertFalse(gi_dep.satisfied)
 
         gi_dep = GstDependency("ThisShouldNotExist", None)
         gi_dep.check()
-        self.failIf(gi_dep.satisfied)
+        self.assertFalse(gi_dep.satisfied)
 
         gi_dep = GtkOrClutterDependency("Gtk", "3.0.0")
         gi_dep.check()
-        self.failUnless(gi_dep.satisfied)
+        self.assertTrue(gi_dep.satisfied)
 
         gi_dep = GtkOrClutterDependency("Gtk", "9.9.9")
         gi_dep.check()
-        self.failIf(gi_dep.satisfied)
+        self.assertFalse(gi_dep.satisfied)
 
         cairo_dep = CairoDependency("1.0.0")
         cairo_dep.check()
-        self.failUnless(cairo_dep.satisfied)
+        self.assertTrue(cairo_dep.satisfied)
 
         cairo_dep = CairoDependency("9.9.9")
         cairo_dep.check()
-        self.failIf(cairo_dep.satisfied)
+        self.assertFalse(cairo_dep.satisfied)
 
         classic_dep = ClassicDependency("numpy", None)
         classic_dep.check()
-        self.failUnless(classic_dep.satisfied)
+        self.assertTrue(classic_dep.satisfied)
 
         gst_plugin_dep = GstPluginDependency("gnonlin", "1.1.90")
         gst_plugin_dep.check()
-        self.failUnless(gst_plugin_dep.satisfied)
+        self.assertTrue(gst_plugin_dep.satisfied)
 
         gst_plugin_dep = GstPluginDependency("gnonlin", "9.9.9")
         gst_plugin_dep.check()
-        self.failIf(gst_plugin_dep.satisfied)
+        self.assertFalse(gst_plugin_dep.satisfied)


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