Index: xen-4.12.4-testing/tools/pygrub/src/pygrub
===================================================================
--- xen-4.12.4-testing.orig/tools/pygrub/src/pygrub
+++ xen-4.12.4-testing/tools/pygrub/src/pygrub
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#!/usr/bin/python3
 #
 # pygrub - simple python-based bootloader for Xen
 #
@@ -20,7 +20,8 @@ import platform
 import resource
 import subprocess
 
-import curses, _curses, curses.wrapper, curses.textpad, curses.ascii
+import curses, _curses, curses.textpad, curses.ascii
+from curses import wrapper
 import getopt
 
 import xenfsimage
@@ -178,7 +179,7 @@ def enable_cursor(ison):
     except _curses.error:
         pass
 
-DISK_TYPE_RAW, DISK_TYPE_HYBRIDISO, DISK_TYPE_DOS = range(3)
+DISK_TYPE_RAW, DISK_TYPE_HYBRIDISO, DISK_TYPE_DOS = list(range(3))
 def identify_disk_image(file):
     """Detect DOS partition table or HybridISO format."""
     fd = os.open(file, os.O_RDONLY)
@@ -205,7 +206,7 @@ def get_solaris_slice(file, offset):
     buf = os.read(fd, 512)
     os.close(fd)
     if struct.unpack("<H", buf[508:510])[0] != DKL_MAGIC:
-        raise RuntimeError, "Invalid disklabel magic"
+        raise RuntimeError("Invalid disklabel magic")
 
     nslices = struct.unpack("<H", buf[30:32])[0]
 
@@ -216,7 +217,7 @@ def get_solaris_slice(file, offset):
         if slicetag == V_ROOT:
             return slicesect * SECTOR_SIZE
 
-    raise RuntimeError, "No root slice found"      
+    raise RuntimeError("No root slice found")
 
 def get_fs_offset_gpt(file):
     fd = os.open(file, os.O_RDONLY)
@@ -551,20 +552,17 @@ class Grub:
         we're being given a raw config file rather than a disk image."""
         
         if not os.access(fn, os.R_OK):
-            raise RuntimeError, "Unable to access %s" %(fn,)
+            raise RuntimeError("Unable to access %s" %(fn,))
 
-        cfg_list = map(lambda x: (x,grub.GrubConf.Grub2ConfigFile),
-                       ["/boot/grub/grub.cfg", "/grub/grub.cfg",
-                        "/boot/grub2/grub.cfg", "/grub2/grub.cfg"]) + \
-                   map(lambda x: (x,grub.ExtLinuxConf.ExtLinuxConfigFile),
-                       ["/boot/isolinux/isolinux.cfg",
+        cfg_list = [(x,grub.GrubConf.Grub2ConfigFile) for x in ["/boot/grub/grub.cfg", "/grub/grub.cfg",
+                        "/boot/grub2/grub.cfg", "/grub2/grub.cfg"]] + \
+                   [(x,grub.ExtLinuxConf.ExtLinuxConfigFile) for x in ["/boot/isolinux/isolinux.cfg",
                         "/boot/extlinux/extlinux.conf",
                         "/boot/extlinux.conf",
                         "/extlinux/extlinux.conf",
-                        "/extlinux.conf"]) + \
-                   map(lambda x: (x,grub.GrubConf.GrubConfigFile),
-                       ["/boot/grub/menu.lst", "/boot/grub/grub.conf",
-                        "/grub/menu.lst", "/grub/grub.conf"])
+                        "/extlinux.conf"]] + \
+                   [(x,grub.GrubConf.GrubConfigFile) for x in ["/boot/grub/menu.lst", "/boot/grub/grub.conf",
+                        "/grub/menu.lst", "/grub/grub.conf"]]
 
         if not fs:
             # set the config file and parse it
@@ -576,7 +574,7 @@ class Grub:
 
         for f,parser in cfg_list:
             if fs.file_exists(f):
-                print >>sys.stderr, "Using %s to parse %s" % (parser,f)
+                print("Using %s to parse %s" % (parser,f), file=sys.stderr)
                 self.cf = parser()
                 self.cf.filename = f
                 break
@@ -586,7 +584,7 @@ class Grub:
         # limit read size to avoid pathological cases
         buf = f.read(FS_READ_MAX)
         del f
-        self.cf.parse(buf)
+        self.cf.parse(buf.decode())
 
     def image_index(self):
         if isinstance(self.cf.default, int):
@@ -730,7 +728,7 @@ class Grub:
 def get_entry_idx(cf, entry):
     # first, see if the given entry is numeric
     try:
-        idx = string.atoi(entry)
+        idx = int(entry)
         return idx
     except ValueError:
         pass
@@ -770,14 +768,14 @@ def run_grub(file, entry, fs, cfg_args):
     if list_entries:
         for i in range(len(g.cf.images)):
             img = g.cf.images[i]
-            print "title: %s" % img.title
-            print "  root: %s" % img.root
-            print "  kernel: %s" % img.kernel[1]
-            print "  args: %s" % img.args
-            print "  initrd: %s" % img.initrd[1]
+            print("title: %s" % img.title)
+            print("  root: %s" % img.root)
+            print("  kernel: %s" % img.kernel[1])
+            print("  args: %s" % img.args)
+            print("  initrd: %s" % img.initrd[1])
 
     if interactive and not list_entries:
-        curses.wrapper(run_main)
+        wrapper(run_main)
     else:
         sel = g.image_index()
 
@@ -788,7 +786,7 @@ def run_grub(file, entry, fs, cfg_args):
            sel = idx
 
     if sel == -1:
-        print "No kernel image selected!"
+        print("No kernel image selected!")
         sys.exit(1)
 
     try:
@@ -877,7 +875,7 @@ def format_sxp(kernel, ramdisk, args):
 def format_simple(kernel, ramdisk, args, sep):
     for check in (kernel, ramdisk, args):
         if check is not None and sep in check:
-            raise RuntimeError, "simple format cannot represent delimiter-containing value"
+            raise RuntimeError("simple format cannot represent delimiter-containing value")
     s = ("kernel %s" % kernel) + sep
     if ramdisk:
         s += ("ramdisk %s" % ramdisk) + sep
@@ -900,8 +898,8 @@ if __name__ == "__main__":
                 sys.exit("The requested %s file does not exist" % file_type)
         try:
             datafile = fs.open_file(file_to_read)
-        except Exception, e:
-            print >>sys.stderr, e
+        except Exception as e:
+            print(e, file=sys.stderr)
             sys.exit("Error opening %s in guest" % file_to_read)
         dataoff = 0
         while True:
@@ -914,8 +912,8 @@ if __name__ == "__main__":
                 return
             try:
                 os.write(fd_dst, data)
-            except Exception, e:
-                print >>sys.stderr, e
+            except Exception as e:
+                print(e, file=sys.stderr)
                 if path_dst:
                     os.unlink(path_dst)
                 del datafile
@@ -988,7 +986,7 @@ if __name__ == "__main__":
             try:
                 part_offs = [ int(a) ]
             except ValueError:
-                print "offset value must be an integer"
+                print("offset value must be an integer")
                 usage()
                 sys.exit(1)
         elif o in ("--entry",):
@@ -1001,18 +999,18 @@ if __name__ == "__main__":
             debug = True
         elif o in ("--output-format",):
             if a not in ["sxp", "simple", "simple0"]:
-                print "unknown output format %s" % a
+                print("unknown output format %s" % a)
                 usage()
                 sys.exit(1)
             output_format = a
         elif o in ("--output-directory",):
             if not os.path.isdir(a):
-                print "%s is not an existing directory" % a
+                print("%s is not an existing directory" % a)
                 sys.exit(1)
             output_directory = a + '/'
 
     if debug:
-	logging.basicConfig(level=logging.DEBUG)
+        logging.basicConfig(level=logging.DEBUG)
 
 
     if interactive and uid:
@@ -1020,8 +1018,8 @@ if __name__ == "__main__":
         sys.exit(1)
 
     try:
-        os.makedirs(output_directory, 0700)
-    except OSError,e:
+        os.makedirs(output_directory, 0o700)
+    except OSError as e:
         if (e.errno == errno.EEXIST) and os.path.isdir(output_directory):
             pass
         else:
@@ -1046,10 +1044,10 @@ if __name__ == "__main__":
     # debug
     if isconfig:
         chosencfg = run_grub(file, entry, fs, incfg["args"])
-        print "  kernel: %s" % chosencfg["kernel"]
+        print("  kernel: %s" % chosencfg["kernel"])
         if chosencfg["ramdisk"]:
-            print "  initrd: %s" % chosencfg["ramdisk"]
-        print "  args: %s" % chosencfg["args"]
+            print("  initrd: %s" % chosencfg["ramdisk"])
+        print("  args: %s" % chosencfg["args"])
         sys.exit(0)
 
     # if boot filesystem is set then pass to fsimage.open
@@ -1086,7 +1084,7 @@ if __name__ == "__main__":
             # IOErrors raised by fsimage.open
             # RuntimeErrors raised by run_grub if no menu.lst present
             if debug:
-		traceback.print_exc()
+                traceback.print_exc()
             fs = None
             continue
 
@@ -1095,7 +1093,7 @@ if __name__ == "__main__":
 
     # Did looping through partitions find us a kernel?
     if fs is None:
-        raise RuntimeError, "Unable to find partition containing kernel"
+        raise RuntimeError("Unable to find partition containing kernel")
 
     copy_from_image(fs, chosencfg["kernel"], "kernel",
                     fd_kernel, None if uid else path_kernel, not_really)
@@ -1133,5 +1131,5 @@ if __name__ == "__main__":
         ostring = format_simple(bootcfg["kernel"], bootcfg["ramdisk"], args, "\0")
 
     sys.stdout.flush()
-    os.write(fd, ostring)
+    os.write(fd, ostring.encode('utf-8'))
     
Index: xen-4.12.4-testing/tools/pygrub/src/GrubConf.py
===================================================================
--- xen-4.12.4-testing.orig/tools/pygrub/src/GrubConf.py
+++ xen-4.12.4-testing/tools/pygrub/src/GrubConf.py
@@ -44,7 +44,7 @@ def get_path(s):
         return (None, s)
     idx = s.find(')')
     if idx == -1:
-        raise ValueError, "Unable to find matching ')'"
+        raise ValueError("Unable to find matching ')'")
     d = s[:idx]
     return (GrubDiskPart(d), s[idx + 1:])
 
@@ -100,7 +100,7 @@ class _GrubImage(object):
                 "  initrd: %s\n" %(self.title, self.root, self.kernel,
                                    self.args, self.initrd))
     def _parse(self, lines):
-        map(self.set_from_line, lines)
+        list(map(self.set_from_line, lines))
 
     def reset(self, lines):
         self._root = self._initrd = self._kernel = self._args = None
@@ -141,7 +141,7 @@ class GrubImage(_GrubImage):
     def set_from_line(self, line, replace = None):
         (com, arg) = grub_exact_split(line, 2)
 
-        if self.commands.has_key(com):
+        if com in self.commands:
             if self.commands[com] is not None:
                 setattr(self, self.commands[com], arg.strip())
             else:
@@ -177,7 +177,7 @@ class _GrubConfigFile(object):
             self.parse()
 
     def parse(self, buf = None):
-        raise RuntimeError, "unimplemented parse function"   
+        raise RuntimeError("unimplemented parse function")
 
     def hasPasswordAccess(self):
         return self.passwordAccess
@@ -201,7 +201,7 @@ class _GrubConfigFile(object):
                 import crypt
                 if crypt.crypt(password, pwd[1]) == pwd[1]:
                     return True
-            except Exception, e:
+            except Exception as e:
                 self.passExc = "Can't verify password: %s" % str(e)
                 return False
 
@@ -213,7 +213,7 @@ class _GrubConfigFile(object):
 
     def set(self, line):
         (com, arg) = grub_exact_split(line, 2)
-        if self.commands.has_key(com):
+        if com in self.commands:
             if self.commands[com] is not None:
                 setattr(self, self.commands[com], arg.strip())
             else:
@@ -232,8 +232,8 @@ class _GrubConfigFile(object):
         else:
             self._default = val
 
-        if self._default < 0:
-            raise ValueError, "default must be positive number"
+        if int(self._default) < 0:
+            raise ValueError("default must be positive number")
     default = property(_get_default, _set_default)
 
     def set_splash(self, val):
@@ -265,7 +265,7 @@ class GrubConfigFile(_GrubConfigFile):
     def parse(self, buf = None):
         if buf is None:
             if self.filename is None:
-                raise ValueError, "No config file defined to parse!"
+                raise ValueError("No config file defined to parse!")
 
             f = open(self.filename, 'r')
             lines = f.readlines()
@@ -296,7 +296,7 @@ class GrubConfigFile(_GrubConfigFile):
                 continue
 
             (com, arg) = grub_exact_split(l, 2)
-            if self.commands.has_key(com):
+            if com in self.commands:
                 if self.commands[com] is not None:
                     setattr(self, self.commands[com], arg.strip())
                 else:
@@ -328,7 +328,7 @@ class Grub2Image(_GrubImage):
         if com == "set":
             (com,arg) = grub2_handle_set(arg)
             
-        if self.commands.has_key(com):
+        if com in self.commands:
             if self.commands[com] is not None:
                 setattr(self, self.commands[com], arg.strip())
             else:
@@ -364,7 +364,7 @@ class Grub2ConfigFile(_GrubConfigFile):
     def parse(self, buf = None):
         if buf is None:
             if self.filename is None:
-                raise ValueError, "No config file defined to parse!"
+                raise ValueError("No config file defined to parse!")
 
             f = open(self.filename, 'r')
             lines = f.readlines()
@@ -398,7 +398,7 @@ class Grub2ConfigFile(_GrubConfigFile):
             title_match = re.match('^menuentry ["\'](.*?)["\'] (.*){', l)
             if title_match:
                 if img is not None:
-                    raise RuntimeError, "syntax error: cannot nest menuentry (%d %s)" % (len(img),img)
+                    raise RuntimeError("syntax error: cannot nest menuentry (%d %s)" % (len(img),img))
                 img = []
                 title = title_match.group(1)
                 if not l.endswith('}'):
@@ -416,7 +416,7 @@ class Grub2ConfigFile(_GrubConfigFile):
                         menu_level -= 1
                         continue
                     else:
-                        raise RuntimeError, "syntax error: closing brace without menuentry"
+                        raise RuntimeError("syntax error: closing brace without menuentry")
 
                 self.add_image(Grub2Image(title, img))
                 img = None
@@ -431,7 +431,7 @@ class Grub2ConfigFile(_GrubConfigFile):
             if com == "set":
                 (com,arg) = grub2_handle_set(arg)
                 
-            if self.commands.has_key(com):
+            if com in self.commands:
                 if self.commands[com] is not None:
                     arg_strip = arg.strip()
                     if arg_strip == "${saved_entry}" or arg_strip == "${next_entry}":
@@ -446,7 +446,7 @@ class Grub2ConfigFile(_GrubConfigFile):
                 logging.debug("Unknown directive %s" %(com,))
             
         if img is not None:
-            raise RuntimeError, "syntax error: end of file with open menuentry(%d %s)" % (len(img),img)
+            raise RuntimeError("syntax error: end of file with open menuentry(%d %s)" % (len(img),img))
 
         if self.hasPassword():
             self.setPasswordAccess(False)
@@ -465,12 +465,12 @@ class Grub2ConfigFile(_GrubConfigFile):
         
 if __name__ == "__main__":
     if len(sys.argv) < 3:
-        raise RuntimeError, "Need a grub version (\"grub\" or \"grub2\") and a grub.conf or grub.cfg to read"
+        raise RuntimeError("Need a grub version (\"grub\" or \"grub2\") and a grub.conf or grub.cfg to read")
     if sys.argv[1] == "grub":
         g = GrubConfigFile(sys.argv[2])
     elif sys.argv[1] == "grub2":
         g = Grub2ConfigFile(sys.argv[2])
     else:
-        raise RuntimeError, "Unknown config type %s" % sys.argv[1]
+        raise RuntimeError("Unknown config type %s" % sys.argv[1])
     for i in g.images:
-        print i #, i.title, i.root, i.kernel, i.args, i.initrd
+        print(i) #, i.title, i.root, i.kernel, i.args, i.initrd
Index: xen-4.12.4-testing/tools/pygrub/src/ExtLinuxConf.py
===================================================================
--- xen-4.12.4-testing.orig/tools/pygrub/src/ExtLinuxConf.py
+++ xen-4.12.4-testing/tools/pygrub/src/ExtLinuxConf.py
@@ -12,7 +12,7 @@
 
 import sys, re, os
 import logging
-import GrubConf
+from . import GrubConf
 
 class ExtLinuxImage(object):
     def __init__(self, lines, path):
@@ -32,7 +32,7 @@ class ExtLinuxImage(object):
         self.lines = []
         self.path = path
         self.root = ""
-        map(self.set_from_line, lines)
+        list(map(self.set_from_line, lines))
 
     def set_from_line(self, line, replace = None):
         (com, arg) = GrubConf.grub_exact_split(line, 2)
@@ -67,7 +67,7 @@ class ExtLinuxImage(object):
                         setattr(self, "initrd", a.replace("initrd=", ""))
                         arg = arg.replace(a, "")
 
-        if com is not None and self.commands.has_key(com):
+        if com is not None and com in self.commands:
             if self.commands[com] is not None:
                 setattr(self, self.commands[com], re.sub('^"(.+)"$', r"\1", arg.strip()))
             else:
@@ -136,7 +136,7 @@ class ExtLinuxConfigFile(object):
     def parse(self, buf = None):
         if buf is None:
             if self.filename is None:
-                raise ValueError, "No config file defined to parse!"
+                raise ValueError("No config file defined to parse!")
 
             f = open(self.filename, 'r')
             lines = f.readlines()
@@ -167,7 +167,7 @@ class ExtLinuxConfigFile(object):
 
             (com, arg) = GrubConf.grub_exact_split(l, 2)
             com = com.lower()
-            if self.commands.has_key(com):
+            if com in self.commands:
                 if self.commands[com] is not None:
                     setattr(self, self.commands[com], arg.strip())
                 else:
@@ -207,8 +207,8 @@ class ExtLinuxConfigFile(object):
         
 if __name__ == "__main__":
     if len(sys.argv) < 2:
-        raise RuntimeError, "Need a configuration file to read"
+        raise RuntimeError("Need a configuration file to read")
     g = ExtLinuxConfigFile(sys.argv[1])
     for i in g.images:
-        print i
-    print g.default
+        print(i)
+    print(g.default)
Index: xen-4.12.4-testing/tools/pygrub/src/LiloConf.py
===================================================================
--- xen-4.12.4-testing.orig/tools/pygrub/src/LiloConf.py
+++ xen-4.12.4-testing/tools/pygrub/src/LiloConf.py
@@ -4,7 +4,7 @@
 
 import sys, re, os
 import logging
-import GrubConf
+from . import GrubConf
 
 class LiloImage(object):
     def __init__(self, lines, path):
@@ -24,12 +24,12 @@ class LiloImage(object):
         self.lines = []
         self.path = path
         self.root = ""
-        map(self.set_from_line, lines)
+        list(map(self.set_from_line, lines))
 
     def set_from_line(self, line, replace = None):
         (com, arg) = GrubConf.grub_exact_split(line, 2)
 
-        if self.commands.has_key(com):
+        if com in self.commands:
             if self.commands[com] is not None:
                 setattr(self, self.commands[com], re.sub('^"(.+)"$', r"\1", arg.strip()))
             else:
@@ -97,7 +97,7 @@ class LiloConfigFile(object):
     def parse(self, buf = None):
         if buf is None:
             if self.filename is None:
-                raise ValueError, "No config file defined to parse!"
+                raise ValueError("No config file defined to parse!")
 
             f = open(self.filename, 'r')
             lines = f.readlines()
@@ -127,7 +127,7 @@ class LiloConfigFile(object):
                 continue
 
             (com, arg) = GrubConf.grub_exact_split(l, 2)
-            if self.commands.has_key(com):
+            if com in self.commands:
                 if self.commands[com] is not None:
                     setattr(self, self.commands[com], arg.strip())
                 else:
@@ -170,8 +170,8 @@ class LiloConfigFile(object):
 
 if __name__ == "__main__":
     if len(sys.argv) < 2:
-        raise RuntimeError, "Need a lilo.conf to read"
+        raise RuntimeError("Need a lilo.conf to read")
     g = LiloConfigFile(sys.argv[1])
     for i in g.images:
-        print i #, i.title, i.root, i.kernel, i.args, i.initrd
-    print g.default
+        print(i) #, i.title, i.root, i.kernel, i.args, i.initrd
+    print(g.default)
Index: xen-4.12.4-testing/tools/pygrub/src/fsimage/fsimage.c
===================================================================
--- xen-4.12.4-testing.orig/tools/pygrub/src/fsimage/fsimage.c
+++ xen-4.12.4-testing/tools/pygrub/src/fsimage/fsimage.c
@@ -66,12 +66,12 @@ fsimage_file_read(fsimage_file_t *file,
 
 	bufsize = size ? size : 4096;
 
-	if ((buffer = PyString_FromStringAndSize(NULL, bufsize)) == NULL)
+	if ((buffer = PyBytes_FromStringAndSize(NULL, bufsize)) == NULL)
 		return (NULL);
  
 	while (1) {
 		int err;
-		void *buf = PyString_AS_STRING(buffer) + bytesread;
+		void *buf = PyBytes_AS_STRING(buffer) + bytesread;
 
 		err = fsi_pread_file(file->file, buf, bufsize,
 		    bytesread + offset);
@@ -91,12 +91,12 @@ fsimage_file_read(fsimage_file_t *file,
 			if (bufsize == 0)
 				break;
 		} else {
-			if (_PyString_Resize(&buffer, bytesread + bufsize) < 0)
+			if (_PyBytes_Resize(&buffer, bytesread + bufsize) < 0)
 				return (NULL);
 		}
 	}
 
-	_PyString_Resize(&buffer, bytesread);
+	_PyBytes_Resize(&buffer, bytesread);
 	return (buffer);
 }
 
@@ -107,7 +107,7 @@ PyDoc_STRVAR(fsimage_file_read__doc__,
    "file. If offset is specified as well, read from the given "
    "offset.\n");
 
-static struct PyMethodDef fsimage_file_methods[] = {
+static PyMethodDef fsimage_file_methods[] = {
 	{ "read", (PyCFunction) fsimage_file_read,
 	    METH_VARARGS|METH_KEYWORDS, fsimage_file_read__doc__ },
 	{ NULL, NULL, 0, NULL }	
@@ -116,7 +116,13 @@ static struct PyMethodDef fsimage_file_m
 static PyObject *
 fsimage_file_getattr(fsimage_file_t *file, char *name)
 {
-	return (Py_FindMethod(fsimage_file_methods, (PyObject *)file, name));
+	PyMethodDef *ml = fsimage_file_methods;
+	for (; ml->ml_name != NULL; ml++) {
+		if (name[0] == ml->ml_name[0] &&
+			strcmp(name+1, ml->ml_name+1) == 0)
+			return PyCFunction_New(ml, (PyObject *)file);
+	}
+	return (NULL);
 }
 
 static void
@@ -130,8 +136,7 @@ fsimage_file_dealloc(fsimage_file_t *fil
 
 static char fsimage_file_type__doc__[] = "Filesystem image file";
 PyTypeObject fsimage_file_type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"xenfsimage.file",			/* tp_name */
 	sizeof(fsimage_file_t),			/* tp_size */
 	0,					/* tp_itemsize */
@@ -207,7 +212,7 @@ PyDoc_STRVAR(fsimage_fs_file_exists__doc
    "file_exists(fs, name) - lookup name in the given fs and return "
    "True if it exists");
 
-static struct PyMethodDef fsimage_fs_methods[] = {
+static PyMethodDef fsimage_fs_methods[] = {
 	{ "open_file", (PyCFunction) fsimage_fs_open_file,
 	  METH_VARARGS|METH_KEYWORDS, fsimage_fs_open_file__doc__ },
 	{ "file_exists", (PyCFunction) fsimage_fs_file_exists,
@@ -218,7 +223,13 @@ static struct PyMethodDef fsimage_fs_met
 static PyObject *
 fsimage_fs_getattr(fsimage_fs_t *fs, char *name)
 {
-	return (Py_FindMethod(fsimage_fs_methods, (PyObject *)fs, name));
+	PyMethodDef *ml = fsimage_fs_methods;
+	for (; ml->ml_name != NULL; ml++) {
+		if (name[0] == ml->ml_name[0] &&
+			strcmp(name+1, ml->ml_name+1) == 0)
+			return PyCFunction_New(ml, (PyObject *)fs);
+	}
+	return (NULL);
 }
 
 static void
@@ -232,8 +243,7 @@ fsimage_fs_dealloc (fsimage_fs_t *fs)
 PyDoc_STRVAR(fsimage_fs_type__doc__, "Filesystem image");
 
 PyTypeObject fsimage_fs_type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,					/* ob_size */
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
 	"xenfsimage.fs",			/* tp_name */
 	sizeof(fsimage_fs_t),			/* tp_size */
 	0,					/* tp_itemsize */
@@ -331,8 +341,17 @@ static struct PyMethodDef fsimage_module
 	{ NULL, NULL, 0, NULL }
 };
 
+static struct PyModuleDef fsimage_module =
+{
+    PyModuleDef_HEAD_INIT,
+    "fsimage",
+    "",
+    -1,
+    fsimage_module_methods
+};
+
 PyMODINIT_FUNC
-initxenfsimage(void)
+PyInit_xenfsimage(void)
 {
-	Py_InitModule("xenfsimage", fsimage_module_methods);
+	return PyModule_Create(&fsimage_module);
 }
