diff --git a/tools/include/xen-foreign/mkheader.py b/tools/include/xen-foreign/mkheader.py
index 081b57f842a2..3a33df4984a2 100644
--- a/tools/include/xen-foreign/mkheader.py
+++ b/tools/include/xen-foreign/mkheader.py
@@ -2,21 +2,21 @@
 
 from __future__ import print_function
 
-import sys, re;
-from structs import unions, structs, defines;
+import sys, re
+from structs import unions, structs, defines
 
 # command line arguments
-arch    = sys.argv[1];
-outfile = sys.argv[2];
-infiles = sys.argv[3:];
+arch    = sys.argv[1]
+outfile = sys.argv[2]
+infiles = sys.argv[3:]
 
 
 ###########################################################################
 # configuration #2: architecture information
 
-inttypes = {};
-header = {};
-footer = {};
+inttypes = {}
+header = {}
+footer = {}
 
 #arm
 inttypes["arm32"] = [
@@ -35,7 +35,7 @@ header["arm32"] = """
 # define __DECL_REG(n64, n32) uint64_t n64
 # define __align8__ FIXME
 #endif
-""";
+"""
 footer["arm32"] = """
 #undef __DECL_REG
 """
@@ -56,7 +56,7 @@ header["arm64"] = """
 # define __DECL_REG(n64, n32) uint64_t n64
 # define __align8__ FIXME
 #endif
-""";
+"""
 footer["arm64"] = """
 #undef __DECL_REG
 """
@@ -73,12 +73,12 @@ header["x86_32"] = """
 #define __DECL_REG_LO16(name) uint32_t e ## name
 #define __i386___X86_32 1
 #pragma pack(4)
-""";
+"""
 footer["x86_32"] = """
 #undef __DECL_REG_LO8
 #undef __DECL_REG_LO16
 #pragma pack()
-""";
+"""
 
 # x86_64
 inttypes["x86_64"] = [
@@ -100,7 +100,7 @@ header["x86_64"] = """
 #define __DECL_REG_LO16       __DECL_REG
 #define __DECL_REG_HI         __DECL_REG
 #define __x86_64___X86_64 1
-""";
+"""
 footer["x86_64"] = """
 #undef __DECL_REG
 #undef __DECL_REG_LOHI
@@ -112,12 +112,12 @@ footer["x86_64"] = """
 ###########################################################################
 # main
 
-input  = "";
-output = "";
-fileid = re.sub("[-.]", "_", "__FOREIGN_%s__" % outfile.upper());
+input  = ""
+output = ""
+fileid = re.sub("[-.]", "_", "__FOREIGN_%s__" % outfile.upper())
 
 for name in infiles:
-    f = open(name, "r");
+    f = open(name, "r")
 
     # Sanity check the licence of the input file(s)
     line = f.readline()
@@ -126,8 +126,8 @@ for name in infiles:
               (sys.argv[0], name, line.strip()), file=sys.stderr)
         exit(1)
 
-    input += f.read();
-    f.close();
+    input += f.read()
+    f.close()
 
 # replace path in "infiles" by path in '/usr/include' to avoid exposing the
 # build directory path in the generated headers.
@@ -151,83 +151,81 @@ output += """/* SPDX-License-Identifier: MIT */
 """ % (arch, headers_name_list, sys.argv[0], fileid, fileid)
 
 if arch in header:
-    output += header[arch];
-    output += "\n";
+    output += header[arch]
+    output += "\n"
 
 defined = {}
 
 # add defines to output
 for line in re.findall("#define[^\n]+", input):
     for define in defines:
-        regex = "#define\s+%s\\b" % define;
-        match = re.search(regex, line);
+        regex = "#define\s+%s\\b" % define
+        match = re.search(regex, line)
         if None == match:
-            continue;
+            continue
         defined[define] = 1
         if define.upper()[0] == define[0]:
-            replace = define + "_" + arch.upper();
+            replace = define + "_" + arch.upper()
         else:
-            replace = define + "_" + arch;
-        regex = "\\b%s\\b" % define;
-        output += re.sub(regex, replace, line) + "\n";
-output += "\n";
+            replace = define + "_" + arch
+        regex = "\\b%s\\b" % define
+        output += re.sub(regex, replace, line) + "\n"
+output += "\n"
 
 # delete defines, comments, empty lines
-input = re.sub("#define[^\n]+\n", "", input);
+input = re.sub("#define[^\n]+\n", "", input)
 input = re.compile("/\*(.*?)\*/", re.S).sub("", input)
-input = re.compile("\n\s*\n", re.S).sub("\n", input);
+input = re.compile("\n\s*\n", re.S).sub("\n", input)
 
 # add unions to output
 for union in unions:
-    regex = "union\s+%s\s*\{(.*?)\n\};" % union;
+    regex = "union\s+%s\s*\{(.*?)\n\};" % union
     match = re.search(regex, input, re.S)
     if None == match:
-        output += "#define %s_has_no_%s 1\n" % (arch, union);
+        output += "#define %s_has_no_%s 1\n" % (arch, union)
     else:
-        output += "union %s_%s {%s\n};\n" % (union, arch, match.group(1));
-    output += "\n";
+        output += "union %s_%s {%s\n};\n" % (union, arch, match.group(1))
+    output += "\n"
 
 # add structs to output
 for struct in structs:
-    regex = "(?:#ifdef ([A-Z_]+))?\nstruct\s+%s\s*\{(.*?)\n\};" % struct;
+    regex = "(?:#ifdef ([A-Z_]+))?\nstruct\s+%s\s*\{(.*?)\n\};" % struct
     match = re.search(regex, input, re.S)
     if None == match or \
            (match.group(1) is not None and match.group(1) not in defined):
-        output += "#define %s_has_no_%s 1\n" % (arch, struct);
+        output += "#define %s_has_no_%s 1\n" % (arch, struct)
     else:
-        output += "struct %s_%s {%s\n};\n" % (struct, arch, match.group(2));
-        output += "typedef struct %s_%s %s_%s_t;\n" % (struct, arch, struct, arch);
-    output += "\n";
+        output += "struct %s_%s {%s\n};\n" % (struct, arch, match.group(2))
+        output += "typedef struct %s_%s %s_%s_t;\n" % (struct, arch, struct, arch)
+    output += "\n"
 
 # add footer
 if arch in footer:
-    output += footer[arch];
-    output += "\n";
-output += "#endif /* %s */\n" % fileid;
+    output += footer[arch]
+    output += "\n"
+output += "#endif /* %s */\n" % fileid
 
 # replace: defines
 for define in defines:
     if define.upper()[0] == define[0]:
-        replace = define + "_" + arch.upper();
+        replace = define + "_" + arch.upper()
     else:
-        replace = define + "_" + arch;
-    output = re.sub("\\b%s\\b" % define, replace, output);
+        replace = define + "_" + arch
+    output = re.sub("\\b%s\\b" % define, replace, output)
 
 # replace: unions
 for union in unions:
-    output = re.sub("\\b(union\s+%s)\\b" % union, "\\1_%s" % arch, output);
+    output = re.sub("\\b(union\s+%s)\\b" % union, "\\1_%s" % arch, output)
 
 # replace: structs + struct typedefs
 for struct in structs:
-    output = re.sub("\\b(struct\s+%s)\\b" % struct, "\\1_%s" % arch, output);
-    output = re.sub("\\b(%s)_t\\b" % struct, "\\1_%s_t" % arch, output);
+    output = re.sub("\\b(struct\s+%s)\\b" % struct, "\\1_%s" % arch, output)
+    output = re.sub("\\b(%s)_t\\b" % struct, "\\1_%s_t" % arch, output)
 
 # replace: integer types
 for old, new in inttypes[arch]:
     output = re.sub("\\b%s\\b" % old, new, output)
 
 # print results
-f = open(outfile, "w");
-f.write(output);
-f.close;
-
+with open(outfile, "w") as f:
+    f.write(output)
