diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8d35cb3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+__pycache__
+*.pyc
diff --git a/.hgignore b/.hgignore
deleted file mode 100644
index 0825a52..0000000
--- a/.hgignore
+++ /dev/null
@@ -1,4 +0,0 @@
-syntax: glob
-
-*.pyc
-
diff --git a/.hgtags b/.hgtags
deleted file mode 100644
index ca77dc0..0000000
--- a/.hgtags
+++ /dev/null
@@ -1,3 +0,0 @@
-4938a2222c2250779560047a61cfa7ad11dc03e8 rel_1_1_2011_0510
-3bd7e4328239a60da67ae0382394c8c7da33a582 rel_1_1_2012_0623
-9d2a2d1cf4b1ab59adf6a511c609e20c8d0a6ff0 rel_1_1_2014_0819
diff --git a/src/8ebed2c.py b/src/8ebed2c.py
index 3addb4f..93c07c9 100755
--- a/src/8ebed2c.py
+++ b/src/8ebed2c.py
@@ -88,8 +88,8 @@
         infilename = args[0]
         outfilename = args[1]
     except IndexError:
-        print "Usage:", __doc__, "\n"
-        print "Run with the -h option to see a list of all options."
+        print("Usage:", __doc__, "\n")
+        print("Run with the -h option to see a list of all options.")
         sys.exit(1)
     parse_and_gen(options, infilename, outfilename, tests=tests.Tests)
     if options.compile:
diff --git a/src/eightebed/context.py b/src/eightebed/context.py
index 8dec8f2..9a9c050 100644
--- a/src/eightebed/context.py
+++ b/src/eightebed/context.py
@@ -12,18 +12,18 @@
     """
     >>> d = Context({ 'a': 2, 'b': 3 })
     >>> e = Context({ 'c': 4 }, parent=d)
-    >>> print e.lookup('c')
+    >>> e.lookup('c')
     4
-    >>> print e.lookup('b')
+    >>> e.lookup('b')
     3
-    >>> print e.lookup('e', None)
-    None
-    >>> print e.lookup('e')
+    >>> e.lookup('e', None) is None
+    True
+    >>> e.lookup('e')
     Traceback (most recent call last):
     ...
     KeyError: 'e'
     >>> d.declare('d', 7)
-    >>> print e.lookup('d')
+    >>> e.lookup('d')
     7
     >>> d.declare('b', 4)
     Traceback (most recent call last):
@@ -34,10 +34,10 @@
     ...
     KeyError: 'b already declared'
     >>> e.empty()
-    >>> print e.lookup('c', None)
-    None
-    >>> print d.lookup('a', None)
-    None
+    >>> e.lookup('c', None) is None
+    True
+    >>> d.lookup('a', None) is None
+    True
 
     """
 
diff --git a/src/eightebed/drivers.py b/src/eightebed/drivers.py
index 1e6fce3..00b50ba 100644
--- a/src/eightebed/drivers.py
+++ b/src/eightebed/drivers.py
@@ -85,7 +85,7 @@
 
 def cmdline(options):
     cmd = ""
-    print "Eightebed interactive!  Type 'quit' to quit."
+    print("Eightebed interactive!  Type 'quit' to quit.")
     options.run = True
     options.clean = True
     while True:
@@ -97,5 +97,5 @@
             ast = parse_and_check(cmd, options=options)
             result = load_and_go(ast, options=options)
             sys.stdout.write(result)
-        except Exception, e:
-            print "Exception!", repr(e)
+        except Exception as e:
+            print("Exception!", repr(e))
diff --git a/src/eightebed/rooibos.py b/src/eightebed/rooibos.py
index 21cd304..2b2c0eb 100644
--- a/src/eightebed/rooibos.py
+++ b/src/eightebed/rooibos.py
@@ -52,14 +52,14 @@
     def peek(self):
         if not self.buffer:
             try:
-                self.buffer.append(self.generator.next())
+                self.buffer.append(next(self.generator))
             except StopIteration:
                 return None
         return self.buffer[0]
 
     def advance(self):
         if not self.buffer:
-            self.buffer.extend(self.generator.next())
+            self.buffer.extend(next(self.generator))
         self.buffer.pop()
 
 
@@ -465,7 +465,7 @@
 
     def __getitem__(self, key):
         if self.trace:
-            print "Reading production ", key
+            print("Reading production ", key)
         if key in self.productions:
             return self.productions[key]
         elif self.parent: