--- lib/contrib/debian/errorhandler.py	(original)
+++ lib/contrib/debian/errorhandler.py	(refactored)
@@ -88,7 +88,7 @@
             warn_msgs.append('For image conversion Debian package inkscape is'
                              + ' needed')
         if warn_msgs:
-            print >> sys.stderr, "\n" + "\n".join(warn_msgs) + "\n"
+            print("\n" + "\n".join(warn_msgs) + "\n", file=sys.stderr)
             return True
         else:
             return False
@@ -119,11 +119,11 @@
         nulldev1.close()
 
         if rc == 3 or rc == 4:
-            print >> sys.stderr
-            print >> sys.stderr, 'A possible reason for transformation',
-            print >> sys.stderr, 'failure is invalid DocBook'
-            print >> sys.stderr, '(as reported by xmllint)'
-            print >> sys.stderr
+            print(file=sys.stderr)
+            print('A possible reason for transformation', end=' ', file=sys.stderr)
+            print('failure is invalid DocBook', file=sys.stderr)
+            print('(as reported by xmllint)', file=sys.stderr)
+            print(file=sys.stderr)
             return True
         else:
             return False
@@ -157,7 +157,7 @@
                 warn_msgs.append('For utf8 encoding Debian package '
                                  + debian_pkg + ' is needed')
         if warn_msgs:
-            print >> sys.stderr, "\n" + "\n".join(warn_msgs) + "\n"
+            print("\n" + "\n".join(warn_msgs) + "\n", file=sys.stderr)
             return True
         else:
             return False
@@ -182,12 +182,12 @@
             for log_entry in obj.runtex.texer.tex.log.get_errors():
                 if (log_entry['text']
                     == r'Undefined control sequence \cyrchar.'):
-                    print >> sys.stderr
-                    print >> sys.stderr, 'Transformation failure',
-                    print >> sys.stderr, 'might be caused by handling a',
-                    print >> sys.stderr, 'cyrillic document'
-                    print >> sys.stderr, 'without the XeTeX backend'
-                    print >> sys.stderr
+                    print(file=sys.stderr)
+                    print('Transformation failure', end=' ', file=sys.stderr)
+                    print('might be caused by handling a', end=' ', file=sys.stderr)
+                    print('cyrillic document', file=sys.stderr)
+                    print('without the XeTeX backend', file=sys.stderr)
+                    print(file=sys.stderr)
                     return True
         except:
             pass
--- lib/dbtexmf/core/txtparser.py	(original)
+++ lib/dbtexmf/core/txtparser.py	(refactored)
@@ -96,7 +96,7 @@
                 continue
             key = m.group(1)
             value = m.group(2).strip()
-            if not self.conf_mapping.has_key(key):
+            if key not in self.conf_mapping:
                 continue
             o = self.conf_mapping[key]
 
--- lib/dbtexmf/core/error.py	(original)
+++ lib/dbtexmf/core/error.py	(refactored)
@@ -49,7 +49,7 @@
 
 def failure_track(msg):
     global _dump_stack
-    print >>sys.stderr, (msg)
+    print((msg), file=sys.stderr)
     if _dump_stack:
         traceback.print_exc()
 
--- lib/dbtexmf/dblatex/xetex/fcmanager.py	(original)
+++ lib/dbtexmf/dblatex/xetex/fcmanager.py	(refactored)
@@ -169,7 +169,7 @@
 
     def get_font_handling(self, char, all=False, family_type=""):
         if not(family_type):
-            font_family = self.fonts.values()
+            font_family = list(self.fonts.values())
         else:
             font_family = self.fonts_family.get(family_type, None)
         
--- lib/dbtexmf/dblatex/grubber/bibtopic.py	(original)
+++ lib/dbtexmf/dblatex/grubber/bibtopic.py	(refactored)
@@ -1,6 +1,6 @@
 
-from plugins import TexModule
-from bibtex import BibTex
+from .plugins import TexModule
+from .bibtex import BibTex
 
 
 class BibSect(BibTex):
--- lib/dbtexmf/dblatex/grubber/index.py	(original)
+++ lib/dbtexmf/dblatex/grubber/index.py	(refactored)
@@ -45,9 +45,9 @@
 import xml.dom.minidom
 
 from subprocess import Popen, PIPE
-from msg import _, msg
-from plugins import TexModule
-from util import md5_file
+from .msg import _, msg
+from .plugins import TexModule
+from .util import md5_file
 
 
 class Xindy:
@@ -514,7 +514,7 @@
         index = self.indices[name] = Index(self.doc, idx, ind, ilg)
         for cmd in self.defaults:
             index.command(*cmd)
-        if self.commands.has_key(name):
+        if name in self.commands:
             for cmd in self.commands[name]:
                 index.command(*cmd)
 
@@ -546,23 +546,23 @@
                 args = args[1:]
         if names is None:
             self.defaults.append([cmd, args])
-            names = indices.keys()
+            names = list(indices.keys())
         for index in names:
-            if indices.has_key(index):
+            if index in indices:
                 indices[index].command(cmd, args[1:])
-            elif self.commands.has_key(index):
+            elif index in self.commands:
                 self.commands[index].append([cmd, args])
             else:
                 self.commands[index] = [[cmd, args]]
 
     def post_compile (self):
-        for index in self.indices.values():
+        for index in list(self.indices.values()):
             if index.post_compile():
                 return 1
         return 0
 
     def clean (self):
-        for index in self.indices.values():
+        for index in list(self.indices.values()):
             index.clean()
         return 0
 
--- lib/dbtexmf/dblatex/grubber/ps2pdf.py	(original)
+++ lib/dbtexmf/dblatex/grubber/ps2pdf.py	(refactored)
@@ -7,9 +7,9 @@
 import sys
 import os
 
-from msg import _, msg
-from maker import DependShell
-from plugins import TexModule
+from .msg import _, msg
+from .maker import DependShell
+from .plugins import TexModule
 
 
 class Module (TexModule):
--- lib/dbtexmf/dblatex/grubber/dvips.py	(original)
+++ lib/dbtexmf/dblatex/grubber/dvips.py	(refactored)
@@ -13,9 +13,9 @@
 from os.path import *
 import subprocess
 
-from msg import _ , msg
-from plugins import TexModule
-from maker import Depend
+from .msg import _ , msg
+from .plugins import TexModule
+from .maker import Depend
 
 class Dep (Depend):
     def __init__ (self, doc, target, source, node):
--- lib/dbtexmf/dblatex/grubber/makeidx.py	(original)
+++ lib/dbtexmf/dblatex/grubber/makeidx.py	(refactored)
@@ -24,7 +24,7 @@
 """
 import sys
 
-from index import Index
+from .index import Index
 
 class Module (Index):
     def __init__ (self, doc, dict):
--- lib/dbtexmf/dblatex/grubber/xr-hyper.py	(original)
+++ lib/dbtexmf/dblatex/grubber/xr-hyper.py	(refactored)
@@ -9,9 +9,9 @@
 """
 import os
 
-from msg import _, msg
-from plugins import TexModule
-from latex import Latex
+from .msg import _, msg
+from .plugins import TexModule
+from .latex import Latex
 
 class Module(TexModule):
     def __init__ (self, doc, dict):
@@ -23,7 +23,7 @@
         # remember the engine used to build the main latex document
         self.texmodules = []
         for m in ("pdftex", "xetex"):
-            if doc.modules.has_key(m):
+            if m in doc.modules:
                 self.texmodules.append(m)
 
         # want to track each external document whose .aux is required
--- lib/dbtexmf/dblatex/grubber/bibtex.py	(original)
+++ lib/dbtexmf/dblatex/grubber/bibtex.py	(refactored)
@@ -12,7 +12,7 @@
 """
 
 # Stop python 2.2 from calling "yield" statements syntax errors.
-from __future__ import generators
+
 
 import os, sys
 from os.path import *
@@ -21,8 +21,8 @@
 
 #from grubber import _
 #from grubber import *
-from msg import _, msg
-from plugins import TexModule
+from .msg import _, msg
+from .plugins import TexModule
 
 re_bibdata = re.compile(r"\\bibdata{(?P<data>.*)}")
 re_citation = re.compile(r"\\citation{(?P<cite>.*)}")
@@ -111,7 +111,7 @@
         """
         if self.style:
             old_bst = self.style + ".bst"
-            if exists(old_bst) and self.doc.sources.has_key(old_bst):
+            if exists(old_bst) and old_bst in self.doc.sources:
                 del self.doc.sources[old_bst]
 
         self.style = style
@@ -168,7 +168,7 @@
             return 1
 
         dtime = getmtime(self.blgfile)
-        for db in self.db.values():
+        for db in list(self.db.values()):
             if getmtime(db) > dtime:
                 msg.log(_("bibliography database %s was modified") % db,
                         pkg="bibtex")
@@ -207,7 +207,7 @@
                 m = re_citation.match(line)
                 if m:
                     cite = m.group("cite")
-                    if not cites.has_key(cite):
+                    if cite not in cites:
                         last = last + 1
                         cites[cite] = last
                     continue
@@ -218,11 +218,11 @@
         dbs.sort()
 
         if self.sorted:
-            list = cites.keys()
+            list = list(cites.keys())
             list.sort()
             return list, dbs
         else:
-            list = [(n,c) for (c,n) in cites.items()]
+            list = [(n,c) for (c,n) in list(cites.items())]
             list.sort()
             return [c for (n,c) in list], dbs
 
@@ -235,7 +235,7 @@
             match = re_undef.match(line)
             if match:
                 cites[match.group("cite")] = None
-        list = cites.keys()
+        list = list(cites.keys())
         list.sort()
         return list
 
@@ -400,9 +400,9 @@
                 file = d["file"]
                 if file[-4:] == ".bib":
                     file = file[:-4]
-                if self.db.has_key(file):
+                if file in self.db:
                     d["file"] = self.db[file]
-                elif self.db.has_key(file + ".bib"):
+                elif file + ".bib" in self.db:
                     d["file"] = self.db[file + ".bib"]
                 yield d
             last_line = line
--- lib/dbtexmf/dblatex/grubber/xetex.py	(original)
+++ lib/dbtexmf/dblatex/grubber/xetex.py	(refactored)
@@ -2,7 +2,7 @@
 XeTeX support for Rubber.
 """
 
-from plugins import TexModule
+from .plugins import TexModule
 
 class Module (TexModule):
     def __init__ (self, doc, dict):
--- lib/dbtexmf/dblatex/grubber/pdftex.py	(original)
+++ lib/dbtexmf/dblatex/grubber/pdftex.py	(refactored)
@@ -14,8 +14,8 @@
 import subprocess
 from subprocess import Popen, PIPE
 
-from msg import _, msg
-from plugins import TexModule
+from .msg import _, msg
+from .plugins import TexModule
 
 
 class Module (TexModule):
--- lib/dbtexmf/xslt/xsltproc.py	(original)
+++ lib/dbtexmf/xslt/xsltproc.py	(refactored)
@@ -26,7 +26,7 @@
         if self.use_catalogs and self.catalogs:
             cmd.append("--catalogs")
         if params:
-            for param, value in params.items():
+            for param, value in list(params.items()):
                 cmd += ["--param", param, "'%s'" % value]
         if opts:
             cmd += opts
--- lib/dbtexmf/xslt/xsltconf.py	(original)
+++ lib/dbtexmf/xslt/xsltconf.py	(refactored)
@@ -52,7 +52,7 @@
             return args
 
         param_args = []
-        for param, value in params.items():
+        for param, value in list(params.items()):
             param_args.append(self.param_format % {"param_name": param,
                                                    "param_value": value})
 
--- lib/dbtexmf/xslt/saxon.py	(original)
+++ lib/dbtexmf/xslt/saxon.py	(refactored)
@@ -22,7 +22,7 @@
             cmd += opts
         cmd += [xmlfile, xslfile]
         if params:
-            for param, value in params.items():
+            for param, value in list(params.items()):
                 cmd += ["%s=%s" % (param, "'%s'" % value)]
         self.system(cmd)
 
--- tools/dblatex_config.py	(original)
+++ tools/dblatex_config.py	(refactored)
@@ -104,7 +104,7 @@
     (options, args) = parser.parse_args()
 
     if len(args) != 2:
-        print >> sys.stderr, "Invalid argument count: expected 2"
+        print("Invalid argument count: expected 2", file=sys.stderr)
         parser.parse_args(["-h"])
 
     txt_file = args[0]
--- tools/paramcheck.py	(original)
+++ tools/paramcheck.py	(refactored)
@@ -104,12 +104,12 @@
     sr = set(reffiles)
 
     torem_from_syn = ss - sp
-    print "==========="
-    print "In param list, missing in %s:\n" % (synopdir), sp - ss
-    print "\nIn param list, missing in refentries:\n", sp - sr
-    print "\nIn synopsis, not in param list:\n", torem_from_syn
-    print "\nIn synopsis, missing in refentries:\n", ss - sr - torem_from_syn
-    print "\nIn refentries, missing in %s:\n" % (synopdir), sr - ss
+    print("===========")
+    print("In param list, missing in %s:\n" % (synopdir), sp - ss)
+    print("\nIn param list, missing in refentries:\n", sp - sr)
+    print("\nIn synopsis, not in param list:\n", torem_from_syn)
+    print("\nIn synopsis, missing in refentries:\n", ss - sr - torem_from_syn)
+    print("\nIn refentries, missing in %s:\n" % (synopdir), sr - ss)
 
 
 if __name__ == "__main__":
--- tools/utfdump.py	(original)
+++ tools/utfdump.py	(refactored)
@@ -17,9 +17,9 @@
                 o = encode(uchar)[0]
             except:
                 o = "?"
-            print "U%04X: %s" % (ord(uchar), o)
+            print("U%04X: %s" % (ord(uchar), o))
             outline += o
-        print "Line %3d: %s" % (lineno, outline)
+        print("Line %3d: %s" % (lineno, outline))
 
 
 if __name__ == "__main__":
--- tools/pdfscan.py	(original)
+++ tools/pdfscan.py	(refactored)
@@ -40,7 +40,7 @@
 
     def failure_track(self, msg, rc=1):
         self.rc = rc
-        print >>sys.stderr, (msg)
+        print((msg), file=sys.stderr)
         if self._dump_stack:
             traceback.print_exc()
 
@@ -329,10 +329,10 @@
         self.unresolved = []
 
     def count(self):
-        return len(self.pdfobjects.values())
+        return len(list(self.pdfobjects.values()))
 
     def types(self):
-        return self.objtypes.keys()
+        return list(self.objtypes.keys())
 
     def add_object(self, pdfobject):
         self.pdfobjects[pdfobject.ident()] = pdfobject
@@ -359,7 +359,7 @@
         self.unresolved = unresolved
 
     def stream_decode(self):
-        for pdfobj in self.pdfobjects.values():
+        for pdfobj in list(self.pdfobjects.values()):
             pdfobj.stream_decode()
 
 
@@ -873,10 +873,10 @@
         return self.params.get(param, default)
     
     def values(self):
-        return self.params.values()
+        return list(self.params.values())
 
     def keys(self):
-        return self.params.keys()
+        return list(self.params.keys())
 
     def infos(self):
         return self.params
@@ -889,7 +889,7 @@
 
     def link_to(self, pdfobjects):
         unresolved = 0
-        for param, value in self.params.items():
+        for param, value in list(self.params.items()):
             # Point to something else than a string? Skip it
             if not(isinstance(value, str)):
                 continue
@@ -960,7 +960,7 @@
             shutil.rmtree(self.cache_dirname)
         else:
             for fname in self.cache_files:
-                print "shutil.remove(", fname
+                print("shutil.remove(", fname)
 
     def cache(self, **kwargs):
         if self.cache_method == "file":
@@ -1253,11 +1253,11 @@
 
     def dump(self):
         s = self._level * "  " + "q '" + self._data + "'"
-        print s
+        print(s)
         for q in self._children:
             q.dump()
         s = self._level * "  " + "Q"
-        print s
+        print(s)
 
 
 class PDFTextObject:
@@ -1445,7 +1445,7 @@
             return textdata
         if (self.font.tounicode):
             textdata = self._re_textunicode.findall(self.data)
-            s = u" ".join(self.font.tounicode.decode(textdata))
+            s = " ".join(self.font.tounicode.decode(textdata))
             return self.encode(s, "substitute")[0]
         else:
             return ""
@@ -1456,11 +1456,11 @@
     @classmethod
     def _encode_subs(cls, exc):
         if not isinstance(exc, UnicodeEncodeError):
-            return u""
+            return ""
         l = []
         for c in exc.object[exc.start:exc.end]:
-            l.append(u"&#x%x;" % ord(c))
-        return (u"".join(l), exc.end)
+            l.append("&#x%x;" % ord(c))
+        return ("".join(l), exc.end)
 
 
 class PDFFont:
@@ -1494,7 +1494,7 @@
 
     def get_pdffont(self, fontobj, fontsize):
         key = fontobj.descriptor.get("/BaseFont")+"/"+"%6.2f" % fontsize
-        if self.fontused.has_key(key):
+        if key in self.fontused:
             return self.fontused.get(key)
         elif self.global_fontmgr:
             pdffont = self.global_fontmgr.get_pdffont(fontobj, fontsize)
@@ -1517,7 +1517,7 @@
 
     def _get_tounicode(self, pdfobject):
         key = pdfobject.ident()
-        if self.tounicode.has_key(key):
+        if key in self.tounicode:
             tuc = self.tounicode.get(key)
         else:
             tuc = ToUnicode(pdfobject)
@@ -1531,7 +1531,7 @@
         return self.get_pdffont(fontobj, size)
 
     def get_used(self):
-        return self.fontused.values()
+        return list(self.fontused.values())
 
 
 class ToUnicode(PDFStreamHandler):
@@ -1609,8 +1609,8 @@
         for i in range(0, len(data), 4):
             s = data[i:i+4]
             #print s
-            ul.append(unichr(self.get_uccode(int(s,16))))
-        return u"".join(ul)
+            ul.append(chr(self.get_uccode(int(s,16))))
+        return "".join(ul)
 
     def decode(self, data):
         if isinstance(data, list):
@@ -1696,16 +1696,16 @@
         for page in pdf_pages:
             fonts_used = page.find_fonts()
             fonts_used.sort()
-            print "\nPage %d fonts used:" % page.pagenum
+            print("\nPage %d fonts used:" % page.pagenum)
             for i, font in enumerate(fonts_used):
-                print "[%d] %-40s %6.2f pt" % (i, font.name(),
-                                               self.pt_factor*font.size())
-
-            print "\nPage %d layout:" % page.pagenum
+                print("[%d] %-40s %6.2f pt" % (i, font.name(),
+                                               self.pt_factor*font.size()))
+
+            print("\nPage %d layout:" % page.pagenum)
             content_stream = page.streams[0]
             xp, yp = 0., 0.
-            print self.header
-            print self.headline
+            print(self.header)
+            print(self.headline)
             for textobject in content_stream.textobjects:
                 xp, yp = self._print_textobject_layout(textobject, xp, yp,
                                                        fonts_used)
@@ -1728,7 +1728,7 @@
                         font_line.append(idx)
 
             m2 = line[0].matrix * m2
-            if self.show_matrix: print "%s" % m2
+            if self.show_matrix: print("%s" % m2)
 
             x, y = m2.tx(), m2.ty()
             x, y = float(x/72), float(y/72)
@@ -1742,9 +1742,9 @@
             textw = textwrap.wrap(text, wraplen)
 
             if textw:
-                print "%s%s" % (info, textw[0])
+                print("%s%s" % (info, textw[0]))
                 for txt in textw[1:]:
-                    print "%s%s" % (self.padding, txt)
+                    print("%s%s" % (self.padding, txt))
 
             xp, yp = x, y
             for l in line[1:]:
@@ -1765,9 +1765,9 @@
             page_num = i+page_first
             contents = page.descriptor.get("/Contents")
             resources = page.descriptor.get("/Resources")
-            print "Page %d %s: contents: %s, resources: %s" % \
-                                 (page_num, page, contents, resources)
-        print
+            print("Page %d %s: contents: %s, resources: %s" % \
+                                 (page_num, page, contents, resources))
+        print()
 
 class PdfObjectCmd(BasicCmd):
     """
@@ -1804,8 +1804,8 @@
     def _sanitize_objref(self, ident):
         flds = ident.split()
         if len(flds) != 2:
-            print "Invalid object reference: must be in the form "\
-                  "'number generation'"
+            print("Invalid object reference: must be in the form "\
+                  "'number generation'")
             return ""
         else:
             return "%s %s" % (flds[0], flds[1])
@@ -1813,51 +1813,51 @@
     def show_dictionnary(self, ident):
         pdfobject = self.scanner.pdf.get_object(ident)
         if not(pdfobject):
-            print "PDF Object '%s' not found" % ident
+            print("PDF Object '%s' not found" % ident)
             return
         if pdfobject.stream:
-            print "PDF Object '%s' has a stream. Its dictionnary:" % ident
+            print("PDF Object '%s' has a stream. Its dictionnary:" % ident)
         else:
-            print "PDF Object '%s' dictionnary:" % ident
+            print("PDF Object '%s' dictionnary:" % ident)
         self._print_dictionnary(pdfobject.descriptor)
 
     def _print_dictionnary(self, descriptor, level=1):
         indent = "  "*level
-        print "%s<<" % indent
-        for p, v in descriptor.infos().items():
+        print("%s<<" % indent)
+        for p, v in list(descriptor.infos().items()):
             if isinstance(v, PDFDescriptor):
-                print "%s%s:" % (indent, p)
+                print("%s%s:" % (indent, p))
                 self._print_dictionnary(v, level=level+1)
             else:
-                print "%s%s: %s" % (indent, p, v)
-        print "%s>>" % indent
+                print("%s%s: %s" % (indent, p, v))
+        print("%s>>" % indent)
 
     def list_pdfobjects(self):
         pdfobjects = self.scanner.pdf.pdfobjects
-        print "Found %s PDFObjects" % pdfobjects.count()
-        print "Found the following PDFObject types:"
+        print("Found %s PDFObjects" % pdfobjects.count())
+        print("Found the following PDFObject types:")
         types = pdfobjects.types()
         types.sort()
         total = 0
         for typ in types:
             n_type = len(pdfobjects.get_objects_by_type(typ))
-            print " %20s: %5d objects" % (typ, n_type)
+            print(" %20s: %5d objects" % (typ, n_type))
             total = total + n_type
-        print " %20s: %5d objects" % ("TOTAL", total)
+        print(" %20s: %5d objects" % ("TOTAL", total))
 
     def dump_stream(self, ident, outfile):
         pdfobject = self.scanner.pdf.get_object(ident)
         if not(pdfobject):
-            print "PDF Object '%s' not found" % ident
+            print("PDF Object '%s' not found" % ident)
             return
         if not(pdfobject.stream):
-            print "PDF Object '%s' has no stream. Give up." % ident
+            print("PDF Object '%s' has no stream. Give up." % ident)
             return
         pdfobject.stream_decode()
         f = open(outfile, "wb")
         f.write(pdfobject.stream_text())
         f.close()
-        print "PDF Object '%s' stream written to file %s" % (ident, outfile)
+        print("PDF Object '%s' stream written to file %s" % (ident, outfile))
 
 
 
@@ -1895,17 +1895,17 @@
 
     def print_fonts_in_pages(self, pdf_pages, show=True):
         if show:
-            print self.header_fmt % ("PAGE", "FONT", "SIZE")
-            print self.header_fmt % (4*"-", 40*"-", 10*"-")
+            print(self.header_fmt % ("PAGE", "FONT", "SIZE"))
+            print(self.header_fmt % (4*"-", 40*"-", 10*"-"))
 
         for page in pdf_pages:
             fonts_used = page.find_fonts()
             fonts_used.sort()
             for font in fonts_used:
                 if show:
-                    print "%4d %-40s %6.2f %s" % (page.pagenum, font.name(),
-                              self.pt_factor * font.size(), self.font_unit)
-            if show: print self.header_fmt % (4*"-", 40*"-", 10*"-")
+                    print("%4d %-40s %6.2f %s" % (page.pagenum, font.name(),
+                              self.pt_factor * font.size(), self.font_unit))
+            if show: print(self.header_fmt % (4*"-", 40*"-", 10*"-"))
 
     def print_font_summary(self):
         pages = []
@@ -1917,12 +1917,12 @@
                 s += "-%d" % (pg[-1].pagenum)
             pages.append(s)
 
-        print "\nFonts used in pages %s:" % (",".join(pages))
+        print("\nFonts used in pages %s:" % (",".join(pages)))
         fonts_used = self.scanner.pdf.fontmgr.get_used()
         fonts_used.sort()
         for font in fonts_used:
-            print "%-40s %6.2f %s" % \
-                  (font.name(), self.pt_factor*font.size(), self.font_unit)
+            print("%-40s %6.2f %s" % \
+                  (font.name(), self.pt_factor*font.size(), self.font_unit))
 
 
 class PDFScannerCommand:
@@ -2067,11 +2067,11 @@
         if not(verbose):
             return log_groups
 
-        groups = log_groups.keys()
+        groups = list(log_groups.keys())
         for verbose_opt in verbose:
             group, level = ("all:" + verbose_opt).split(":")[-2:]
             if not(level in log_levels):
-                print "Invalid verbose level: '%s'" % level
+                print("Invalid verbose level: '%s'" % level)
                 continue
             if group == "all":
                 for group in groups:
@@ -2079,7 +2079,7 @@
             elif group in groups:
                 log_groups[group] = level
             else:
-                print "Invalid verbose group: '%s'" % group
+                print("Invalid verbose group: '%s'" % group)
                 continue
         return log_groups
 
@@ -2108,8 +2108,8 @@
         elif cache_dirname:
             cache_dirname = os.path.realpath(cache_dirname)
             if not(os.path.exists(cache_dirname)):
-                print "Invalid cache dir: '%s'. Temporary dir used instead" % \
-                      cache_dirname
+                print("Invalid cache dir: '%s'. Temporary dir used instead" % \
+                      cache_dirname)
                 return None
             mgr = StreamManager(cache_method="file",
                                 cache_dirname=cache_dirname,
@@ -2129,7 +2129,7 @@
         fmt = logging.Formatter("%(message)s")
         console.setFormatter(fmt)
 
-        for group, level in log_groups.items():
+        for group, level in list(log_groups.items()):
             log = logging.getLogger("pdfscan.%s" % group)
             log.setLevel(loglevels.get(level, logging.INFO)-1)
             log.addHandler(console)
@@ -2154,7 +2154,7 @@
         argslist.append(args)
 
     if not(remain_args) or remain_args[0] in scanner.commands():
-        print "Missing the PDF File"
+        print("Missing the PDF File")
         parser.parse_args(["-h"])
 
     error = ErrorHandler()
@@ -2163,7 +2163,7 @@
     try:
         pdffile = remain_args[0]
         scanner.run(parser, options, argslist, pdffile)
-    except Exception, e:
+    except Exception as e:
         error.failure_track("Error: '%s'" % (e))
 
     scanner.cleanup()
