--- setup.py	(original)
+++ setup.py	(refactored)
@@ -83,7 +83,7 @@
         self._catalogs = install.catalogs
         self._style = install.style
         self._use_py_path = install.use_python_path
-        print self._package_base
+        print(self._package_base)
 
         # Build the command line script
         self.build_script()
@@ -162,7 +162,7 @@
         script = self.SHELL_SCRIPT % script_args
         script_name = os.path.basename(script_name)
         outfile = os.path.join(self.build_dir, script_name)
-        fd = os.open(outfile, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0755)
+        fd = os.open(outfile, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0o755)
         os.write(fd, script)
         os.close(fd)
 
@@ -260,19 +260,19 @@
         # First, check non critical graphic tools
         found, missed = find_programs(("epstopdf", "convert", "fig2dev"))
         for util in found:
-            print "+checking %s... yes" % util
+            print("+checking %s... yes" % util)
         for util in missed:
-            print "+checking %s... no" % util
+            print("+checking %s... no" % util)
         if missed:
-            print("warning: not found: %s" % ", ".join(missed))
+            print(("warning: not found: %s" % ", ".join(missed)))
 
         # Now, be serious
         found, missed = find_programs(("latex", "makeindex",
                                        "pdflatex", "kpsewhich"))
         for util in found:
-            print "+checking %s... yes" % util
+            print("+checking %s... yes" % util)
         for util in missed:
-            print "+checking %s... no" % util
+            print("+checking %s... no" % util)
         if missed:
             raise OSError("not found: %s" % ", ".join(missed))
 
@@ -292,21 +292,21 @@
         for (mod, deplist) in deplists:
             if not(deplist):
                 xslt_found.append(mod)
-                print "+checking XSLT %s... yes" % mod
+                print("+checking XSLT %s... yes" % mod)
                 continue
             found, missed = find_programs(deplist)
             if missed:
                 xslt_missed.append(mod)
-                print "+checking XSLT %s... no (missing %s)" % \
-                      (mod, ", ".join(missed))
+                print("+checking XSLT %s... no (missing %s)" % \
+                      (mod, ", ".join(missed)))
             else:
                 xslt_found.append(mod)
-                print "+checking XSLT %s... yes" % mod
+                print("+checking XSLT %s... yes" % mod)
 
         if not(xslt_found):
             raise OSError("XSLT not installed: %s" % ", ".join(xslt_missed))
         elif xslt_missed:
-            print "warning: XSLT not found: %s" % ", ".join(xslt_missed)
+            print("warning: XSLT not found: %s" % ", ".join(xslt_missed))
 
     def check_latex_dependencies(self):
         # Find the Latex files from the package
@@ -353,7 +353,7 @@
             if sty in own_stys:
                 status += "found in package"
                 found_stys.append(sty)
-                print status
+                print(status)
                 continue
             stypath = kpsewhich("%s.sty" % sty)
             if stypath:
@@ -362,7 +362,7 @@
             else:
                 status += "no"
                 mis_stys.append(sty)
-            print status
+            print(status)
             
         if mis_stys:
             raise OSError("not found: %s" % ", ".join(mis_stys))
@@ -378,8 +378,8 @@
                 self.check_xslt_dependencies()
                 self.check_util_dependencies()
                 self.check_latex_dependencies()
-            except Exception, e:
-                print >>sys.stderr, "Error: %s" % e
+            except Exception as e:
+                print("Error: %s" % e, file=sys.stderr)
                 sys.exit(1)
 
         if db: db.adapt_paths()
--- lib/dbtexmf/core/dbtex.py	(original)
+++ lib/dbtexmf/core/dbtex.py	(refactored)
@@ -8,7 +8,7 @@
 import shlex
 import tempfile
 import shutil
-import urllib
+import urllib.request, urllib.parse, urllib.error
 import glob
 import imp
 from optparse import OptionParser
@@ -29,9 +29,9 @@
 
 def path_to_uri(path):
     if os.name == 'nt':
-        return 'file:' + urllib.pathname2url(path).replace('|', ':', 1)
+        return 'file:' + urllib.request.pathname2url(path).replace('|', ':', 1)
     else:
-        return urllib.pathname2url(path)
+        return urllib.request.pathname2url(path)
 
 
 class Document:
@@ -395,7 +395,7 @@
         self.update_texinputs()
 
         # For easy debug
-        if self.debug and os.environ.has_key("TEXINPUTS"):
+        if self.debug and "TEXINPUTS" in os.environ:
             if os.name != "nt":
                 f = file("env_tex", "w")
                 f.write("TEXINPUTS=%s\nexport TEXINPUTS\n" % \
@@ -544,13 +544,13 @@
         if options.format:
             try:
                 run.set_format(options.format)
-            except Exception, e:
+            except Exception as e:
                 failed_exit("Error: %s" % e)
 
         # Always set the XSLT (default or not)
         try:
             run.set_xslt(options.xslt)
-        except Exception, e:
+        except Exception as e:
             failed_exit("Error: %s" % e)
 
         if options.xslopts:
@@ -575,7 +575,7 @@
         if options.texstyle:
             try:
                 xslparam, texpath = texstyle_parse(options.texstyle)
-            except Exception, e:
+            except Exception as e:
                 failed_exit("Error: %s" % e)
             run.xslparams.append(xslparam)
             if texpath: run.texinputs.append(texpath)
@@ -630,7 +630,7 @@
             if not(os.path.exists(options.tmpdir)):
                 try:
                     os.mkdir(options.tmpdir)
-                except Exception, e:
+                except Exception as e:
                     failed_exit("Error: %s" % e)
             run.tmpdir_user = os.path.abspath(options.tmpdir)
 
@@ -665,7 +665,7 @@
 
         if options.version:
             version = run.get_version()
-            print "%s version %s" % (self.prog, version)
+            print("%s version %s" % (self.prog, version))
             if not(args):
                 sys.exit(0)
 
@@ -682,14 +682,14 @@
             try:
                 conf.paths = self.get_config_paths()
                 conf.fromstyle(options.style)
-            except Exception, e:
+            except Exception as e:
                 failed_exit("Error: %s" % e)
             
         if options.config:
             try:
                 for config in options.config:
                     conf.fromfile(config)
-            except Exception, e:
+            except Exception as e:
                 failed_exit("Error: %s" % e)
 
         if conf.options:
@@ -735,7 +735,7 @@
         # Try to buid the file
         try:
             run.compile()
-        except Exception, e:
+        except Exception as e:
             signal_error(self, e)
             failed_exit("Error: %s" % e)
 
--- lib/dbtexmf/core/confparser.py	(original)
+++ lib/dbtexmf/core/confparser.py	(refactored)
@@ -1,11 +1,11 @@
 import os
 import sys
 from xml.etree.ElementTree import ParseError
-from xmlparser import XmlConfig
-from txtparser import TextConfig
-from imagedata import ImageConverterPool, ImageConverter
-from imagedata import ImageFormatPool, FormatRule
-from imagedata import image_setup
+from .xmlparser import XmlConfig
+from .txtparser import TextConfig
+from .imagedata import ImageConverterPool, ImageConverter
+from .imagedata import ImageFormatPool, FormatRule
+from .imagedata import image_setup
 from dbtexmf.xslt.xsltconf import XsltCommandPool, XsltEngine
 from dbtexmf.xslt import xslt_setup
 
@@ -76,16 +76,16 @@
         self.style_exts = ["", ".xml", ".specs", ".conf"]
 
     def warn(self, text):
-        print >>sys.stderr, text
+        print(text, file=sys.stderr)
 
     def fromfile(self, filename):
         try:
             self.fromxmlfile(filename)
-        except ParseError, e:
+        except ParseError as e:
             self.warn("Text configuration files are deprecated. "\
                       "Use the XML format instead")
             self.fromtxtfile(filename)
-        except Exception, e:
+        except Exception as e:
             raise e
 
     def fromxmlfile(self, filename):
--- lib/dbtexmf/core/xmlparser.py	(original)
+++ lib/dbtexmf/core/xmlparser.py	(refactored)
@@ -1,7 +1,7 @@
 import os
 import re
 import xml.etree.ElementTree as ET
-from txtparser import texinputs_parse
+from .txtparser import texinputs_parse
 
 class BaseOption:
     def __init__(self, config, optname):
@@ -207,14 +207,14 @@
 
     def options(self):
         opts = []
-        for parsers in self.infos.values():
+        for parsers in list(self.infos.values()):
             for parser in parsers:
                 opts.extend(parser.options())
         return opts
 
     def modules(self):
         mods = {}
-        for parsers in self.infos.values():
+        for parsers in list(self.infos.values()):
             for parser in parsers:
                 mods.update(parser.modules())
         return mods
@@ -282,13 +282,13 @@
 
     def options(self):
         opts = []
-        for parser in self.infos.values():
+        for parser in list(self.infos.values()):
             opts.extend(parser.options())
         return opts
 
     def modules(self):
         mods = {}
-        for parser in self.infos.values():
+        for parser in list(self.infos.values()):
             mods.update(parser.modules())
         return mods
 
--- lib/dbtexmf/core/imagedata.py	(original)
+++ lib/dbtexmf/core/imagedata.py	(refactored)
@@ -3,9 +3,9 @@
 import re
 import shutil
 import logging
-import urllib
+import urllib.request, urllib.parse, urllib.error
 from dbtexmf.core.error import signal_error
-from commander import CommandRunner
+from .commander import CommandRunner
 
 class ObjectFilter:
     """
@@ -26,13 +26,13 @@
         return "("+searched+")"
 
     def select(self, object_list, **filter_criterions):
-        for criterion, value in filter_criterions.items():
+        for criterion, value in list(filter_criterions.items()):
             filter_criterions[criterion] = self._re_multi_or_star(value)
 
         founds = []
         for obj in object_list:
             object_criterions = obj.criterions()
-            for criterion, re_expr in filter_criterions.items():
+            for criterion, re_expr in list(filter_criterions.items()):
                 data = object_criterions.get(criterion, "")
                 m = re.search(re_expr, data)
                 #print "Lookup2:", criterion, re_expr, data, not(m is None)
@@ -259,7 +259,7 @@
 
     def convert(self, fig):
         # Translate the URL to an actual local path
-        fig = urllib.url2pathname(fig)
+        fig = urllib.request.url2pathname(fig)
 
         # Always use '/' in path: work even on windows and is required by tex
         if os.path.sep != '/': fig = fig.replace(os.path.sep, '/')
@@ -273,7 +273,7 @@
             return fig
 
         # Check if this image has been already converted
-        if self.converted.has_key(realfig):
+        if realfig in self.converted:
             self.log.info("Image '%s' already converted as %s" % \
                   (fig, self.converted[realfig]))
             return self.converted[realfig]
--- lib/dbtexmf/dblatex/dblatex.py	(original)
+++ lib/dbtexmf/dblatex/dblatex.py	(refactored)
@@ -7,8 +7,8 @@
 from dbtexmf.core.sgmlxml import Osx
 from dbtexmf.core.dbtex import DbTex, DbTexCommand
 
-from rawtex import RawLatex
-from runtex import RunLatex
+from .rawtex import RawLatex
+from .runtex import RunLatex
 
 
 class DbLatex(DbTex):
--- lib/dbtexmf/dblatex/rawtex.py	(original)
+++ lib/dbtexmf/dblatex/rawtex.py	(refactored)
@@ -8,10 +8,10 @@
 import os
 import re
 
-from rawparse import RawLatexParser, RawUtfParser
-from rawverb import VerbParser
-from rawlabel import RawLabelParser
-from xetex.codec import XetexCodec
+from .rawparse import RawLatexParser, RawUtfParser
+from .rawverb import VerbParser
+from .rawlabel import RawLabelParser
+from .xetex.codec import XetexCodec
 from dbtexmf.core.imagedata import *
 
 
--- lib/dbtexmf/dblatex/rawparse.py	(original)
+++ lib/dbtexmf/dblatex/rawparse.py	(refactored)
@@ -1,7 +1,7 @@
 import re
 
-from texcodec import LatexCodec, TexCodec
-from texhyphen import BasicHyphenator, UrlHyphenator
+from .texcodec import LatexCodec, TexCodec
+from .texhyphen import BasicHyphenator, UrlHyphenator
 
 
 def utf8(u):
@@ -16,7 +16,7 @@
 
 class RawLatexParser:
     def __init__(self,
-                 key_in=utf8(u"\u0370t"), key_out=utf8(u"\u0371t"),
+                 key_in=utf8("\u0370t"), key_out=utf8("\u0371t"),
                  codec=None, output_encoding="latin-1"):
         self.key_in = RawKey(key_in, 1)
         self.key_out = RawKey(key_out, -1)
@@ -27,8 +27,8 @@
         self.hyphenator = UrlHyphenator(codec=self.codec)
         
         # hyphenation patterns
-        self.hypon = re.compile(utf8(u"\u0370h"))
-        self.hypof = re.compile(utf8(u"\u0371h"))
+        self.hypon = re.compile(utf8("\u0370h"))
+        self.hypof = re.compile(utf8("\u0371h"))
 
     def parse(self, line):
         lout = ""
@@ -79,7 +79,7 @@
 
     def __init__(self, codec=None, output_encoding="latin-1"):
         texcodec = codec or TexCodec(output_encoding=output_encoding)
-        RawLatexParser.__init__(self, utf8(u"\u0370u"), utf8(u"\u0371u"),
+        RawLatexParser.__init__(self, utf8("\u0370u"), utf8("\u0371u"),
                                 texcodec)
 
     def translate(self, text):
--- lib/dbtexmf/dblatex/texcodec.py	(original)
+++ lib/dbtexmf/dblatex/texcodec.py	(refactored)
@@ -4,7 +4,7 @@
 #
 import re
 import codecs
-import unient
+from . import unient
 
 # Dictionnary of the handlers installed
 tex_handler_installed = {}
@@ -21,12 +21,12 @@
         try:
             l.append(unient.unicode_map[ord(c)])
         except KeyError:
-            print "Missing character &#x%x;" % ord(c)
-            l.append(u"\&\#x%x;" % ord(c))
+            print("Missing character &#x%x;" % ord(c))
+            l.append("\&\#x%x;" % ord(c))
         if post: l.append(post)
         n = n + 1
     tex_handler_counter[name] = n
-    return (u"".join(l), exc.end)
+    return ("".join(l), exc.end)
 
 
 class TexCodec:
@@ -63,7 +63,7 @@
             self.charmap = {}
             return
 
-        if not(tex_handler_installed.has_key(self._errors)):
+        if not(self._errors in tex_handler_installed):
             f = self.build_error_func(pre, post, errors)
             codecs.register_error(self._errors, f)
             tex_handler_installed[self._errors] = f
@@ -83,7 +83,7 @@
 
     def encode(self, text):
         text = self._encode(text, self._errors)[0]
-        for c, v in self.charmap.items():
+        for c, v in list(self.charmap.items()):
             text = text.replace(c, v)
         return text
  
@@ -120,7 +120,7 @@
         text = self._encode(text, self._errors)[0]
 
         # Special Character Mapping
-        for c, v in self.charmap.items():
+        for c, v in list(self.charmap.items()):
             text = text.replace(c, v)
 
         # Things are done, complete with {}
--- lib/dbtexmf/dblatex/texhyphen.py	(original)
+++ lib/dbtexmf/dblatex/texhyphen.py	(refactored)
@@ -96,5 +96,5 @@
     url = "http://www.fg/foobar fun#fght/fkkkf.tz?id=123"
     h1 = BasicHyphenator()
     h2 = UrlHyphenator()
-    print h1.hyphenate(url)
-    print h2.hyphenate(url)
+    print(h1.hyphenate(url))
+    print(h2.hyphenate(url))
--- lib/dbtexmf/dblatex/rawverb.py	(original)
+++ lib/dbtexmf/dblatex/rawverb.py	(refactored)
@@ -11,9 +11,9 @@
 #
 import re
 
-from texcodec import TexCodec
-from texcodec import tex_handler_counter
-from rawparse import RawUtfParser
+from .texcodec import TexCodec
+from .texcodec import tex_handler_counter
+from .rawparse import RawUtfParser
 
 
 class VerbCodec(TexCodec):
--- lib/dbtexmf/dblatex/rawlabel.py	(original)
+++ lib/dbtexmf/dblatex/rawlabel.py	(refactored)
@@ -1,6 +1,6 @@
-from texcodec import TexCodec
-from texcodec import tex_handler_counter
-from rawparse import RawLatexParser, utf8
+from .texcodec import TexCodec
+from .texcodec import tex_handler_counter
+from .rawparse import RawLatexParser, utf8
 
 
 def label_char_replace(exc, pre, post, errors):
@@ -16,7 +16,7 @@
         if post: l.append(post)
         n = n + 1
     tex_handler_counter[errors] = n
-    return (u"".join(l), exc.end)
+    return ("".join(l), exc.end)
 
 
 class LabelCodec(TexCodec):
@@ -60,7 +60,7 @@
     """
     def __init__(self, codec=None, output_encoding="latin-1"):
         texcodec = codec or LabelCodec(output_encoding=output_encoding)
-        RawLatexParser.__init__(self, utf8(u"\u0370l"), utf8(u"\u0371l"),
+        RawLatexParser.__init__(self, utf8("\u0370l"), utf8("\u0371l"),
                                 texcodec)
 
     def translate(self, text):
--- lib/dbtexmf/dblatex/xetex/codec.py	(original)
+++ lib/dbtexmf/dblatex/xetex/codec.py	(refactored)
@@ -3,7 +3,7 @@
 import codecs
 
 from dbtexmf.dblatex.texcodec import LatexCodec
-from fsencoder import FontSpecEncoder
+from .fsencoder import FontSpecEncoder
 
 
 class XetexCodec(LatexCodec):
--- lib/dbtexmf/dblatex/xetex/fsencoder.py	(original)
+++ lib/dbtexmf/dblatex/xetex/fsencoder.py	(refactored)
@@ -11,8 +11,8 @@
 import re
 import xml.dom.minidom
 
-from fontspec import UnicodeInterval
-from fsconfig import FontSpecConfig
+from .fontspec import UnicodeInterval
+from .fsconfig import FontSpecConfig
 
 
 class FontSpecEncoder:
@@ -68,7 +68,7 @@
         """
         fontspec = self._cur_fontspec or self._conf.default_fontspec
 
-        print >>sys.stderr, "Current:", fontspec.id
+        print("Current:", fontspec.id, file=sys.stderr)
         fontspec = fontspec.match(char)
         while not(fontspec):
             leaf = self._ref_stack.pop()
--- lib/dbtexmf/dblatex/xetex/fontspec.py	(original)
+++ lib/dbtexmf/dblatex/xetex/fontspec.py	(refactored)
@@ -49,7 +49,7 @@
         if m:
             return int(m.group(1), 16)
         else:
-            raise RuntimeError, 'Not a unicode codepoint: ' + codepoint
+            raise RuntimeError('Not a unicode codepoint: ' + codepoint)
 
     def from_char(self, char):
         """Interval for a single character"""
@@ -167,7 +167,7 @@
                     intervals.append(
                         UnicodeInterval().from_codepoint(m.group(1)))
                 else:
-                    raise RuntimeError, 'Unable to parse range: "' + range + '"'
+                    raise RuntimeError('Unable to parse range: "' + range + '"')
         return intervals
 
     def _parse_transitions(self, node, transition_type):
@@ -194,7 +194,7 @@
         specified font types.
         """
         s = ''
-        for type, font in fonts.items():
+        for type, font in list(fonts.items()):
             s += '\switch%sfont{%s}' % (type, font)
         if s:
             s = r"\savefamily" + s + r"\loadfamily{}"
--- lib/dbtexmf/dblatex/xetex/fsconfig.py	(original)
+++ lib/dbtexmf/dblatex/xetex/fsconfig.py	(refactored)
@@ -12,8 +12,8 @@
 import xml.dom.minidom
 import logging
 
-from fcfallback import FcFallbackFontSpec, DefaultFontSpec
-from fontspec import FontSpec, _indent
+from .fcfallback import FcFallbackFontSpec, DefaultFontSpec
+from .fontspec import FontSpec, _indent
 
 
 class FontSpecConfig:
--- lib/dbtexmf/dblatex/xetex/fcfallback.py	(original)
+++ lib/dbtexmf/dblatex/xetex/fcfallback.py	(refactored)
@@ -1,5 +1,5 @@
-from fontspec import FontSpec
-from fcmanager import FcManager
+from .fontspec import FontSpec
+from .fcmanager import FcManager
 
 
 class DefaultFontSpec(FontSpec):
@@ -54,8 +54,8 @@
         for fontspec in self.fontspecs:
 
             if fontspec in self.fcmissed:
-                print "Specified font '%s' is missing in the system!" % \
-                      (fontspec.mainfont())
+                print("Specified font '%s' is missing in the system!" % \
+                      (fontspec.mainfont()))
                 continue
 
             fcfont = self.fccache.get(fontspec.mainfont()) or \
@@ -97,7 +97,7 @@
         fontspec.add_char(char)
         fontspec.add_ignored(self._ignored)
         # Register the font and its related fontconfig object
-        for fcfont in fcfonts.values():
+        for fcfont in list(fcfonts.values()):
             self.fccache[fcfont.name] = fcfont
         self.add_subfont(fontspec)
         return fontspec
--- lib/dbtexmf/dblatex/runtex.py	(original)
+++ lib/dbtexmf/dblatex/runtex.py	(refactored)
@@ -5,7 +5,7 @@
 import re
 import shutil
 
-from grubber.texbuilder import LatexBuilder
+from .grubber.texbuilder import LatexBuilder
 
 
 class RunLatex:
--- lib/dbtexmf/dblatex/grubber/texbuilder.py	(original)
+++ lib/dbtexmf/dblatex/grubber/texbuilder.py	(refactored)
@@ -9,9 +9,9 @@
 import subprocess
 import os
 import shlex
-from msg import _, msg
-from maker import Maker
-from latex import Latex
+from .msg import _, msg
+from .maker import Maker
+from .latex import Latex
 
 
 class IndexBuilder:
@@ -90,7 +90,7 @@
         self.tex.prepare()
 
         # Set the index configuration
-        if self.tex.modules.has_key("makeidx"):
+        if "makeidx" in self.tex.modules:
             idx = self.tex.modules["makeidx"]
             if self.index.style: idx.do_style(self.index.style)
             if self.index.tool: idx.do_tool(self.index.tool)
--- lib/dbtexmf/dblatex/grubber/msg.py	(original)
+++ lib/dbtexmf/dblatex/grubber/msg.py	(refactored)
@@ -37,9 +37,9 @@
             self.stdout = None
 
     def write_stdout(self, text, level=0):
-        print text
+        print(text)
     def write_stderr(self, text, level=0):
-        print >>sys.stderr, text
+        print(text, file=sys.stderr)
 
     def push_pos (self, pos):
         self.pos.append(pos)
@@ -66,7 +66,7 @@
             if text[0:13] == "LaTeX Error: ":
                 text = text[13:]
             self._log.error(self.format_pos(info, text))
-            if info.has_key("code") and info["code"] and not self.short:
+            if "code" in info and info["code"] and not self.short:
                 self._log.error(self.format_pos(info,
                     _("leading text: ") + info["code"]))
 
@@ -100,24 +100,24 @@
         the dictionary given as first argument.
         """
         if len(self.pos) > 0:
-            if where is None or not where.has_key("file"):
+            if where is None or "file" not in where:
                 where = self.pos[-1]
         elif where is None or where == {}:
             return text
 
-        if where.has_key("file") and where["file"] is not None:
+        if "file" in where and where["file"] is not None:
             pos = self.simplify(where["file"])
-            if where.has_key("line") and where["line"]:
+            if "line" in where and where["line"]:
                 pos = "%s:%d" % (pos, int(where["line"]))
-                if where.has_key("last"):
+                if "last" in where:
                     if where["last"] != where["line"]:
                         pos = "%s-%d" % (pos, int(where["last"]))
             pos = pos + ": "
         else:
             pos = ""
-        if where.has_key("page"):
+        if "page" in where:
             text = "%s (page %d)" % (text, int(where["page"]))
-        if where.has_key("pkg"):
+        if "pkg" in where:
             text = "[%s] %s" % (where["pkg"], text)
         return pos + text
 
--- lib/dbtexmf/dblatex/grubber/maker.py	(original)
+++ lib/dbtexmf/dblatex/grubber/maker.py	(refactored)
@@ -8,7 +8,7 @@
 import time
 import subprocess
 
-from msg import _, msg
+from .msg import _, msg
 
 class Depend (object): #{{{2
     """
@@ -51,7 +51,7 @@
                 # We set the node's date to that of the most recently modified
                 # product file, assuming all other files were up to date then
                 # (though not necessarily modified).
-                self.date = max(map(os.path.getmtime, self.prods))
+                self.date = max(list(map(os.path.getmtime, self.prods)))
             except OSError:
                 # If some product file does not exist, set the last
                 # modification date to None.
@@ -64,7 +64,7 @@
         """
         if not self.date:
             return 1
-        for src in self.sources.values():
+        for src in list(self.sources.values()):
             if src.date > self.date:
                 return 1
         return 0
@@ -81,14 +81,14 @@
           on this one have to be remade)
         """
         if self.making:
-            print "FIXME: cyclic make"
+            print("FIXME: cyclic make")
             return 1
         self.making = 1
 
         # Make the sources
         self.failed_dep = None
         must_make = force
-        for src in self.sources.values():
+        for src in list(self.sources.values()):
             ret = src.make()
             if ret == 0:
                 self.making = 0
@@ -152,7 +152,7 @@
             if os.path.exists(file):
                 msg.log(_("removing %s") % file)
                 os.unlink(file)
-        for src in self.sources.values():
+        for src in list(self.sources.values()):
             src.clean()
         self.date = None
 
@@ -170,7 +170,7 @@
         if self.sources == {}:
             return self.prods
         ret = []
-        for dep in self.sources.values():
+        for dep in list(self.sources.values()):
             ret.extend(dep.leaves())
         return ret
 
--- lib/dbtexmf/dblatex/grubber/latex.py	(original)
+++ lib/dbtexmf/dblatex/grubber/latex.py	(refactored)
@@ -11,12 +11,12 @@
 import time
 import subprocess
 
-from msg import _, msg
-from util import Watcher
-from logparser import LogParser
-from texparser import TexParser
-from plugins import Modules
-from maker import Depend
+from .msg import _, msg
+from .util import Watcher
+from .logparser import LogParser
+from .texparser import TexParser
+from .plugins import Modules
+from .maker import Depend
 
 
 class Latex(Depend):
@@ -175,7 +175,7 @@
             self.watcher.watch(self.srcbase + "." + ext)
 
         msg.log(_("building additional files..."))
-        for mod in self.modules.objects.values():
+        for mod in list(self.modules.objects.values()):
             if mod.pre_compile():
                 self.failed_module = mod
                 return 1
@@ -188,7 +188,7 @@
         """
         msg.log(_("running post-compilation scripts..."))
 
-        for mod in self.modules.objects.values():
+        for mod in list(self.modules.objects.values()):
             if mod.post_compile():
                 self.failed_module = mod
                 return 1
@@ -201,7 +201,7 @@
         """
         msg.log(_("running last-compilation scripts..."))
 
-        for mod in self.modules.objects.values():
+        for mod in list(self.modules.objects.values()):
             if mod.last_compile():
                 self.failed_module = mod
                 return 1
@@ -233,7 +233,7 @@
         # for dep in self.sources.values():
         #     dep.clean()
 
-        for mod in self.modules.objects.values():
+        for mod in list(self.modules.objects.values()):
             mod.clean()
 
     def remove_suffixes (self, list):
--- lib/dbtexmf/dblatex/grubber/util.py	(original)
+++ lib/dbtexmf/dblatex/grubber/util.py	(refactored)
@@ -11,7 +11,7 @@
     # Fallback for python 2.4:
     import md5 as hashlib
 import os
-from msg import _, msg
+from .msg import _, msg
 
 
 def md5_file(fname):
@@ -45,7 +45,7 @@
         of the files that changed, or None of they didn't change.
         """
         changed = []
-        for file in self.files.keys():
+        for file in list(self.files.keys()):
             if os.path.exists(file):
                 new = md5_file(file)
                 if self.files[file] != new:
--- lib/dbtexmf/dblatex/grubber/logparser.py	(original)
+++ lib/dbtexmf/dblatex/grubber/logparser.py	(refactored)
@@ -5,11 +5,11 @@
 
 This module defines the class that parses the LaTeX log files.
 """
-from __future__ import generators
+
 
 import re
 
-from msg import _, msg
+from .msg import _, msg
 
 class LogParser:
     """
@@ -188,7 +188,7 @@
                         m = self.re_ignored.search(error)
                         if m:
                             d["file"] = last_file
-                            if d.has_key("code"):
+                            if "code" in d:
                                 del d["code"]
                             d.update( m.groupdict() )
                         elif pos[-1] is None:
--- lib/dbtexmf/dblatex/grubber/plugins.py	(original)
+++ lib/dbtexmf/dblatex/grubber/plugins.py	(refactored)
@@ -7,7 +7,7 @@
 import imp
 
 from os.path import *
-from msg import _, msg
+from .msg import _, msg
 
 import sys
 
@@ -106,7 +106,7 @@
         dictionary. Return 0 if no module was found, 1 if a module was found
         and loaded, and 2 if the module was found but already loaded.
         """
-        if self.modules.has_key(name):
+        if name in self.modules:
             return 2
         try:
             file, path, descr = imp.find_module(name, [""])
@@ -155,7 +155,7 @@
         """
         Check if a given module is loaded.
         """
-        return self.objects.has_key(name)
+        return name in self.objects
 
     def register (self, name, dict={}):
         """
@@ -165,7 +165,7 @@
         delayed commands for this module. The dictionary describes the
         command that caused the registration.
         """
-        if self.has_key(name):
+        if name in self:
             msg.debug(_("module %s already registered") % name)
             return 2
 
@@ -191,7 +191,7 @@
 
         # Run any delayed commands.
 
-        if self.commands.has_key(name):
+        if name in self.commands:
             for (cmd, args, vars) in self.commands[name]:
                 msg.push_pos(vars)
                 try:
@@ -219,10 +219,10 @@
         Send a command to a particular module. If this module is not loaded,
         store the command so that it will be sent when the module is register.
         """
-        if self.objects.has_key(mod):
+        if mod in self.objects:
             self.objects[mod].command(cmd, args)
         else:
-            if not self.commands.has_key(mod):
+            if mod not in self.commands:
                 self.commands[mod] = []
             self.commands[mod].append((cmd, args, self.env.vars.copy()))
 
--- lib/dbtexmf/core/dbtex.py	(original)
+++ lib/dbtexmf/core/dbtex.py	(refactored)
@@ -183,7 +183,7 @@
         self.flags &= ~what
 
     def get_version(self):
-        f = file(os.path.join(self.topdir, "xsl", "version.xsl"))
+        f = open(os.path.join(self.topdir, "xsl", "version.xsl"))
         versions = re.findall("<xsl:variable[^>]*>([^<]*)<", f.read())
         f.close()
         if versions:
@@ -196,7 +196,7 @@
             self.xslbuild = self.xslmain
             return
 
-        f = file(wrapper, "w")
+        f = open(wrapper, "w")
         f.write(self.xsl_header)
         f.write('<xsl:import href="%s"/>\n' % path_to_uri(self.xslmain))
         for xsluser in self.xslusers:
@@ -231,7 +231,7 @@
                               self.listings, opts=self.xslopts, params=param)
         else:
             self.log.info("No external file support")
-            f = file(self.listings, "w")
+            f = open(self.listings, "w")
             f.write("<listings/>\n")
             f.close()
 
@@ -268,7 +268,7 @@
         # set list
         self.log.info("Build the book set list...")
         xslset = "doclist.xsl"
-        f = file(xslset, "w")
+        f = open(xslset, "w")
         f.write(self.xsl_header)
         f.write('<xsl:import href="%s"/>\n' % path_to_uri(self.xslbuild))
         f.write('<xsl:import href="%s"/>\n' % path_to_uri(self.xslset))
@@ -397,12 +397,12 @@
         # For easy debug
         if self.debug and "TEXINPUTS" in os.environ:
             if os.name != "nt":
-                f = file("env_tex", "w")
+                f = open("env_tex", "w")
                 f.write("TEXINPUTS=%s\nexport TEXINPUTS\n" % \
                         os.environ["TEXINPUTS"])
                 f.close()
             else:
-                f = file("env_tex.bat", "w")
+                f = open("env_tex.bat", "w")
                 f.write("set TEXINPUTS=%s\n" % os.environ["TEXINPUTS"])
                 f.close()
 
--- lib/contrib/which/which.py.orig	2019-09-10 00:40:36.000000000 +0200
+++ lib/contrib/which/which.py	2020-11-17 18:09:15.000000000 +0100
@@ -90,13 +90,13 @@
     if sys.platform.startswith('win'):
         if os.path.splitext(exeName)[1].lower() != '.exe':
             exeName += '.exe'
-        import _winreg
+        import winreg
         try:
             key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" +\
                   exeName
-            value = _winreg.QueryValue(_winreg.HKEY_LOCAL_MACHINE, key)
+            value = winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE, key)
             registered = (value, "from HKLM\\"+key)
-        except _winreg.error:
+        except winreg.error:
             pass
         if registered and not os.path.exists(registered[0]):
             registered = None
@@ -243,7 +243,7 @@
     If no match is found for the command, a WhichError is raised.
     """
     try:
-        match = whichgen(command, path, verbose, exts).next()
+        match = next(whichgen(command, path, verbose, exts))
     except StopIteration:
         raise WhichError("Could not find '%s' on the path." % command)
     return match
@@ -278,19 +278,19 @@
     altpath = None
     exts = None
     try:
-        optlist, args = getopt.getopt(argv[1:], 'haVvqp:e:',
+        opts, args = getopt.getopt(argv[1:], 'haVvqp:e:',
             ['help', 'all', 'version', 'verbose', 'quiet', 'path=', 'exts='])
-    except getopt.GetoptError, msg:
+    except getopt.GetoptError as msg:
         sys.stderr.write("which: error: %s. Your invocation was: %s\n"\
                          % (msg, argv))
         sys.stderr.write("Try 'which --help'.\n")
         return 1
     for opt, optarg in optlist:
         if opt in ('-h', '--help'):
-            print _cmdlnUsage
+            print(_cmdlnUsage)
             return 0
         elif opt in ('-V', '--version'):
-            print "which %s" % __version__
+            print("which %s" % __version__)
             return 0
         elif opt in ('-a', '--all'):
             all = 1
@@ -318,9 +318,9 @@
         nmatches = 0
         for match in whichgen(arg, path=altpath, verbose=verbose, exts=exts):
             if verbose:
-                print "%s (%s)" % match
+                print("%s (%s)" % match)
             else:
-                print match
+                print(match)
             nmatches += 1
             if not all:
                 break
